【问题标题】:Windows Product Key - Different answers from different techniquesWindows 产品密钥 - 来自不同技术的不同答案
【发布时间】:2017-01-27 03:56:25
【问题描述】:

this question(询问如何检索 Windows 产品密钥)之后,从各种方法获得的信息似乎相互矛盾。这个问题问为什么它们都应该返回相同的值时会有区别?

这两种方法...

电源外壳

(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey

CMD

wmic path softwarelicensingservice get OA3xOriginalProductKey

向此 VBS 脚本返回不同的结果 ...

Set WshShell = CreateObject("WScript.Shell")
MsgBox ConvertToKey(WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId"))

Function ConvertToKey(Key)
    Const KeyOffset = 52
    i = 28
    Chars = "BCDFGHJKMPQRTVWXY2346789"
    Do
        Cur = 0
        x = 14
        Do
            Cur = Cur * 256
            Cur = Key(x + KeyOffset) + Cur
            Key(x + KeyOffset) = (Cur \ 24) And 255
            Cur = Cur Mod 24
            x = x - 1
        Loop While x >= 0
        i = i - 1
        KeyOutput = Mid(Chars, Cur + 1, 1) & KeyOutput
        If (((29 - i) Mod 6) = 0) And (i <> -1) Then
            i = i - 1
            KeyOutput = "-" & KeyOutput
        End If
    Loop While i >= 0
    ConvertToKey = KeyOutput
End Function

POWERSHELL 和 CMD 一致,但 VBS 脚本显示的值不同。

任何想法为什么会这样?


更新 - 快到了!!

以下 PowerShell 脚本获取与 PowerShell 和 Cmd 命令相同的产品密钥。值的编码方式似乎发生了一些变化(我还没有时间确定这种变化是什么)

function Get-ProductKey {
     <#
    .SYNOPSIS
        Retrieves the product key and OS information from a local or remote system/s.

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

    .Notes
Author:             Boe Prox
        Version: 1.1
            -Update of function from http://powershell.com/cs/blogs/tips/archive/2012/04/30/getting-windows-product-key.aspx
            -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

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

        Description
        -----------
        Retrieves the product key information from 'Server1'
    #>
    [cmdletbinding()]
    Param (
        [parameter(ValueFromPipeLine=$True,ValueFromPipeLineByPropertyName=$True)]
        [Alias("CN","__Server","IPAddress","Server")]
        [string[]]$Computername = $Env:Computername
    )
    Begin {
        $map="BCDFGHJKMPQRTVWXY2346789"
    }
    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)
            $value = $remoteReg.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue('DigitalProductId')[0x34..0x42]
            $isWin8OrNewer = [math]::Floor(($value[14] / 6)) -band 1
            $value[14] = ($value[14] -band 0xF7) -bor (($isWin8OrNewer -band 2) * 4)
            $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
            }
        } Catch {
            $ProductKey = $_.Exception.Message
        }

        if ($isWin8OrNewer){
            $ProductKey = $ProductKey.Remove(0, 1)
            $ProductKey = $ProductKey.Insert($r, 'N')
        }

        #insert dashes to make key more readable
        for($i = 5; $i -lt 29; $i = $i + 6){
            $ProductKey = $ProductKey.Insert($i, '-')
        }
                $object = New-Object PSObject -Property @{
                    Computername = $Computer
                    ProductKey = $ProductKey
                    OSDescription = $os.Caption
                    OSVersion = $os.Version
                }
                $object.pstypenames.insert(0,'ProductKey.Info')
                $object
            } Else {
                $object = New-Object PSObject -Property @{
                    Computername = $Computer
                    ProductKey = 'Unreachable'
                    OSDescription = 'Unreachable'
                    OSVersion = 'Unreachable'
                }
                $object.pstypenames.insert(0,'ProductKey.Info')
                $object
            }
        }
    }
}

以上脚本取自here,但考虑到了 TJ 在底部 cmets 中建议的更改,日期为 2016 年 2 月 5 日。那家伙是个传奇!嗯,原作者也清楚!

我将在创建 VB 版本后发布它,假设这个问题没有被关闭(只需要 3 票,所以快点行动吧)/讽刺。

【问题讨论】:

  • 因为这两种方法都使用不同的位置来查找密钥。你已经already posted about this 为什么要创建一个新问题?
  • 我写了更新 3 :0) 当然,每个 Windows 副本只有一个 Windows 产品密钥,因此我对为什么我得到不同的答案感到困惑! VBS 脚本已被宣布,不曾被称赞为在过去检索有效的 Windows 产品密钥,那么为什么它现在应该停止工作呢?
  • 显然,这是一个单独的问题!哦,你已经改变了你的评论,现在你看到我是另一个问题的作者。我的第一个问题是关于检索产品密钥,这个问题是为什么我会得到不同的结果。
  • 他们确实不会欢迎来到微软的世界!
  • 如果我把它分成两个问题,其他人会抱怨我应该开始另一个问题。所以我付出了额外的努力来提出一个截然不同的问题。为什么会发生这种情况与我如何做到这一点有很大不同?我希望你能欣赏我尴尬的处境!因为我感谢您的意见;0)

标签: powershell vbscript cmd wsh


【解决方案1】:

在我测试的 Windows 7 和 Windows 10 系统上,这个键不存在: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId
但是vbscript仍然会输出一个值而不是抛出一个错误。

您可能在 Windows 7 上寻找此值:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DefaultProductKey\DigitalProductId
(注意:它在 Windows 10 上不存在)

【讨论】:

    【解决方案2】:

    根据this article,WMI 查询将返回制造商存储在 BIOS 或 UEFI 固件中的 OEM 密钥。从注册表读取的 VBScript 方法将返回用户在安装期间(或之后)输入的零售产品密钥。

    【讨论】:

    • 我没有在我的机器上输入不同的密钥!因此,我希望所有三种方法都得到相同的结果......也许它与 64 位键值有关,而 VBS 方法正在使用 32 位值?!我真的不知道,信息似乎有点稀缺。
    • 这个答案回答了部分问题,但另一个未回答的问题是为什么 VBScript 与 Powershell 脚本相比返回不同的产品密钥。我相信答案是,尽管产品密钥在所有 Windows 版本中都存储在相同的注册表值中,但对于 Win8+,它的编码方式不同,正如 OP 所暗示的那样。这反映在您拥有$isWin8OrNewer 的Powershell 脚本中。另请参阅适用于所有 Windows 版本的 VBScript:github.com/foerl/Windows-10-Key-Extract-VBS/blob/master/…
    猜你喜欢
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多