Powershell‎ > ‎

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


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 




Comments