Public/Repair-WindowsLicense.ps1
|
#Requires -Version 5 <# .SYNOPSIS Reinstalls known-good Windows system license files. .DESCRIPTION Finds .xrm-ms files below the local Windows OEM and SPP token directories and reinstalls them through SoftwareLicensingService. This operation is local-only because the files must come from the target system's own Windows installation. .INPUTS None. .OUTPUTS None if successful. Throws after attempting every discovered license file when one or more files fail. .EXAMPLE Repair-WindowsLicense -Verbose .LINK https://github.com/zbalkan/slmgr-ps #> function Repair-WindowsLicense { [CmdletBinding(SupportsShouldProcess = $true, PositionalBinding = $false, ConfirmImpact = 'High')] param() $licenseFiles = @(Get-SystemLicenseFile -ErrorAction Stop) if (-not $PSCmdlet.ShouldProcess( 'localhost', "Reinstall $($licenseFiles.Count) Windows system license file(s)")) { return } $repairFailures = [System.Collections.Generic.List[System.Management.Automation.ErrorRecord]]::new() $session = $null try { $session = Get-Session -Computer 'localhost' -Credentials $null -ErrorAction Stop $service = Get-CimInstance -CimSession $session -ClassName SoftwareLicensingService -ErrorAction Stop $installedAny = $false foreach ($file in $licenseFiles) { try { $license = @(Get-LicenseFileContent -Path $file.FullName -ErrorAction Stop)[0] $service | Invoke-SppCimMethod -MethodName InstallLicense -Arguments @{ License = $license.Content } $installedAny = $true } catch { $message = "Failed to reinstall system license file '$($file.FullName)': $($_.Exception.Message)" $exception = [System.InvalidOperationException]::new($message, $_.Exception) $errorRecord = [System.Management.Automation.ErrorRecord]::new( $exception, 'WindowsSystemLicenseRepairFailed', [System.Management.Automation.ErrorCategory]::InvalidOperation, $file.FullName) $repairFailures.Add($errorRecord) } } if ($installedAny) { try { $service | Invoke-SppCimMethod -MethodName RefreshLicenseStatus } catch { $message = "System licenses were reinstalled, but licensing status could not be refreshed: $($_.Exception.Message)" $exception = [System.InvalidOperationException]::new($message, $_.Exception) $errorRecord = [System.Management.Automation.ErrorRecord]::new( $exception, 'WindowsSystemLicenseRefreshFailed', [System.Management.Automation.ErrorCategory]::InvalidOperation, 'localhost') $repairFailures.Add($errorRecord) } } } catch { $message = "System license repair could not start: $($_.Exception.Message)" $exception = [System.InvalidOperationException]::new($message, $_.Exception) $errorRecord = [System.Management.Automation.ErrorRecord]::new( $exception, 'WindowsSystemLicenseRepairStartFailed', [System.Management.Automation.ErrorCategory]::ConnectionError, 'localhost') $repairFailures.Add($errorRecord) } finally { if ($null -ne $session) { Remove-CimSession -CimSession $session -ErrorAction Ignore | Out-Null } } if ($repairFailures.Count -gt 0) { foreach ($failure in $repairFailures) { Write-Error -ErrorRecord $failure } $PSCmdlet.ThrowTerminatingError($repairFailures[0]) } } |