{"id":251,"date":"2024-04-02T20:00:00","date_gmt":"2024-04-02T18:00:00","guid":{"rendered":"https:\/\/schellevis-ict.nl\/?p=251"},"modified":"2025-09-16T15:20:23","modified_gmt":"2025-09-16T13:20:23","slug":"azure-automation-startstop-virtual-machines","status":"publish","type":"post","link":"https:\/\/schellevis-ict.nl\/?p=251","title":{"rendered":"Azure Automation: StartStop Virtual Machines"},"content":{"rendered":"\n<p>With my customers I often use the Azure Runbooks to stop certain virtual machines outside of business hours. Mostly non-production virtual machines that I have discussed, with the responsible teams, at what hours of the day or night these machines are not begin used, so you won&#8217;t burn compute costs. For production environment you are more likely to use reservations so the stopping of the VM&#8217;s won&#8217;t help in cutting costs.<br>You can use the script below within a Azure Runbook and a associated schedule to stop certain virtual machines at the time of the scheduled runbook. You will need to tag your virtual machines with &#8220;VMStartStop&#8221; and then with a certain number as a value.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>#StopVM automation script to shutdown VM's according to Runbook schedule\n\n#login to Azure\nWrite-Output \"Logging into Azure...\"\nConnect-AzAccount -Identity\n\nSelect-AzSubscription -SubscriptionId $RunAsConnection.SubscriptionID  | Write-Verbose\n    \n## List all subs\n$AllSubID = (Get-AzSubscription).SubscriptionId\nWrite-Output \"$(Get-Date -format s) - List of Subscription below\"\n$AllSubID\n\n$AllVMList = @()\nForeach ($SubID in $AllSubID) {\n    Select-AzSubscription -Subscriptionid \"$SubID\"\n\n    $VMs = Get-AzVM | Where-Object { $_.tags.VMStartStop -ne $null }\n    Foreach ($VM in $VMs) {\n        $VM = New-Object psobject -Property @{`\n                \"Subscriptionid\" = $SubID;\n            \"ResourceGroupName\"  = $VM.ResourceGroupName;\n            \"VMStartStop\"        = $VM.tags.VMStartStop;\n            \"VMName\"             = $VM.Name\n        }\n        $AllVMList += $VM | Select-Object Subscriptionid, ResourceGroupName, VMName, VMStartStop\n    }\n}\n\n## Sort VM's on priority\n$AllVMListSorted = $AllVMList | Sort-Object -Property VMStartStop\nWrite-Output \"$(Get-Date -format s) - Sort VM's on prio\"\n$AllVMListSorted\n\n##Start VMs block\nWrite-Output \"$(Get-Date -format s) - VM's stop.\"\n\nForeach ($VM in $AllVMListSorted) {\n    Write-Output \"$(Get-Date -format s) - Stop VM: $($VM.VMName) in RG: $($VM.ResourceGroupName)\"\n    Select-AzSubscription -Subscriptionid $VM.Subscriptionid\n    Stop-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.VMName -Force\n    Start-Sleep -s 5\n}\n\nWrite-Output \"$(Get-Date -format s) All VM's stopped.\"<\/code><\/pre>\n\n\n\n<p>The script will iterate through all your subscriptions and list the virtual machines that have been tagged. It also sorts them after so you can setup a particular sequence in shutting down virtual machines for a specific workload for example. The script used for starting the VM&#8217;s again is the exact same script except you will use the &#8220;Start-AzVM&#8221; cmdlet at the bottom:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Start-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.VMName<\/code><\/pre>\n\n\n\n<p>I hope this will help you on cutting down on compute costs within your environment or with your customers!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With my customers I often use the Azure Runbooks to stop certain virtual machines outside of business hours. Mostly non-production virtual machines that I have&hellip;<\/p>\n","protected":false},"author":1,"featured_media":252,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,11],"tags":[],"class_list":["post-251","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-azureautomation"],"_links":{"self":[{"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=\/wp\/v2\/posts\/251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=251"}],"version-history":[{"count":2,"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=\/wp\/v2\/posts\/251\/revisions"}],"predecessor-version":[{"id":275,"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=\/wp\/v2\/posts\/251\/revisions\/275"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=\/wp\/v2\/media\/252"}],"wp:attachment":[{"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/schellevis-ict.nl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}