functions/Actions/VirtualMachines/Shutdown/Invoke-AzureFailureVMShutdown.ps1
|
function Invoke-AzureFailureVMShutdown { [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $true)] [string] $Step, [Parameter(Mandatory = $true)] [string] $Branch, [Parameter(Mandatory = $true)] [string[]] $TargetResourceId, [string] $Duration, [bool] $AbruptShutdown = $false, [string] $ActionName = "urn:csci:microsoft:virtualMachine:shutdown/1.0" ) if ($AbruptShutdown) { Write-PSFMessage -Level Warning -Message "Abrupt Shutdown enabled. This may cause data loss or corruption on the target VM(s)." } $actionJobs = @() foreach ($target in $TargetResourceId) { $actionJob = @{ TargetResourceId = $target } Write-PSFMessage -Level Verbose -Message "Shutting down VM: $target" try { $vmStatus = Get-AzVM -ResourceId $target -Status -ErrorAction Stop } catch { Write-PSFMessage -Level Warning -Message "Step ($Step), Branch ($Branch), Target ($target): Failed to get VM status. Error: $($_.Exception.Message)." $actionJob.Job = $false $actionJob.Status = "Error" $actionJob.StatusMessage = 'Failed to get VM status - {0}' -f ($_.Exception.Message -replace "`r`n", "\n") $actionJobs += $actionJob $paramUpdateAzureFailureTrace = @{ ResourceId = $target Step = $Step Branch = $Branch Action = $ActionName ActionStatus = $actionJob.Status ActionMessage = $actionJob.StatusMessage ActionTriggerTime = Get-Date } Update-AzureFailureTrace @paramUpdateAzureFailureTrace continue } if ( $vmStatus.Statuses[1].Code -eq "PowerState/running") { if ($PSCmdlet.ShouldProcess("Virtual Machine", "Shutdown")) { $actionJob.Job = Stop-AzVM -Id $target -Force:$true -SkipShutdown:$AbruptShutdown -AsJob } $actionJob.Status = "InProgress" } else { Write-PSFMessage -Level Warning -Message "Step ($Step), Branch ($Branch), Target ($target): VM is not in 'running' state. Current state: $($vmStatus.Statuses[1].DisplayStatus). Skipping shutdown." $actionJob.Job = $false $actionJob.Status = "Skipped" $actionJob.StatusMessage = 'VM is not in running state' } $actionJobs += $actionJob $paramUpdateAzureFailureTrace = @{ ResourceId = $target Step = $Step Branch = $Branch Action = $ActionName ActionStatus = $actionJob.Status ActionMessage = $actionJob.StatusMessage ActionTriggerTime = Get-Date } Update-AzureFailureTrace @paramUpdateAzureFailureTrace } $jobsToWaitFor = ($actionJobs | Where-Object { $_.Job -ne $false }).Job if ($jobsToWaitFor) { Write-PSFMessage -Level Verbose -Message "Waiting for {0} VM shutdown jobs to complete" -StringValues $jobsToWaitFor.Count $null = Wait-Job -Job $jobsToWaitFor Write-PSFMessage -Level Verbose -Message "VM shutdown jobs complete" } foreach ($actionJob in $actionJobs) { if($actionJob.Status -in @("Error", "Skipped")) { #TODO: Handle errors in the $actionJob.Job $actionStatus = $actionJob.Status } elseif($actionJob.Job.State -eq "Failed") { $actionStatus = "Error" $actionJob.StatusMessage = 'VM shutdown job failed: {0}' -f ($actionJob.Job.Error[0].Exception.Message -replace "`r`n", "\n") } else{ $actionStatus = if ($WhatIfPreference) { "WhatIf" } else { "Success" } } $actionCompleteTime = if ($actionJob.Job) { ($actionJob.Job | Receive-Job).EndTime } else { Get-Date } $paramUpdateAzureFailureTrace = @{ ResourceId = $actionJob.TargetResourceId Step = $Step Branch = $Branch ActionStatus = $actionStatus ActionMessage = $actionJob.StatusMessage Action = $ActionName ActionCompleteTime = $actionCompleteTime } Update-AzureFailureTrace @paramUpdateAzureFailureTrace } } |