Private/Invoke-KMSActivation.ps1

function Invoke-KMSActivation
{
    [CmdletBinding()]
    param(
        [Microsoft.Management.Infrastructure.CimSession]$CimSession,
        [CimInstance]$Service,
        [string]$KMSServerFQDN,
        [int]$KMSServerPort,
        [switch]$InstallKmsClientKey,
        [ValidatePattern('^[A-Za-z0-9]{5}(?:-[A-Za-z0-9]{5}){4}$')]
        [string]$ProductKey,
        [Guid]$ActivationId
    )

    if ($InstallKmsClientKey.IsPresent -and $PSBoundParameters.ContainsKey('ProductKey'))
    {
        throw 'InstallKmsClientKey and ProductKey cannot be used together.'
    }

    $installRequested = $InstallKmsClientKey.IsPresent -or $PSBoundParameters.ContainsKey('ProductKey')
    if ($installRequested -and $PSBoundParameters.ContainsKey('ActivationId'))
    {
        throw 'ActivationId cannot be combined with product-key installation because InstallProductKey is service-scoped.'
    }
    $kmsSettingsRequested = $PSBoundParameters.ContainsKey('KMSServerFQDN')
    if ($PSBoundParameters.ContainsKey('KMSServerPort')) { $kmsSettingsRequested = $true }
    $statusParams = @{ CimSession = $CimSession }
    if ($PSBoundParameters.ContainsKey('ActivationId')) { $statusParams['ActivationId'] = $ActivationId }
    $product = $null
    if ($PSBoundParameters.ContainsKey('ActivationId'))
    {
        $product = Get-WindowsLicensingProduct -CimSession $CimSession -ActivationId $ActivationId
    }
    if (-not $installRequested)
    {
        $licenseInfo = Get-LicenseStatus @statusParams
        Write-Verbose "License Status: $($licenseInfo.LicenseStatus)"
        if ($licenseInfo.Activated -and -not $kmsSettingsRequested)
        {
            Write-Warning 'The product is already activated.'
            return
        }
    }

    if ($PSBoundParameters.ContainsKey('KMSServerFQDN'))
    {
        $kmsTarget = if ($null -ne $product) { $product } else { $Service }
        $kmsTarget | Invoke-SppCimMethod -MethodName SetKeyManagementServiceMachine -Arguments @{ MachineName = $KMSServerFQDN }
        # Always set the port when changing the FQDN: without this, a stale non-default port
        # from a previous call would be reused, silently targeting the wrong endpoint.
        $effectivePort = if ($PSBoundParameters.ContainsKey('KMSServerPort')) { $KMSServerPort } else { 1688 }
        $kmsTarget | Invoke-SppCimMethod -MethodName SetKeyManagementServicePort -Arguments @{ PortNumber = $effectivePort }
    }
    elseif ($PSBoundParameters.ContainsKey('KMSServerPort'))
    {
        $kmsTarget = if ($null -ne $product) { $product } else { $Service }
        $kmsTarget | Invoke-SppCimMethod -MethodName SetKeyManagementServicePort -Arguments @{ PortNumber = $KMSServerPort }
    }

    if ($installRequested)
    {
        $keyToInstall = $ProductKey
        if ($InstallKmsClientKey.IsPresent)
        {
            $keyToInstall = Get-KMSKey -CimSession $CimSession
            if ($keyToInstall -eq 'Unknown')
            {
                throw 'No KMS client setup key is available for this OS edition. Provide a product key manually or use a recognised edition.'
            }
        }

        Write-Verbose 'Installing product key'
        $Service | Invoke-SppCimMethod -MethodName InstallProductKey -Arguments @{ ProductKey = $keyToInstall }
        Start-Sleep -Seconds 10 # Installing product key takes time.
        $Service | Invoke-SppCimMethod -MethodName RefreshLicenseStatus
        Start-Sleep -Seconds 2

        $partialProductKey = $keyToInstall.Substring($keyToInstall.Length - 5).ToUpperInvariant()
        $product = Get-WindowsLicensingProduct -CimSession $CimSession `
            -PartialProductKey $partialProductKey
        if ([string]::IsNullOrWhiteSpace($product.ID))
        {
            throw 'The licensing product selected after key installation has no activation ID; activation cannot continue safely.'
        }
        $statusParams['ActivationId'] = [Guid]$product.ID
    }

    # Activate the product selected after any requested key installation.
    if ($null -eq $product) { $product = Get-WindowsLicensingProduct -CimSession $CimSession }
    $product | Invoke-SppCimMethod -MethodName Activate
    $Service | Invoke-SppCimMethod -MethodName RefreshLicenseStatus

    $license = Get-LicenseStatus @statusParams
    if ($license.Activated)
    {
        Write-Verbose "The computer activated successfully. Current status: $($license.LicenseStatus)"
    }
    else
    {
        throw "Activation failed. Current status: $($license.LicenseStatus)"
    }
}