Volume Licensing

Query machines for License mode

$PsExecPath = "C:\Scripts\PSTools\PsExec.exe" $ExportFilePath = "C:\Scripts\VolumeLicensingList.csv" $Machines = Get-QADComputer -SizeLimit 0 -IncludedProperties OperatingSystem -OSName "*Windows Server*" |      Where {$_.OperatingSystem -ne "Windows Server 2003"} | Select Name, OperatingSystem   #$Machines | Group-Object -Property OperatingSystem | select count, name  foreach ($Machine in $Machines) {     $LicMode = $null     $Command = [ScriptBlock]::Create(@" $PsExecPath \\$($Machine.Name) cscript c:\windows\system32\slmgr.vbs /dlv "@)     $LicMode =(((Invoke-Command -ScriptBlock $Command |          Select-String "Description:" | out-string).split(",")[1]).trim()).split(" ")[0]     $Machine | Add-Member -membertype noteproperty -name LicenseMode -Value $LicMode }  $Machines | Export-Csv -NoTypeInformation -Path $ExportFilePath

Variable Substitution in a PowerShell Script Block

http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/22/variable-substitution-in-a-powershell-script-block.aspx

Interesting issue with scriptblocks and invoke-command

This will fail with the following error

$Command = {$PsExecPath \\$($Machine.Name) cscript c:\windows\system32\slmgr.vbs /dlv}

Unexpected token '\\$($Machine.Name)' in expression or statement.

But this works fine

$Command = [ScriptBlock]::Create(@" $PsExecPath \\$($Machine.Name) cscript c:\windows\system32\slmgr.vbs /dlv "@)

Full script with email

$StartTime = Get-Date $PsExecPath = "C:\Scripts\PSTools\PsExec.exe" $ExportFilePath = "C:\Scripts\VolumeLicensingList.csv"  $smtpServer = "mail.blah.com" $To =    "Kevin Curran <kcurran@blah.com>" $From = "AD Reporting <ADReporting@blah.com>"  $Machines = Get-QADComputer -SizeLimit 0 -IncludedProperties OperatingSystem -OSName "*Windows Server*" |      Where {$_.OperatingSystem -ne "Windows Server 2003"} | Select Name, OperatingSystem, whenCreated   #$Machines | Group-Object -Property OperatingSystem | select count, name  $Total = ($Machines.Count)  foreach ($Machine in $Machines) {     $Counter ++     $LicMode = $null     $Results = $null     $KMSServer = $null     Write-Host "$Counter of $Total : $($Machine.Name)"     $Command = [ScriptBlock]::Create("$PsExecPath \\$($Machine.Name) cscript c:\windows\system32\slmgr.vbs /dlv")     $Results = Invoke-Command -ScriptBlock $Command     $LicMode =((($Results |          Select-String "Description:" | out-string).split(",")[1]).trim()).split(" ")[0]     $KMSServer = ($Results| Select-String "KMS machine name"| out-string).trim().split(": ")[6]     $Machine | Add-Member -membertype noteproperty -name LicenseMode -Value $LicMode     $Machine | Add-Member -membertype noteproperty -name KMSServer -Value $KMSServer }  $Machines | Export-Csv -NoTypeInformation -Path $ExportFilePath  $StopTime = Get-Date  $ElapsedTime =$StopTime - $StartTime   $message = "Please see the attached files for more details `r`n`r`n" $message += "This script was run by " + $env:username + " on " + $env:COMPUTERNAME + "`r`n" $message += "ScriptName: $($MyInvocation.MyCommand) `r`n" $message += "Script path: $(Split-Path -Parent $MyInvocation.MyCommand.Path) `r`n" $message += "Script completed in $([Math]::Round($ElapsedTime.TotalMinutes,0)) Minutes"   Send-MailMessage -From $From -To $To -SmtpServer $smtpServer `     -Subject "Volume Licensing" -Body $message -Attachments $ExportFilePath 

Push out Generic KMS Keys to machines using MAK

Replace Keys with real keys

#Install Generic KMS Keys $StartTime = Get-Date $PsExecPath = "C:\Scripts\PSTools\PsExec.exe" $MachineListFilePath = "C:\scripts\VolumeLicensingList.csv" $ExportFilePath = "C:\scripts\InstallGenericKMS.csv"  $smtpServer = "mail.blah.com" $To =    "Kevin Curran <kcurran@blah.com>" $From = "AD Reporting <ADReporting@blah.com>"  #Machine list should include Machine Names and OperatingSystem $Machines = Import-Csv -Path $MachineListFilePath $Machines = $Machines | where {$_.LicenseMode -like "*MAK*"}   #| select -first 5  $Total = ($Machines.Count)  foreach ($Machine in $Machines) {     $Counter ++     $Key = $null     $LicMode = $null          #Parse the OS and determine what Generic KMS Key to use      $Key =switch ($Machine.operatingSystem.Substring($Machine.operatingSystem.IndexOf("20")))     {         "2008 R2 Enterprise" {"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"}         "2008 R2 Standard"    {"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"}         "2012 Standard" {"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"}         "2008 Enterprise" {"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"}         "2008 Standard" {"XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"}     }     Write-Host "$Counter of $Total : $($Machine.Name) OS: $($Machine.operatingSystem) Key: $Key "           $InstallCommand = [ScriptBlock]::Create("$PsExecPath \\$($Machine.Name) cscript c:\windows\system32\slmgr.vbs /ipk $Key")     $InstKey =(Invoke-Command -ScriptBlock $InstallCommand | Select-String "Installed product key" | out-string).trim()     sleep 5     $ActivateCommand = [ScriptBlock]::Create("$PsExecPath \\$($Machine.Name) cscript c:\windows\system32\slmgr.vbs /ato")     $Activate =(Invoke-Command -ScriptBlock $ActivateCommand | Select-String "Product" | out-string).trim()      $Machine | Add-Member -membertype noteproperty -name Key -Value $Key     $Machine | Add-Member -membertype noteproperty -name KeyInstalled -Value $InstKey     $Machine | Add-Member -membertype noteproperty -name Activateded -Value $Activate }  $Machines | Export-Csv -NoTypeInformation -Path $ExportFilePath  $StopTime = Get-Date  $ElapsedTime =$StopTime - $StartTime   $message = "Please see the attached files for more details `r`n`r`n" $message += "This script was run by " + $env:username + " on " + $env:COMPUTERNAME + "`r`n" $message += "ScriptName: $($MyInvocation.MyCommand) `r`n" $message += "Script path: $(Split-Path -Parent $MyInvocation.MyCommand.Path) `r`n" $message += "Script completed in $([Math]::Round($ElapsedTime.TotalMinutes,0)) Minutes"   Send-MailMessage -From $From -To $To -SmtpServer $smtpServer `     -Subject "Volume Licensing KMS Generic Key Push" -Body $message -Attachments $ExportFilePath