CURYIOUS
CURYIOUS

Reputation: 31

How to find Windows product Key if your sticker is damaged

I found a possible solution to the question here: http://youtu.be/71Vc9QiraQE

I am not a power shell user myself and cannot quite follow the code in the script.

It would be a useful script to help with reinstalls when operating systems have been upgraded. My problem is I would like to understand it more before using it or at least be told it looks harmless.

Here is the Script:

function Get-WindowsKey {
    ## function to retrieve the Windows Product Key from any PC
    param ($targets = ".")
    $hklm = 2147483650
    $regPath = "Software\Microsoft\Windows NT\CurrentVersion"
    $regValue = "DigitalProductId"
    Foreach ($target in $targets) {
        $productKey = $null
        $win32os = $null
        $wmi = [WMIClass]"\\$target\root\default:stdRegProv"
        $data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
        $binArray = ($data.uValue)[52..66]
        $charsArray = "B","C","D","E","F","G","H","J","K","M","P","Q","­R","T","V","W","X","Y","2","3","4","5","6","7","8","9"
        ## decrypt base24 encoded binary data
        For ($i = 24; $i -ge 0; $i--) {
            $k = 0
            For ($j = 14; $j -ge 0; $j--) {
                $k = $k * 256 -bxor $binArray[$j]
                $binArray[$j] = [math]::truncate($k / 24)
                $k = $k % 24
            }
            $productKey = $charsArray[$k] + $productKey
            If (($i % 5 -eq 0) -and ($i -ne 0)) {
                $productKey = "-" + $productKey
            }
        }
        $win32os = Get-WmiObject Win32_OperatingSystem -computer $target
        $obj = New-Object Object
        $obj | Add-Member Noteproperty Computer -value $target
        $obj | Add-Member Noteproperty Caption -value $win32os.Caption
        $obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion
        $obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture
        $obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber
        $obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser
        $obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber
        $obj | Add-Member Noteproperty ProductKey -value $productkey
        $obj
    }
}
Get-WindowsKey

The first command used in Windows PowerShell:

Set-ExecutionPolicy RemoteSigned

If the first script doesn't work, try this: I was able to get my key using this, but I had to fix the script, changing the last line to:

function Get-WindowsKey {
# ...
}
Get-WindowsKey localhost

Upvotes: 2

Views: 11971

Answers (3)

Chris Calverley
Chris Calverley

Reputation: 1

The code is wrong, you are getting the key decrypted wrong... Look at $charsArray, no E and a couple others...

function Get-WindowsKey {
    ## function to retrieve the Windows Product Key from any PC
    param ($targets = ".")
    $hklm = 2147483650
    $regPath = "Software\Microsoft\Windows NT\CurrentVersion"
    $regValue = "DigitalProductId"
    Foreach ($target in $targets) {
        $productKey = $null
        $win32os = $null
        $wmi = [WMIClass]"\\$target\root\default:stdRegProv"
        $data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
        $binArray = ($data.uValue)[52..66]
        $charsArray = "B","C","D","F","G","H","J","K","M","P","Q","­R","T","V","W","X","Y","2","3","4","6","7","8","9"
        ## decrypt base24 encoded binary data
        For ($i = 24; $i -ge 0; $i--) {
            $k = 0
            For ($j = 14; $j -ge 0; $j--) {
                $k = $k * 256 -bxor $binArray[$j]
                $binArray[$j] = [math]::truncate($k / 24)
                $k = $k % 24
            }
            $productKey = $charsArray[$k] + $productKey
            If (($i % 5 -eq 0) -and ($i -ne 0)) {
                $productKey = "-" + $productKey
            }
        }
        $win32os = Get-WmiObject Win32_OperatingSystem -computer $target
        $obj = New-Object Object
        $obj | Add-Member Noteproperty Computer -value $target
        $obj | Add-Member Noteproperty Caption -value $win32os.Caption
        $obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion
        $obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture
        $obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber
        $obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser
        $obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber
        $obj | Add-Member Noteproperty ProductKey -value $productkey
        $obj
    }
}
$key = Get-WindowsKey
$key.productkey

Upvotes: 0

Olaf Dietsche
Olaf Dietsche

Reputation: 74018

Trying to explain what the code does.

The script is reading the registry value Software\Microsoft\Windows NT\CurrentVersion\DigitalProductId and extracts the relevant part

$wmi = [WMIClass]"\\$target\root\default:stdRegProv"
$data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
$binArray = ($data.uValue)[52..66]

As the comment in the code says, it then decodes ("decrypts") the value in the for loop. The registry value is base24 encoded.

$charsArray = "B","C","D","E","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","5","6","7","8","9"
For ($i = 24; $i -ge 0; $i--) {
    $k = 0
    For ($j = 14; $j -ge 0; $j--) {
        $k = $k * 256 -bxor $binArray[$j]
        $binArray[$j] = [math]::truncate($k / 24)
        $k = $k % 24
    }
    $productKey = $charsArray[$k] + $productKey
    If (($i % 5 -eq 0) -and ($i -ne 0)) {
        $productKey = "-" + $productKey
    }
}

And finally the code shows the product key along with several system values

$win32os = Get-WmiObject Win32_OperatingSystem -computer $target
$obj = New-Object Object
$obj | Add-Member Noteproperty Computer -value $target
$obj | Add-Member Noteproperty Caption -value $win32os.Caption
$obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion
$obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture
$obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber
$obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser
$obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber
$obj | Add-Member Noteproperty ProductKey -value $productkey
$obj

Depending on whether it's a retail or enterprise version, the registry value may be found in either DigitalProductId or DigitalProductId4, e.g.

$regValue = "DigitalProductId"

vs

$regValue = "DigitalProductId4"

Upvotes: 0

Deadly-Bagel
Deadly-Bagel

Reputation: 1620

I think the YouTube video overdoes it a bit, you could simply cut and paste the contents of that into a PowerShell window without having to muck about with executionpolicy and importing the file.

Just open PowerShell, paste the below code into it and hit Enter a few times until it returns.

param ($targets = ".")
$hklm = 2147483650
$regPath = "Software\Microsoft\Windows NT\CurrentVersion"
$regValue = "DigitalProductId4"
Foreach ($target in $targets) {
    $productKey = $null
    $win32os = $null
    $wmi = [WMIClass]"\\$target\root\default:stdRegProv"
    $data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
    $binArray = ($data.uValue)[52..66]
    $charsArray = "B","C","D","E","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","5","6","7","8","9"
    ## decrypt base24 encoded binary data to characters. 
    For ($i = 24; $i -ge 0; $i--) {
        $k = 0
        For ($j = 14; $j -ge 0; $j--) {
            $k = $k * 256 -bxor $binArray[$j]
            $binArray[$j] = [math]::truncate($k / 24)
            $k = $k % 24
        }
        $productKey = $charsArray[$k] + $productKey
        If (($i % 5 -eq 0) -and ($i -ne 0)) {
            $productKey = "-" + $productKey
        }
    }
    $win32os = Get-WmiObject Win32_OperatingSystem -computer $target
    $obj = New-Object Object
    $obj | Add-Member Noteproperty Computer -value $target
    $obj | Add-Member Noteproperty Caption -value $win32os.Caption
    $obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion
    $obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture
    $obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber
    $obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser
    $obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber
    $obj | Add-Member Noteproperty ProductKey -value $productkey
    $obj
}

I highly recommend backing up the hard drive (or replacing it entirely) in case the script hasn't decrypted it properly. It would kind of suck to go through all this to find it's wrong and you've just wiped your previous OS.

Upvotes: 2

Related Questions