Public/Invoke-CloudPCEndGracePeriod.ps1
|
function Invoke-CloudPCEndGracePeriod { <# .SYNOPSIS Ends the grace period for one or more Windows 365 Cloud PCs. .DESCRIPTION Calls Microsoft Graph beta https://graph.microsoft.com/beta/deviceManagement/virtualEndpoint/cloudPCs/{id}/endGracePeriod to end the grace period for a Cloud PC. Ending grace period immediately deprovisions the Cloud PC without waiting the seven-day grace period. Use Get-CloudPC -ProvisioningStatus inGracePeriod to review targets before invoking this action. The service processes this action asynchronously. After Graph accepts the request, the Cloud PC can continue to appear as inGracePeriod for several minutes while Windows 365 state converges. Use -Wait to poll until the Cloud PC leaves inGracePeriod or the timeout is reached. .PARAMETER CloudPC A WindowsCloudPC.CloudPC object returned by Get-CloudPC, or an exact Cloud PC identifier. .PARAMETER Id The Cloud PC ID. .PARAMETER All Ends grace period for every Cloud PC returned by Get-CloudPC -ProvisioningStatus inGracePeriod. .PARAMETER Force Suppress confirmation prompts. Equivalent to -Confirm:$false. .PARAMETER Wait Poll after a successful request until the Cloud PC leaves inGracePeriod, is no longer returned, or TimeoutSeconds is reached. .PARAMETER PollIntervalSeconds Seconds between wait checks. Defaults to 30. .PARAMETER TimeoutSeconds Maximum seconds to wait. Defaults to 600. .PARAMETER PassThru Emit a WindowsCloudPC.EndGracePeriodResult object for each target. .EXAMPLE Get-CloudPC -ProvisioningStatus inGracePeriod .EXAMPLE Invoke-CloudPCEndGracePeriod -CloudPC 'CPC-USER-01' -WhatIf .EXAMPLE Invoke-CloudPCEndGracePeriod -All -WhatIf .EXAMPLE Invoke-CloudPCEndGracePeriod -CloudPC 'CPC-USER-01' -Force -PassThru -Wait #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'ByObject')] [OutputType('WindowsCloudPC.EndGracePeriodResult')] param( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByObject')] [object]$CloudPC, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'ById')] [Alias('CloudPcId')] [string]$Id, [Parameter(Mandatory, ParameterSetName = 'All')] [switch]$All, [switch]$Force, [switch]$Wait, [ValidateRange(5, 3600)] [int]$PollIntervalSeconds = 30, [ValidateRange(5, 86400)] [int]$TimeoutSeconds = 600, [switch]$PassThru ) begin { if ($Force -and -not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = 'None' } Connect-CloudPC -AdditionalScopes 'CloudPC.ReadWrite.All' | Out-Null } process { $targets = @() if ($PSCmdlet.ParameterSetName -eq 'All') { $targets = @(Get-CloudPC -ProvisioningStatus inGracePeriod) } elseif ($PSCmdlet.ParameterSetName -eq 'ById') { $targets = @(Resolve-CloudPCTarget -Id $Id -CommandName 'Invoke-CloudPCEndGracePeriod') } else { try { $targets = @(Resolve-CloudPCTarget -CloudPC $CloudPC -CommandName 'Invoke-CloudPCEndGracePeriod') } catch { Write-Error -ErrorRecord $_ return } } if ($targets.Count -eq 0) { Write-Warning 'Invoke-CloudPCEndGracePeriod: no Cloud PCs in grace period were found.' return } foreach ($targetPc in $targets) { $target = "Cloud PC '$($targetPc.Name)' ($($targetPc.Id))" $status = 'Accepted' $errorMessage = $null $requestedAt = [datetime]::Now $completedAt = $null $lastObservedProvisioningStatus = $targetPc.ProvisioningStatus $waitTimedOut = $false $verificationCommand = "Get-CloudPC -ProvisioningStatus inGracePeriod,deprovisioning | Where-Object Id -eq '$($targetPc.Id)'" if (-not $PSCmdlet.ShouldProcess($target, 'End grace period and deprovision')) { if ($PassThru) { [pscustomobject]@{ PSTypeName = 'WindowsCloudPC.EndGracePeriodResult' CloudPcId = $targetPc.Id CloudPcName = $targetPc.Name Status = 'WhatIf' RequestedAt = $null CompletedAt = $null WaitRequested = [bool]$Wait WaitTimedOut = $false LastObservedProvisioningStatus = $targetPc.ProvisioningStatus ExpectedStateLag = '5-10 minutes' VerificationCommand = $verificationCommand ErrorMessage = $null } } continue } $escapedCloudPcId = [uri]::EscapeDataString($targetPc.Id) $uri = "https://graph.microsoft.com/beta/deviceManagement/virtualEndpoint/cloudPCs/$escapedCloudPcId/endGracePeriod" try { Invoke-MgGraphRequest -Method POST -Uri $uri | Out-Null } catch { $status = 'Failed' $errorMessage = $_.Exception.Message Write-Error -Message "Invoke-CloudPCEndGracePeriod: action failed for $target - $errorMessage" -Exception $_.Exception } if ($Wait -and $status -eq 'Accepted') { $deadline = (Get-Date).AddSeconds($TimeoutSeconds) do { try { $current = Get-CloudPC -Id $targetPc.Id $lastObservedProvisioningStatus = $current.ProvisioningStatus if ($lastObservedProvisioningStatus -ne 'inGracePeriod') { $status = 'Completed' $completedAt = [datetime]::Now break } } catch { $lastObservedProvisioningStatus = 'NotFound' $status = 'Completed' $completedAt = [datetime]::Now break } if ((Get-Date) -ge $deadline) { $waitTimedOut = $true $status = 'Accepted' break } Start-Sleep -Seconds $PollIntervalSeconds } while ($true) } if ($PassThru) { [pscustomobject]@{ PSTypeName = 'WindowsCloudPC.EndGracePeriodResult' CloudPcId = $targetPc.Id CloudPcName = $targetPc.Name Status = $status RequestedAt = $requestedAt CompletedAt = $completedAt WaitRequested = [bool]$Wait WaitTimedOut = $waitTimedOut LastObservedProvisioningStatus = $lastObservedProvisioningStatus ExpectedStateLag = '5-10 minutes' VerificationCommand = $verificationCommand ErrorMessage = $errorMessage } } } } } |