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])
    }
}