Public/Initialize-WindowsDeviceLink.ps1

function Initialize-WindowsDeviceLink {
    <#
    .SYNOPSIS
    Safely ensures that the local DeviceLink has a tenant-side preassociation when appropriate.
 
    .DESCRIPTION
    Orchestrates existing WindowsDeviceLink operations without performing destructive repair.
    The cmdlet obtains the local DeviceLink, checks the tenant-side Device Association, classifies
    health, and creates a preassociation only when the validated state is LocalOnly.
 
    Existing preassociated or associated records are left unchanged. Unexpected, incomplete,
    unsupported, or unknown states are blocked rather than repaired automatically.
 
    For DeviceCode authentication, one token is acquired at the start and reused for lookup,
    registration, and verification so one initialization run requires only one device-code sign-in.
 
    This cmdlet never resets firmware state, removes an association, or reboots the device.
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory)]
        [ValidateSet('DeviceCode','Interactive','ClientSecret','AccessToken','Certificate','CertificateThumbprint','CertificateSubjectName','EnvironmentVariable','ManagedIdentity')]
        [string]$Method,
        [ValidateNotNullOrEmpty()][string]$TenantId,
        [ValidateNotNullOrEmpty()][string]$ClientId,
        [securestring]$AccessToken,
        [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate,
        [ValidateNotNullOrEmpty()][string]$CertificateThumbprint,
        [ValidateNotNullOrEmpty()][string]$CertificateSubjectName,
        [bool]$SendCertificateChain = $false,
        [securestring]$ClientSecret,
        [ValidateNotNullOrEmpty()][string]$Environment = 'Global',
        [ValidateRange(1, 600)][double]$ClientTimeout = 100,
        [ValidateNotNullOrEmpty()][string]$WindowsManagementServicePath,
        [ValidateRange(5, 600)][int]$TimeoutSeconds = 120
    )

    $effectiveAccessToken = $null
    try {
        $effectiveMethod = $Method
        if ($Method -eq 'DeviceCode') {
            if (-not $TenantId) { throw '-TenantId is required for -Method DeviceCode.' }
            if ($Environment -ne 'Global') { throw 'Native DeviceCode initialization currently supports the Global Microsoft cloud only.' }
            $tokenParameters = @{ TenantId = $TenantId }
            if ($ClientId) { $tokenParameters.ClientId = $ClientId }
            Write-Information -InformationAction Continue -MessageData 'Using native OAuth device-code authentication for DeviceLink initialization.'
            $token = Get-WindowsDeviceLinkDeviceCodeToken @tokenParameters
            $effectiveAccessToken = ConvertTo-SecureString $token.AccessToken -AsPlainText -Force
            $token = $null
            $effectiveMethod = 'AccessToken'
        }

        $commonOnline = @{ Method = $effectiveMethod; Environment = $Environment; ClientTimeout = $ClientTimeout }
        if ($effectiveAccessToken) {
            $commonOnline.TenantId = $TenantId
            $commonOnline.AccessToken = $effectiveAccessToken
        }
        else {
            foreach ($name in @('TenantId','ClientId','AccessToken','Certificate','CertificateThumbprint','CertificateSubjectName','SendCertificateChain','ClientSecret')) {
                if ($PSBoundParameters.ContainsKey($name)) { $commonOnline[$name] = $PSBoundParameters[$name] }
            }
        }

        $statusParameters = @{ Online = $true; Method = $effectiveMethod; Environment = $Environment; ClientTimeout = $ClientTimeout; TimeoutSeconds = $TimeoutSeconds }
        foreach ($key in $commonOnline.Keys) {
            if ($key -notin @('Method','Environment','ClientTimeout')) { $statusParameters[$key] = $commonOnline[$key] }
        }
        if ($PSBoundParameters.ContainsKey('WindowsManagementServicePath')) { $statusParameters.WindowsManagementServicePath = $WindowsManagementServicePath }

        $beforeStatus = Get-WindowsDeviceLinkStatus @statusParameters
        $beforeHealth = $beforeStatus | Test-WindowsDeviceLinkHealth
        $action = 'Blocked'; $changed = $false; $registration = $null
        $afterStatus = $beforeStatus; $afterHealth = $beforeHealth; $message = $beforeHealth.Summary

        switch ($beforeHealth.State) {
            'Preassociated' { $action = 'None'; $message = 'The DeviceLink is already preassociated. No change was made.' }
            'Associated' { $action = 'None'; $message = 'The DeviceLink is already associated. No change was made.' }
            'LocalOnly' {
                $action = 'Register'
                $deviceLinkParameters = @{ TimeoutSeconds = $TimeoutSeconds }
                if ($PSBoundParameters.ContainsKey('WindowsManagementServicePath')) { $deviceLinkParameters.WindowsManagementServicePath = $WindowsManagementServicePath }
                $deviceLink = Get-WindowsDeviceLink @deviceLinkParameters

                if ($PSCmdlet.ShouldProcess($deviceLink.SerialNumber, 'Create the missing tenant-side DeviceLink preassociation')) {
                    $registerParameters = @{}
                    foreach ($key in $commonOnline.Keys) { $registerParameters[$key] = $commonOnline[$key] }
                    $registerParameters.InputObject = $deviceLink
                    $registerParameters.Confirm = $false
                    $registration = Register-WindowsDeviceLink @registerParameters
                    $changed = $true
                    $afterStatus = Get-WindowsDeviceLinkStatus @statusParameters
                    $afterHealth = $afterStatus | Test-WindowsDeviceLinkHealth
                    if ($afterHealth.State -notin @('Preassociated','Associated')) {
                        throw "DeviceLink registration returned, but verification did not reach Preassociated or Associated. Verified state: $($afterHealth.State)."
                    }
                    $message = "DeviceLink registration completed and was verified as $($afterHealth.State)."
                }
                else { $message = 'The DeviceLink is locally valid and not associated; registration would be performed.' }
            }
            default { $message = "Initialization was blocked because the current health state is '$($beforeHealth.State)'. $($beforeHealth.RecommendedAction)" }
        }

        [pscustomobject]@{
            PSTypeName='Windows.DeviceLink.InitializationResult'; Action=$action; Changed=$changed
            BeforeState=$beforeHealth.State; AfterState=$afterHealth.State; Severity=$afterHealth.Severity; Message=$message
            SerialNumber=$beforeStatus.SerialNumber; LinkId=$beforeStatus.LinkId
            AssociationId=if ($afterStatus.AssociationId) { $afterStatus.AssociationId } elseif ($registration) { $registration.Id } else { $null }
            AssociationState=$afterStatus.AssociationState; FirmwareVariables=$afterStatus.FirmwareVariablesPresent
            RegistrationResult=$registration; BeforeStatus=$beforeStatus; AfterStatus=$afterStatus
        }
    }
    finally { $effectiveAccessToken = $null }
}