Public/Windows/Get-WindowsProductKey.ps1

function Get-WindowsProductKey {
    [cmdletbinding()]
    Param (
        [parameter(ValueFromPipeLine,ValueFromPipelineByPropertyName)]
        [string[]]$Computername = $Env:Computername,
        [Switch] $FullReport
    )

    process {

        $GetProductKeyFromComputer = {
            param (
                [Parameter(Mandatory,ValueFromPipeline)]
                [String] $Computer
            )

            $map = "BCDFGHJKMPQRTVWXY2346789"

            if (Test-Connection -ComputerName $Computer -Count 1 -Quiet) {
                try {
                    Write-Verbose ("{0}: Attempting remote registry access" -f $Computer)
                    $remoteReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $Computer)
                    $ProductKeyValue = $remoteReg.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue('DigitalProductId')[0x34..0x42]
                    $ProductNameValue = $remoteReg.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue('ProductName')
                    $isWin8OrNewer = [math]::Floor(($ProductKeyValue[14] / 6)) -band 1
                    $ProductKeyValue[14] = ($ProductKeyValue[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 $ProductKeyValue[$j]
                            $ProductKeyValue[$j] = [math]::Floor([double]($r / 24))
                            $r = $r % 24
                        }
                        $ProductKey = $map[$r] + $ProductKey
                    }
                }
                catch {
                    Write-Verbose "Error finding Product Key"
                    $ProductKey = $_.Exception.Message
                }

                if ($isWin8OrNewer) {
                    $ProductKey = $ProductKey.Remove(0, 1)
                    $ProductKey = $ProductKey.Insert($r, 'N')
                }
                for ($i = 5; $i -lt 29; $i = $i + 6) {
                    $ProductKey = $ProductKey.Insert($i, '-')
                }

            }
            else {
                $ProductKey = 'Failure'
            }

            [PSCustomObject]@{
                Machine = $Computer
                ProductName = $ProductNameValue
                ProductKey = $ProductKey
            }
        }

        foreach ($Computer in $Computername) {

            $ProductKeyObject = & $GetProductKeyFromComputer -Computer $Computer
            $OutputObject = [PSCustomObject]@{
                Machine = $ProductKeyObject.Machine
                ProductName = $ProductKeyObject.ProductName
                ProductKey = $ProductKeyObject.ProductKey
            }
            if($FullReport){

                $LicenseStatusDict = @{
                    0 = "Unlicensed";
                    1 = "Licensed";
                    2 = "OOBGrace";
                    3 = "OOTGrace";
                    4 = "NonGenuineGrace";
                    5 = "Notification";
                    6 = "ExtendedGrace"
                }


                $ExtendedInfoKeys = 'Name','Description','ApplicationId','ProductKeyChannel','UseLicenseURL','ValidationURL','ProductKeyID','LicenseStatus','LicenseFamily'
                $ExtendedInfo = Get-CimInstance -ClassName SoftwareLicensingProduct -filter 'PartialProductKey is not null' | Select-Object $ExtendedInfoKeys

                $LicenseStatus = $LicenseStatusDict[$ExtendedInfo.LicenseStatus -as [Int]]
                $OutputObject | Add-Member -NotePropertyName LicenseStatus -NotePropertyValue $LicenseStatus | Out-Null
                $OutputObject | Add-Member -NotePropertyName LicenseName -NotePropertyValue $ExtendedInfo.Name | Out-Null
                $OutputObject | Add-Member -NotePropertyName Description -NotePropertyValue $ExtendedInfo.Description | Out-Null
                $OutputObject | Add-Member -NotePropertyName LicenseFamily -NotePropertyValue $ExtendedInfo.LicenseFamily | Out-Null
                $OutputObject | Add-Member -NotePropertyName ProductKeyChannel -NotePropertyValue $ExtendedInfo.ProductKeyChannel | Out-Null
                $OutputObject | Add-Member -NotePropertyName ApplicationID -NotePropertyValue $ExtendedInfo.ApplicationId | Out-Null
                $OutputObject | Add-Member -NotePropertyName ProductKeyID -NotePropertyValue $ExtendedInfo.ProductKeyID | Out-Null
                $OutputObject | Add-Member -NotePropertyName UseLicenseURL -NotePropertyValue $ExtendedInfo.UseLicenseURL | Out-Null
                $OutputObject | Add-Member -NotePropertyName ValidationURL -NotePropertyValue $ExtendedInfo.ValidationURL | Out-Null
            }

            $OutputObject
        }
    }
}