# encoding: ascii
# api: powershell
# title: Get-WindowsProduct
# description: This is the “proper” version of Get-WindowsProductKey
# version: 0.1
# type: function
# author: akaNeo
# license: CC0
# function: Get-WindowsProduct
# x-poshcode-id: 5683
# x-archived: 2015-01-31T20:30:23
# x-published: 2015-01-12T10:07:00
#
# Works fine on Windows NT 6.2 or 6.3
#
Function Get-WindowsProduct
{
function DecodeDigitalPID([byte[]]$digitalProductId)
{
$base24 = 'BCDFGHJKMPQRTVWXY2346789'
$cryptedStringLength = 24
$decryptionLength = 14
$decryptedKey = [System.String]::Empty
[System.Boolean]$containsN = ($digitalProductId[$decryptionLength] -shr 3) -band 1
[System.Byte]$digitalProductId[$decryptionLength] = $digitalProductId[$decryptionLength] -band 0xF7
for ($i = $cryptedStringLength; $i -ge 0; $i--)
{
$digitMapIndex = 0
for ($j = $decryptionLength; $j -ge 0; $j--)
{
[System.UInt16]$digitMapIndex = $digitMapIndex -shl 8 -bxor $digitalProductId[$j]
[System.Byte]$digitalProductId[$j] = [System.Math]::Floor($digitMapIndex / $base24.Length)
[System.UInt16]$digitMapIndex = $digitMapIndex % $base24.Length
}
$decryptedKey = $decryptedKey.Insert(0, $base24[$digitMapIndex])
}
if ($containsN)
{
$firstCharIndex = 0
for ($index = 0; $index -lt $cryptedStringLength; $index++)
{
if ($decryptedKey[0] -ne $base24[$index]) { continue }
$firstCharIndex = $index; break
}
$decryptedKey = $decryptedKey.Remove(0, 1).Insert($firstCharIndex,'N')
}
for ($t = 20; $t -ge 5; $t -= 5) { $decryptedKey = $decryptedKey.Insert($t, '-') }
return $decryptedKey
}
$regKey = Get-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion'
return [PSCustomObject]@{
Version = [System.Environment]::OSVersion.VersionString
Edition = $regKey.EditionID
Type = switch ([System.Environment]::Is64BitOperatingSystem) { $true {'x86-64'}; $false {'x86-32'}}
ProductID = $regKey.ProductId
ProductKey = DecodeDigitalPID($regKey.DigitalProductId[0x34..0x42])
## 1970-01-01 :: UTC + seconds value from registry
Installed = [System.DateTime]::FromBinary(0x089F7FF5F7B58000).AddSeconds($regKey.InstallDate).ToLocalTime()
}
}