Problem
How many times have you wanted to Start or Stop all Virtual Machines in an Azure Resource Group ? For me it seems to be quite often, especially for development environment resource groups. It’s not that difficult though. You can just enumerate the VM’s then cycle through them and call ‘Start-AzureRMVM’ or ‘Start-AzureRMVM’. However, the more VM’s you have, that approach running serially as PowerShell does means it can take quite some time to complete. Go to the Portal and right-click on each VM and start|stop ?
There has to be a way of starting/shutting down all VM’s in a Resource Group in parallel via PowerShell right ?
Some searching and it seems common to use Azure Automation and Workflow’s to accomplish it. But I don’t want to run this on schedule or necessarily mess around with Azure Automation for development environments, or have to connected to the portal and kickoff the workflow.
What I wanted was a script that was portable. That lead me to messing around with ‘ScriptBlocks’ and ‘Start-Job’ functions in PowerShell. Passing variables in for locally hosted jobs running against Azure though was painful. So I found a quick clean way of doing it, that I detail in this post.
Solution
I’m using the brilliant Invoke-Parallel Powershell Script from Cookie.Monster, to in essence multi-thread and run in parallel the Virtual Machine ‘start’ and ‘stop’ requests.
In my script at the bottom of this post I haven’t included the ‘invoke-parallel.ps1’. The link for it is in the paragraph above. You’ll need to either reference it at the start of your script, or include it in your script. If you want to keep it all together in a single script include it like I have in the screenshot below.
My rudimentary PowerShell script takes two parameters;
- Power state. Either ‘Start’ or ‘Stop’
- Resource Group. The name of the Azure Resource Group containing the Virtual Machines you are wanting to start/stop. eg. ‘RG01’
<
p style=”background:white;”>Example: .\AzureRGVMPowerGo.ps1 -power ‘Start’ -azureResourceGroup ‘RG01’ or PowerShell .\AzureRGVMPowerGo.ps1 -power ‘Start’ -azureResourceGroup ‘RG01’
Note: If you don’t have a session to Azure in your current environment, you’ll be prompted to authenticate.
Your VM’s will simultaneously start/stop.
What’s it actually doing ?
It’s pretty simple. The script enumerates the VM’s in the Resource Group you’ve specified. It looks to see the status of the VM’s (Running or Deallocated) that is the inverse of the ‘Power’ state you’ve specified when running the script. It’ll start stopped VM’s in the Resource Group when you run it with ‘Start’ or it will stop all started VM’s in the Resource Group when you run it with ‘Stop’. Simples.
This script could also easily be updated to do other similar tasks. Like, delete all VM’s in a Resource Group.
Here it is
Enjoy.
Follow Darren Robinson on Twitter
I like it , you saved me the time to write such a script , thanks a lot . few ideas for improvement . In my case I have multiple subscriptions so I have to change the script to use the subscription ID instead on tenant ID
Apologies, I may be missing something obvious. But, I can’t find your script on this article.
Hey Joe. It’s in the post but doesn’t show if your browsing on a mobile browser. Here’s the GIT link. https://gist.github.com/darrenjrobinson/960fdbd63d17569ada6e#file-azurergvmpowergo-ps1
Hi,
I am looking for runbook which can help to shutdown all vms in all resource groups in a single subscription id with exclusion list. can you help me.
Hey Sam, there are numerous sample scripts for that. Checkout this one for example.
https://gallery.technet.microsoft.com/scriptcenter/Stop-All-VMs-in-Specified-40c8531e
DR
That’s a great script – thank you.
I have a usecase where I want my customer to be able use a script like this to start/stop some of the VMs in their account, but NOT to be able to loging to the portal and make changes to the VM configuration.
Do you if/how I can set up a role to allow that access?
Regards,
Brendan
Hi Brendan. Have you looked at creating a custom role ? https://azure.microsoft.com/en-us/documentation/articles/role-based-access-control-custom-roles/
Great script. Saving me a ton of time. Thanks!
Perfect, going to work brilliantly with my DevTest Labs. Thank you.
Hi Darren,
I think I’m close, but I’m not sure where to go from here. I’m no longer getting, but the VMs aren’t being started either.
Enumerating VM’s from AzureRM in Resource Group ‘ AX2012R3-DevTest-Dev1-A-4ac3eae28e47cb84 ‘
WARNING: Breaking change notice: In upcoming release, top level properties, DataDiskNames and NetworkInterfaceIDs, will
be removed from VM object because they are also in StorageProfile and NetworkProfile, respectively.
Starting VM’s in Resource Group AX2012R3-DevTest-Dev1-A-4ac3eae28e47cb84
Thanks for this article and for your help!
Carolee
I’ve been using a similar script for months and started receiving an error:
Breaking change notice: In upcoming release, top level properties, DataDiskNames and NetworkInterfaceIDs, will be removed from VM object because they are also in StorageProfile and NetworkProfile, respectively.
RunbookFlow : Resource group ‘RESOURCE-GROUP’ could not be found.
ErrorCode: ResourceGroupNotFound
ErrorMessage: Resource group ‘RESOURCE-GROUP’ could not be found.
StatusCode: 404
ReasonPhrase: Not Found
OperationID : SOME_GUID_HERE
At line:9 char:57
+ RunbookFlow `
+ ~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Invoke-RunbookFlow], ComputeCloudException
+ FullyQualifiedErrorId : Orchestrator.GraphRunbook.Cmdlets.InvokeRunbookFlowCommand
Odd enough, a similar script will run on some VM’s but not on others.
Thoughts?
I get the same message indicating that DataDiskNames and NetworkInterface
IDs, will be removed but that’s just informational. The startup|shutdown functions still work as they always did. Looking at your message it appears that your runbook can’t find the ResourceGroup. Has it been renamed or is it in a different subscription ?
I see more like:
$SubscriptionName = Get-AzureRmSubscription | sort Name | Select Name
instead?