Stop-VMsInSequence.ps1
<#PSScriptInfo
.VERSION 1.0 .GUID 935665dd-8ead-431d-8697-7863edb1f6ec .AUTHOR info@thomas-zuehlke.de .COMPANYNAME .COPYRIGHT .TAGS AzureAutomation VirtualMachines Utility Stop .LICENSEURI .PROJECTURI https://www.thomas-zuehlke.de/2020/01/start-stop-vms-in-sequence-and-with-delay-via-azure-automation/ .ICONURI .EXTERNALMODULEDEPENDENCIES Az.Account Az.Compute .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> #Requires -Module Az.Account #Requires -Module Az.Compute <# .SYNOPSIS Connects to Azure and stops specified VMs in a sequence and including a wait time between the VMs. .DESCRIPTION Connects to Azure and stops specified VMs in a sequence and including a wait time between the VMs. It is based on Stop-AzureV2Vs (https://github.com/azureautomation/runbooks/blob/master/Utility/ARM/Stop-AzureV2VMs.ps1). If you provide the sequence "vm4, 30, vm3, 60, vm2, vm1", then VM4 stops first, then it waits 30 seconds before VM3 stops, then waits again for 60 seconds, then VM2 stops and finally VM4 stops. .PARAMETER AzureConnectionAssetName Optional with default of "AzureRunAsConnection". The name of an Automation connection asset that contains an Azure AD service principal with authorization for the subscription you want to start VMs in. To use an asset with a different name you can pass the asset name as a runbook input parameter or change the default value for this input parameter. .PARAMETER ResourceGroupName Mandatory All VMs in the sequence list, must be located in this resource group. .PARAMETER Sequence Mandatory A sequence of VM names of a resource group and waiting times in seconds. The informations are separated with commas. Example: vm1, vm2, 60, vm3 This stops vm1, then vm2, then waiting 1 minute and afterwards vm3 will be stopped. .NOTES AUTHOR: Thomas Zühlke LASTEDIT: Januar, 2020 #> # Returns strings with status messages [OutputType([String])] param ( [Parameter(Mandatory=$false)] [String] $AzureConnectionAssetName = "AzureRunAsConnection", [Parameter(Mandatory=$true)] [String] $ResourceGroupName, [Parameter(Mandatory=$true)] [String] $Sequence ) try { # Connect to Azure using service principal auth $ServicePrincipalConnection = Get-AutomationConnection -Name $AzureConnectionAssetName Write-Output "Logging in to Azure..." $Null = Add-AzAccount ` -ServicePrincipal ` -TenantId $ServicePrincipalConnection.TenantId ` -ApplicationId $ServicePrincipalConnection.ApplicationId ` -CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint } catch { if(!$ServicePrincipalConnection) { throw "Connection $AzureConnectionAssetName not found." } else { throw $_.Exception } } $elems = $Sequence.Split(",") foreach($elem in $elems){ $elem = $elem.Trim() [int]$seconds = 0 [bool]$result = [int]::TryParse($elem, [ref]$seconds) if($result -eq $true) { Write-Output "Sleeping $seconds ..." Start-Sleep $seconds }else { Write-Host "Stopping VM: $elem" $VM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $elem $StopRtn = $VM | Stop-AzVM -Force -ErrorAction Continue if ($StopRtn.Status -ne "Succeeded") { # The VM failed to stop, so send notice Write-Output ($VM.Name + " failed to stop") Write-Error ($VM.Name + " failed to stop. Error was:") -ErrorAction Continue Write-Error (ConvertTo-Json $StopRtn) -ErrorAction Continue } else { # The VM stoped, so send notice Write-Output ($VM.Name + " has been stoped") } } } |