May 7, 2014 - Warren Held

Retrieve Windows Product Keys With PowerShell

If you are looking to retrieve Windows XP, Windows 7, Windows Vista, Server 2003, Server 2008, or Server 2012 product keys and remotely over the network or locally then this PowerShell script will simplify this task.  I used chunks of PowerShell code from here for the Get-ProductKey function.  WinRM has to be enabled on the computers you are trying to retrieve product keys from.  The easiest way to enable WinRM is to open a PowerShell prompt on the computer and run:

WinRM quickconfig

You can copy and paste this code into notepad and save it with a .ps1 extension.  Then right click on the file and select ‘Run with PowerShell’.  You’ll need to change localhost to a comma seperated list of computer names that you want to retrieve the Windows product key from, and supply domain administrator credentials in the form of domain\user.

$computers = 'localhost' #comma separated list of computer names
$cred = Get-Credential #domain administrator credentials in domain\user format
Invoke-Command -Credential $cred -ComputerName $computers -ScriptBlock {
function Get-ProductKey {
Retrieves the product key and OS information from a local or remote system/s.

Retrieves the product key and OS information from a local or remote system/s. Queries of 64bit OS from a 32bit OS will result in
inaccurate data being returned for the Product Key. You must query a 64bit OS from a system running a 64bit OS.

.PARAMETER Computername
Name of the local or remote system/s.

Author: Boe Prox
Version: 1.1
-Update of function from
-Added capability to query more than one system
-Supports remote system query
-Supports querying 64bit OSes
-Shows OS description and Version in output object
-Error Handling

Get-ProductKey -Computername Server1

OSDescription Computername OSVersion ProductKey
------------- ------------ --------- ----------
Microsoft(R) Windows(R) Server 2003, Enterprise Edition Server1 5.2.3790 bcdfg-hjklm-pqrtt-vwxyy-12345

Retrieves the product key information from 'Server1'
Param (
[string[]]$Computername = $Env:Computername
Begin {
Process {
ForEach ($Computer in $Computername) {
Write-Verbose ("{0}: Checking network availability" -f $Computer)
If (Test-Connection -ComputerName $Computer -Count 1 -Quiet) {
Try {
Write-Verbose ("{0}: Retrieving WMI OS information" -f $Computer)
$OS = Get-WmiObject -ComputerName $Computer Win32_OperatingSystem -ErrorAction Stop
} Catch {
$OS = New-Object PSObject -Property @{
Caption = $_.Exception.Message
Version = $_.Exception.Message
Try {
Write-Verbose ("{0}: Attempting remote registry access" -f $Computer)
$remoteReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
If ($OS.OSArchitecture -eq '64-bit') {
$value = $remoteReg.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue('DigitalProductId4')[0x34..0x42]
} Else {
$value = $remoteReg.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue('DigitalProductId')[0x34..0x42]
$ProductKey = ""
Write-Verbose ("{0}: Translating data into product key" -f $Computer)
for ($i = 24; $i -ge 0; $i--) {
$r = 0
for ($j = 14; $j -ge 0; $j--) {
$r = ($r * 256) -bxor $value[$j]
$value[$j] = [math]::Floor([double]($r/24))
$r = $r % 24
$ProductKey = $map[$r] + $ProductKey
if (($i % 5) -eq 0 -and $i -ne 0) {
$ProductKey = "-" + $ProductKey
} Catch {
$ProductKey = $_.Exception.Message
$object = New-Object PSObject -Property @{
Computername = $Computer
ProductKey = $ProductKey
OSDescription = $os.Caption
OSVersion = $os.Version
} Else {
$object = New-Object PSObject -Property @{
Computername = $Computer
ProductKey = 'Unreachable'
OSDescription = 'Unreachable'
OSVersion = 'Unreachable'
} | ft Computername,OSDescription,OSVersion,ProductKey


Uncategorized PowerShell /