Code: # ***************************** # # v12.6.0 compiled at 30-05-25 # # ***************************** # # Add hwid + kms38 Support # Rebuild way of fetch system data # add few `using namespace`, and remove repeated code # Update\fix, function: Parse-DigitalProductId,Parse-DigitalProductId4,Get-ProductID {Major.Minor} Version -> new AdvancedPID -> fixed some offset was mis calculated (wchar x2) also, remove some un-know offset, re-built again all offset + length also, improve Get-ProductID function code
Code: # ***************************** # # v12.8.0 compiled at 31-05-25 # # ***************************** # # Add hwid + kms38 Support # Rebuild way of fetch system data # Add few `using namespace`, and remove repeated code # Update\fix, function: Parse-DigitalProductId,Parse-DigitalProductId4,Get-ProductID # New Function added, Get-LatestUBR [v2] Add new way to get ubr value, via creative way, not registry B`cause no api was found, so. found a creative way. Update it again, it seem that regex is faster than manual extract ubr 40'ms, like half of a 1's. not seem much, but older weak system ? ... i made test script. check what is faster. Code: Regex Mode Auto Mode --> UseWinSxS Ubr value: 5854 Time elapsed: 00:00:00.051 Auto Mode --> UseWinSxS Manual Mode --> UseWinSxS Ubr value: 5854 Time elapsed: 00:00:00.082 Manual Mode --> UseWinSxS Auto Mode --> UsePackages Ubr value: 5854 Time elapsed: 00:00:00.071 Auto Mode --> UsePackages Manual Mode --> UsePackages Ubr value: 5854 Time elapsed: 00:00:00.077 Manual Mode --> UsePackages Function Mode Auto Mode --> UseWinSxS Ubr value: 5854 Time elapsed: 00:00:00.094 Auto Mode --> UseWinSxS Manual Mode --> UseWinSxS Ubr value: 5854 Time elapsed: 00:00:00.100 Manual Mode --> UseWinSxS Auto Mode --> UsePackages Ubr value: 5854 Time elapsed: 00:00:00.102 Auto Mode --> UsePackages Manual Mode --> UsePackages Ubr value: 5854 Time elapsed: 00:00:00.088 Manual Mode --> UsePackages Get-LatestUBR Function [v2] Code: function Get-LatestUBR { param ( [bool]$AutoMode = $false, [switch]$UseWinSxS, [switch]$UsePackages ) function Get-LatestLCUDate { try { $session = New-Object -ComObject Microsoft.Update.Session $searcher = $session.CreateUpdateSearcher() $count = $searcher.GetTotalHistoryCount() $updates = $searcher.QueryHistory(0, $count) $cumulativeUpdates = $updates | Where-Object { $_.Title -like '*Cumulative Update*' -and $_.ResultCode -eq 2 } if ($cumulativeUpdates.Count -gt 0) { return ($cumulativeUpdates | Sort-Object Date -Descending | Select-Object -First 1).Date.Date } } catch {} return $null } function Get-UBRFromFolderName { param ( [Parameter(Mandatory=$true)] [string]$folderName ) try { $folderParts = $folderName -split '_' if ($folderParts.Length -ge 4) { $versionPart = $folderParts[3] $versionParts = $versionPart -split '\.' if ($versionParts.Length -ge 4) { $ubr = $versionParts[3] return [int]$ubr } } return 0 } catch { Write-Warning "Error processing folder name: $folderName. Returning 0." return 0 } } function Get-UBRFromFileName { param ( [Parameter(Mandatory=$true)] [string]$fileName ) # Extract the part of the file name that contains the version info (before the extension) $fileNameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($fileName) # Split by '~' and check if version part exists $parts = $fileNameWithoutExt -split '~' if ($parts.Length -gt 2) { $versionPart = $parts[-1] # The last part should contain version info like '10.0.19041.5854' # Directly split the version part by '.' to get version numbers $versionParts = $versionPart -split '\.' # Check for 4 parts and ensure it starts with "10" if ($versionParts.Length -eq 4 -and $versionParts[0] -eq '10') { # Extract UBR (fourth part of version) return [int]$versionParts[3] } } # Return 0 if version doesn't match "10.x.x.x" format return 0 } function Get-FilesForLatestMonth { param ( [switch]$UseWinSxS, [switch]$UsePackages ) if ($UseWinSxS) { $PackagesPath = 'C:\Windows\WinSxS' $isFolderScan = $true } elseif ($UsePackages) { $PackagesPath = 'C:\Windows\Servicing\Packages' $isFolderScan = $false } else { Write-Error "Specify either -UseWinSxS or -UsePackages." return } $fileList = @() $latestYearMonth = $null $targetDate = Get-LatestLCUDate $dirInfo = [System.IO.DirectoryInfo] $PackagesPath if ($isFolderScan) { foreach ($folder in $dirInfo.EnumerateDirectories('*_10.*_none_*')) { $lastModified = $folder.LastWriteTime $ym = $lastModified.ToString('yyyy-MM') $ymd = $lastModified.Date # Prefer exact match on LCU date if available if ($targetDate -and $ymd -eq $targetDate) { $fileList += $folder.Name } elseif (-not $targetDate) { if (-not $latestYearMonth -or $ym -gt $latestYearMonth) { $latestYearMonth = $ym $fileList = @() } if ($ym -eq $latestYearMonth) { $fileList += $folder.Name } } } } else { foreach ($file in $dirInfo.EnumerateFiles('*~10.*')) { $lastModified = $file.LastWriteTime $ym = $lastModified.ToString('yyyy-MM') if (-not $latestYearMonth -or $ym -gt $latestYearMonth) { $latestYearMonth = $ym $fileList = @() } if ($ym -eq $latestYearMonth) { $fileList += $file.Name } } } return $fileList } # Ensure that either -UseWinSxS or -UsePackages is specified, or AutoMode is enabled if (-not $AutoMode -and -not ($UsePackages -or $UseWinSxS)) { Write-Error "You must specify either -UseWinSxS or -UsePackages." return } if (-not $Global:CurrentVersion) { $Global:CurrentVersion = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' } $maxUbr = 0 $FileNames = @() $winsxsFilter = '*_10.*_none_*' $WinSxSPath = 'C:\Windows\WinSxS' $winsxsRegex = [regex]'10\.\d+\.\d+\.(\d+)' $packagefilter = '*~10.*' $PackagesPath = 'C:\Windows\Servicing\Packages' $packageRegex = [regex]'(10|11)\.\d+\.\d+\.(\d+)' $Global:CurrentVersion = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' # Handle AutoMode if ($AutoMode) { # If AutoMode is enabled, leave this block empty for now } elseif ($UsePackages) { # Get the files for the latest month from the Packages folder $FileNames = Get-FilesForLatestMonth -UsePackages } elseif ($UseWinSxS) { # Get the files for the latest month from the WinSxS folder $FileNames = Get-FilesForLatestMonth -UseWinSxS } # Check if any files were found if (($UsePackages -or $UseWinSxS) -and $FileNames.Count -eq 0) { # No files found, returning 0 return 0 } # Further processing can go here, if required if ($AutoMode) { # --------------------- # >> Auto mode BEGIN << # --------------------- # 1) Scan Packages folder first $dirInfo = [System.IO.DirectoryInfo] $PackagesPath try { foreach ($file in $dirInfo.EnumerateFiles($packagefilter)) { $nameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($file.Name) $match = $packageRegex.Match($nameWithoutExt) #$ubr = Get-UBRFromFileName $file.Name if ($match.Success) { $ubr = [int]$match.Groups[2].Value if ($ubr -gt $maxUbr) { $maxUbr = $ubr } } } } catch { # Ignore access or IO errors per extension scan } # keep for debug purpose # $maxUbr = 0 if ($maxUbr -gt 0) { return $maxUbr } # 2) Try update history COM + WinSxS folder scan $targetDate = Get-LatestLCUDate $dirInfo = [System.IO.DirectoryInfo] $WinSxSPath foreach ($folder in $dirInfo.EnumerateDirectories($winsxsFilter)) { if (-not $targetDate -or ( $folder.LastWriteTime.Date -eq $targetDate)) { $match = $winsxsRegex.Match($folder.Name) #$ubr = Get-UBRFromFolderName -folderName $folder.Name if ($match.Success) { $ubr = [int]$match.Groups[1].Value if ($ubr -gt $maxUbr) { $maxUbr = $ubr } } } } if ($maxUbr -gt 0) { return $maxUbr } # -------------------- # >> Auto mode END << # -------------------- } else { # --------------------- # >> Manu mode BEGIN << # --------------------- foreach ($fileName in $FileNames) { if ($UsePackages) { $nameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($fileName) $match = $packageRegex.Match($nameWithoutExt) #$ubr = Get-UBRFromFileName $fileName if ($match.Success) { $ubr = [int]$match.Groups[2].Value if ($ubr -gt $maxUbr) { $maxUbr = $ubr } } } elseif ($UseWinSxS) { $match = $winsxsRegex.Match($fileName) #$ubr = Get-UBRFromFolderName -folderName $fileName if ($match.Success) { $ubr = [int]$match.Groups[1].Value if ($ubr -gt $maxUbr) { $maxUbr = $ubr } } } } if ($maxUbr -gt 0) { return $maxUbr } # -------------------- # >> Manu mode END << # -------------------- } # 3) Fallback: read UBR from registry last (slowest) try { $regUbr = (Get-ItemProperty -Path $Global:CurrentVersion -Name UBR -ErrorAction Continue).UBR if ($regUbr -and ($regUbr -gt $maxUbr)) { return $regUbr } } catch { } return 0 }
v13.4.0 [compiled at 03-06-25] Code: # Add hwid + kms38 Support # Rebuild way of fetch system data # Add few `using namespace`, and remove repeated code # Update\fix, function: Parse-DigitalProductId,Parse-DigitalProductId4,Get-ProductID # Rebild Get-LatestUBR from scratch, avoid enum 99999999 trillion files # Add ZeroCid replacement method for insider build etc etc # Add alternative method to get key if GetRandom Function fail # Fix bug in productID function # Add Insider Check, and case of ZeroCid + Insider, well, Warning messege
Code: # ***************************** # # v13.5.0 compiled at 08-06-25 # # ***************************** # * Add hwid + kms38 Support * Rebuild way of fetch system data * Add few `using namespace`, and remove repeated code * Update\fix, function: Parse-DigitalProductId,Parse-DigitalProductId4,Get-ProductID * Rebild Get-LatestUBR from scratch, avoid enum 99999999 trillion files * Add ZeroCid replacement method for insider build etc etc * Add alternative method to get key if GetRandom Function fail * Fix bug in productID function * Add Insider Check, and case of ZeroCid + Insider, well, Warning messege * Add support to remove **specific license, or install specifc license using low level api from hell
v13.6.0 [compiled at 09-06-25] Code: * Add hwid + kms38 Support * Rebuild way of fetch system data * Add few `using namespace`, and remove repeated code * Update\fix, function: Parse-DigitalProductId,Parse-DigitalProductId4,Get-ProductID * Rebild Get-LatestUBR from scratch, avoid enum 99999999 trillion files * Add ZeroCid replacement method for insider build etc etc * Add alternative method to get key if GetRandom Function fail * Fix bug in productID function * Add Insider Check, and case of ZeroCid + Insider, well, Warning messege * Add support to remove **specific license, or install specifc license using low level api from hell * Api & Function Update, to make it work better so main change it, replace all DLL calls from slc.dll to spcc.dll {who doe's the actualy job !} and update Retrieve-SKUInfo function which is importand helper to deal with SKU -> Any. [specific needed guid] was re desgined, add few fail safe method , add try-catch Code: Main Function, GetSLIDList. {don't support SL_ID_LICENSE_FILE for specific Sku)} Backup Function, SLGetProductSkuInformation with some un-document Parameters some, From License data blob, some from service himself (un-document) like fileId, pkeyId "fileId", # SL_ID_LICENSE_FILE "pkeyId", # SL_ID_PKEY "productSkuId", # SL_ID_PRODUCT_SKU "licenseId", "privateCertificateId" # SL_ID_LICENSE "applicationId", # SL_ID_APPLICATION and another backup {of backup} function, SLGetInstalledProductKeyIds, to get SL_ID_PKEY only Code: <# .SYNOPSIS Function Retrieve-SKUInfo retrieves related licensing IDs for a given SKU GUID. Specific SKUs require particular IDs: - The SKU for SLUninstallLicense requires the ID_LICENSE_FILE GUID. - The SKU for SLUninstallProofOfPurchase requires the ID_PKEY GUID. Optional Pointer: Handle to the Software Licensing Service (SLC). Optional eReturnIdType: Type of ID to return (e.g., SL_ID_APPLICATION, SL_ID_PKEY, etc.). #> function Retrieve-SKUInfo { param( [Parameter(Mandatory = $true)] [ValidatePattern('^[{]?[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}[}]?$')] [string]$SkuId, [Parameter(Mandatory = $false)] [ValidateSet("SL_ID_APPLICATION", "SL_ID_PRODUCT_SKU", "SL_ID_LICENSE", "SL_ID_PKEY", "SL_ID_ALL_LICENSES", "SL_ID_ALL_LICENSE_FILES", "SL_ID_LICENSE_FILE")] [string]$eReturnIdType, [Parameter(Mandatory=$false)] [Intptr]$hSLC = [IntPtr]::Zero ) function Get-IDs { param ( [string]$returnType, [Intptr]$hSLC ) try { return Get-SLIDList -eQueryIdType SL_ID_PRODUCT_SKU -eReturnIdType $returnType -pQueryId $SkuId -hSLC $hSLC } catch { Write-Warning "Get-SLIDList -eQueryIdType SL_ID_PRODUCT_SKU -eReturnIdType $returnType -pQueryId $SkuId -hSLC $hSLC" return $null } } $product = [Guid]$SkuId if (-not $hSLC -or $hSLC -eq [IntPtr]::Zero -or $hSLC -eq 0) { $hSLC = if ($global:hSLC_ -and $global:hSLC_ -ne [IntPtr]::Zero -and $global:hSLC_ -ne 0) { $global:hSLC_ } else { Manage-SLHandle } } try { $closeHandle = $true if (-not $hSLC -or $hSLC -eq [IntPtr]::Zero -or $hSLC -eq 0) { $hr = $Global:SLC::SLOpen([ref]$hSLC) if ($hr -ne 0) { throw "SLOpen failed: HRESULT 0x{0:X8}" -f $hr } } else { $closeHandle = $false } } catch { return $null } try { # [SL_ID_LICENSE_FILE] Case [Guid]$fileId = try { [Guid]::Parse((Get-LicenseDetails -ActConfigId $product -pwszValueName fileId -hSLC $hSLC).Trim().Substring(0,36)) } catch { [GUID]::Empty } # [SL_ID_LICENSE] Case **Alternative** [Guid]$licenseId = try { [Guid]::Parse((Get-LicenseDetails -ActConfigId $product -pwszValueName licenseId -hSLC $hSLC).Trim().Substring(0,36)) } catch { [Guid]::Empty } [Guid]$privateCertificateId = try { [Guid]::Parse((Get-LicenseDetails -ActConfigId $product -pwszValueName privateCertificateId -hSLC $hSLC).Trim().Substring(0,36)) } catch { [Guid]::Empty } # [SL_ID_APPLICATION] Case **Alternative** [Guid]$applicationId = try { [Guid]::Parse((Get-LicenseDetails -ActConfigId $product -pwszValueName applicationId -hSLC $hSLC).Trim().Substring(0,36)) } catch { [Guid]::Empty } # [SL_ID_PKEY] Case **Alternative** [Guid]$pkId = try { [Guid]::Parse((Get-LicenseDetails -ActConfigId $product -pwszValueName pkeyId -hSLC $hSLC).Trim().Substring(0,36)) } catch { [Guid]::Empty } [uint32]$countRef = 0 [IntPtr]$ppKeyIds = [intPtr]::Zero [GUID]$Product_SKU_ID = [GUID]::Empty [uint32]$hresults = $Global:SLC::SLGetInstalledProductKeyIds($hSLC, [ref]$product, [ref]$countRef, [ref]$ppKeyIds) if ($hresults -and ($hresults -eq 0)) { if ($countRef -gt 0 -and ( $ppKeyIds -ne [IntPtr]::Zero)) { if ($ppKeyIds.ToInt64() -gt 0) { try { $buffer = New-Object byte[] 16 [Marshal]::Copy($ppKeyIds, $buffer, 0, 16) $Product_SKU_ID = [Guid]::new($buffer) } catch { $Product_SKU_ID } } } } # ------------------------------------------------- if (-not $eReturnIdType) { $SKU_DATA = [pscustomobject]@{ ID_SKU = $SkuId ID_APPLICATION = if ($applicationId -and $applicationId -ne [Guid]::Empty) { $applicationId } else { try { Get-IDs SL_ID_APPLICATION -hSLC $hSLC } catch { [Guid]::Empty } } ID_PKEY = if ($pkId -and $pkId -ne [Guid]::Empty) { $pkId } elseif ($Product_SKU_ID -and $Product_SKU_ID -ne [Guid]::Empty) { $Product_SKU_ID } else { try { Get-IDs SL_ID_PKEY -hSLC $hSLC } catch { [Guid]::Empty } } ID_LICENSE_FILE = if ($fileId -and $fileId -ne [Guid]::Empty) { $fileId } else { try { Get-IDs SL_ID_LICENSE_FILE -hSLC $hSLC } catch { [Guid]::Empty } } ID_LICENSE = if (($licenseId -and $privateCertificateId) -and ($licenseId -ne [Guid]::Empty -and $privateCertificateId -ne [Guid]::Empty)) { @($licenseId, $privateCertificateId) } else { try { Get-IDs SL_ID_LICENSE -hSLC $hSLC } catch { [Guid]::Empty } } } return $SKU_DATA } switch ($eReturnIdType) { "SL_ID_APPLICATION" { if ($applicationId -and $applicationId -ne [Guid]::Empty) { return $applicationId } try { return Get-IDs SL_ID_APPLICATION -hSLC $hSLC } catch {} return [Guid]::Empty } "SL_ID_PRODUCT_SKU" { return $SkuId } "SL_ID_LICENSE" { if ($licenseId -and $privateCertificateId -and $licenseId -ne [Guid]::Empty -and $privateCertificateId -ne [Guid]::Empty) { return @($licenseId, $privateCertificateId) } try { return Get-IDs SL_ID_LICENSE -hSLC $hSLC } catch {} return [Guid]::Empty } "SL_ID_PKEY" { if ($pkId -and $pkId -ne [Guid]::Empty) { return $pkId } if ($Product_SKU_ID -and $Product_SKU_ID -ne [Guid]::Empty) { return $Product_SKU_ID } try { return Get-IDs SL_ID_PKEY -hSLC $hSLC } catch {} return [Guid]::Empty } "SL_ID_ALL_LICENSES" { try { return Get-IDs SL_ID_ALL_LICENSES -hSLC $hSLC } catch {} return [Guid]::Empty } "SL_ID_ALL_LICENSE_FILES" { try { return Get-IDs SL_ID_ALL_LICENSE_FILES -hSLC $hSLC } catch {} return [Guid]::Empty } "SL_ID_LICENSE_FILE" { if ($fileId -and $fileId -ne [Guid]::Empty) { return $fileId } #try { return Get-IDs SL_ID_LICENSE_FILE -hSLC $hSLC } catch {} return [Guid]::Empty } default { return [Guid]::Empty } } } finally { if ($null -ne $ppKeyIds -and ( $ppKeyIds -ne [IntPtr]::Zero) -and ( $ppKeyIds -ne 0)) { $null = $Global:kernel32::LocalFree($ppKeyIds) } if ($null -ne $hSLC -and ( $hSLC -ne [IntPtr]::Zero) -and ( $hSLC -ne 0) -and ( $closeHandle)) { Write-Warning "Consider Open handle Using Manage-SLHandle" $null = $Global:SLC::SLClose($hSLC) } } }
New version [per user request] Code: # ***************************** # # v14.0.1 compiled at 09-06-25 # # ***************************** # <# * license remove failure [fixed] * Add Option for custom Specifc activation key * fix another bug, early return, cause results to fail #> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ as per request, will be added soon. only if key match SKU ! Else, try use Genuine one, Or generate One. how it done, decode Key using KeyInfo Libary -> extract Pkeyconfig -> find a match for SKU-REF pair match, ok, not match, use genuine or random. so, i build new function, for that. Sku -> Ref, Ref -> Sku, CD-KEY -> Both new Function. Code: <# .SYNOPSIS Function Retrieve-SKUInfo retrieves related licensing IDs for a given SKU GUID. Convert option, CD-KEY->Ref/ID, Ref->SKU, SKU->Ref #> function Retrieve-ProductKeyInfo { param ( [ValidateScript({ $_ -ne $null -and $_ -ne [guid]::Empty })] [guid]$SkuId, [ValidateScript({ $_ -ne $null -and $_ -gt 0 })] [int]$RefGroupId, [ValidateScript({ $_ -match '^(?i)[A-Z0-9]{5}(-[A-Z0-9]{5}){4}$' })] [string]$CdKey ) function Get-PKeyEntry { param ( [guid]$FilterSkuId, [int32]$FilterRefGroupId ) $paths = @( "C:\Windows\System32\spp\tokens\pkeyconfig\pkeyconfig.xrm-ms", "C:\Windows\System32\spp\tokens\pkeyconfig\pkeyconfig-csvlk.xrm-ms", "C:\Windows\System32\spp\tokens\pkeyconfig\pkeyconfig-downlevel.xrm-ms",, "C:\Program Files\Microsoft Office\root\Licenses16\pkeyconfig-office.xrm-ms" ) foreach ($path in $paths) { if (Test-Path -Path $path) { $entries = Extract-Base64Xml -FilePath $path foreach ($entry in $entries) { if ($FilterSkuId -and $entry.ActConfigId -eq "{$FilterSkuId}") { return $entry } elseif ($FilterRefGroupId -and $entry.RefGroupId -eq $FilterRefGroupId) { return $entry } } } } return $null } # Validate only one parameter $paramsProvided = @($SkuId, $RefGroupId, $CdKey) | Where-Object { $_ } if ($paramsProvided.Count -ne 1) { Write-Warning "Please specify exactly one of -SkuId, -RefGroupId, or -CdKey" return $null } # SkuId to RefGroupId if ($SkuId) { $entry = Get-PKeyEntry -FilterSkuId $SkuId if ($entry) { return $entry.RefGroupId } else { Write-Warning "RefGroupId not found for SkuId: $SkuId" return $null } } # RefGroupId to SkuId elseif ($RefGroupId) { $entry = Get-PKeyEntry -FilterRefGroupId $RefGroupId if ($entry) { return [guid]($entry.ActConfigId -replace '[{}]', '') } else { Write-Warning "ActConfigId not found for RefGroupId: $RefGroupId" return $null } } # CdKey to RefGroupId to SkuId elseif ($CdKey) { try { $decoded = KeyDecode -key0 $CdKey.Substring(0,29) $refGroupFromKey = [int]$decoded[2].Value $entry = Get-PKeyEntry -FilterRefGroupId $refGroupFromKey if ($entry) { return [PSCustomObject]@{ RefGroupId = $refGroupFromKey SkuId = [guid]($entry.ActConfigId -replace '[{}]', '') } } else { Write-Warning "SKU not found for RefGroupId $refGroupFromKey extracted from CD Key" return $null } } catch { Write-Warning "Failed to decode CD Key: $_" return $null } } }
Code: # ***************************** # # v14.2.0 compiled at 11-06-25 # # ***************************** # <# * license remove failure [fixed] * Add Option for custom Specifc activation key * Update Get-LicenseDetails Function * build main enum parser function, to mange enum results * Improve slc libary, to re-use logic if possible reduce loading times of remove windows form * Close Handle Before & after, Add -or Remove license #> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Code: # ***************************** # # v14.1.0 compiled at 10-06-25 # # ***************************** # <# * license remove failure [fixed] * Add Option for custom Specifc activation key * Update Get-LicenseDetails Function * build main enum parser function, to mange enum results #> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OK .. let's see how this goe's Edit. yep, Solved my problem. include in latest version Code: typedef enum _tagSLDATATYPE { SL_DATA_NONE = REG_NONE, // 0 SL_DATA_SZ = REG_SZ, // 1 SL_DATA_DWORD = REG_DWORD, // 4 SL_DATA_BINARY = REG_BINARY, // 3 SL_DATA_MULTI_SZ, // 7 SL_DATA_SUM = 100 // 100 } SLDATATYPE; #define REG_NONE 0 /* no type */ #define REG_SZ 1 /* string type (ASCII) */ #define REG_EXPAND_SZ 2 /* string, includes %ENVVAR% (expanded by caller) (ASCII) */ #define REG_BINARY 3 /* binary format, callerspecific */ #define REG_DWORD 4 /* DWORD in little endian format */ #define REG_DWORD_LITTLE_ENDIAN 4 /* DWORD in little endian format */ #define REG_DWORD_BIG_ENDIAN 5 /* DWORD in big endian format */ #define REG_LINK 6 /* symbolic link (UNICODE) */ #define REG_MULTI_SZ 7 /* multiple strings, delimited by \0, terminated by \0\0 (ASCII) */ #define REG_RESOURCE_LIST 8 /* resource list? huh? */ #define REG_FULL_RESOURCE_DESCRIPTOR 9 /* full resource descriptor? huh? */ #define REG_RESOURCE_REQUIREMENTS_LIST 10 #define REG_QWORD 11 /* QWORD in little endian format */ #> # Define the enum-like values in PowerShell $SLDATATYPE = @{ SL_DATA_NONE = 0 # REG_NONE SL_DATA_SZ = 1 # REG_SZ SL_DATA_DWORD = 4 # REG_DWORD SL_DATA_BINARY = 3 # REG_BINARY SL_DATA_MULTI_SZ = 7 # REG_MULTI_SZ SL_DATA_SUM = 100 # Custom value } function Parse-RegistryData { param ( [Parameter(Mandatory=$true)] [int]$dataType, # Data type (e.g., $SLDATATYPE.SL_DATA_NONE, $SLDATATYPE.SL_DATA_SZ, etc.) [Parameter(Mandatory=$true)] [IntPtr]$ptr, # Pointer to the data (e.g., registry value pointer) [Parameter(Mandatory=$true)] [int]$valueSize, # Size of the data (in bytes) [Parameter(Mandatory=$false)] [string]$valueName # Optional, for special cases (e.g., ProductSkuId) ) $result = $null # Default result to null switch ($dataType) { $SLDATATYPE.SL_DATA_NONE { $result = $null } $SLDATATYPE.SL_DATA_SZ { # SL_DATA_SZ = Unicode string # PtrToStringUni expects length in characters, valueSize is in bytes, so divide by 2 $result = [Marshal]::PtrToStringUni($ptr, $valueSize / 2) } $SLDATATYPE.SL_DATA_DWORD { # SL_DATA_DWORD = DWORD (4 bytes) if ($valueSize -ne 4) { $result = $null # Unexpected size, return null } else { $result = [Marshal]::ReadInt32($ptr) } } $SLDATATYPE.SL_DATA_BINARY { # SL_DATA_BINARY = Binary blob if ($valueName -eq 'ProductSkuId' -and $valueSize -eq 16) { # If it's ProductSkuId and the buffer is 16 bytes, treat it as a GUID $bytes = New-Object byte[] 16 [Marshal]::Copy($ptr, $bytes, 0, 16) $result = [Guid]::new($bytes) } else { # Otherwise, just copy the binary data $result = New-Object byte[] $valueSize [Marshal]::Copy($ptr, $result, 0, $valueSize) } } $SLDATATYPE.SL_DATA_MULTI_SZ { # SL_DATA_MULTI_SZ = Multi-string $raw = [Marshal]::PtrToStringUni($ptr, $valueSize / 2) $result = $raw -split "`0" | Where-Object { $_ -ne '' } } $SLDATATYPE.SL_DATA_SUM { # SL_DATA_SUM = Custom (100) # Handle this case accordingly (based on your logic) $result = $null } default { # Return null for any unsupported data types $result = $null } } return $result }
uplaod new version. remove all wmi calls's, using low level api rebuild activation form, kms38 was fixed (bug) fetch table information become very fast. activation too Code: # ***************************** # # v14.5.0 compiled at 12-06-25 # # ***************************** # <# * license remove failure [fixed] * Add Option for custom Specifc activation key * Update Get-LicenseDetails Function * build main enum parser function, to mange enum results * Improve slc libary, to re-use logic if possible reduce loading times of remove windows form * Close Handle Before & after, Add -or Remove license * Rebuild HWID + KMS38, using low level API, ONLY enum, activation, etc, etc, now very fast. * Fix problem when pointer was not initilized #>
I will check it today Did you check that key fir to sku ? Information will be fixed next time This Information was cause of failure last time It trip and cause catch * Also found out that Use genuine keys was cause of failure They did fit the sku There is the console window l Where you can see latest action Edit. found the problem with user key.
New version. Code: # ***************************** # # v15.0.0 compiled at 14-06-25 # # ***************************** # * Core libraries have been upgraded to improve performance, compatibility, and security.
Code: for /L %# in (0,1,1000) do @(>>keys.txt KeyInfo64 139b %# 0) findstr /b "NBBBB" keys.txt >>BBBs.txt