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
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