This post has been republished via RSS; it originally appeared at: Core Infrastructure and Security Blog articles.
1. Introduction
Managing the costs associated with running virtual machines (VMs) in Azure can be challenging, especially when VMs are left running during non-business hours. One effective solution is to schedule automatic shutdowns using Azure tags. In this blog, we'll walk you through a PowerShell script that uses an Azure tag to define and enforce VM shutdown schedules.
2. Prerequisites
Before you get started, ensure you have the following:
- An active Azure subscription.
- Appropriate permissions to manage VMs and read tag information.
- Basic knowledge of PowerShell scripting.
3. Script Overview
The script manages the power state of Azure virtual machines based on a specified tag and its value, which defines the schedule. For example, a tag named "AutoShutdownSchedule" with a value of "10PM -> 6AM" will shut down the VM at 10 PM and start it at 6 AM.
4. Detailed Script Breakdown
Parameters and Initial Setup
The script accepts three parameters:
TagName: The name of the tag to look for on virtual machines.ManagementGroupId: The ID of the Azure management group to operate on.Simulate: If set to$true, the script will only simulate the actions without making any changes.
param (
[parameter(Mandatory = $true)]
[string]$TagName,
[parameter(Mandatory = $true)]
[string]$ManagementGroupId,
[parameter(Mandatory = $false)]
[bool]$Simulate = $false
)
Function: Get-SubscriptionsUnderManagementGroup
This function retrieves all subscription IDs under a specified Azure management group.
Function: CheckScheduleEntry
This function checks if the current time falls within a specified time range.
Function: AssertVirtualMachinePowerState
This function ensures that a VM is in the desired power state (running or stopped) based on the schedule.
The script iterates through all VMs in the specified subscriptions, checks their tags, and enforces the power state according to the schedule. Below is the outline of what it does
try {
# Main script logic
}
catch {
$errorMessage = $_.Exception.Message
throw "Unexpected exception: $errorMessage"
}
finally {
Write-Output "Script finished (Duration: $(("{0:hh\:mm\:ss}" -f ((Get-Date).ToUniversalTime() - $currentTime))))"
}
5. Usage Example
To run the script, use the following command:
.\StartStopVMsBasedOnTag.ps1 -TagName "AutoShutdownSchedule" -ManagementGroupId "MngEnv" -Simulate $true
I will be running the example in Local PowerShell, but the PowerShell could be run from anywhere including Automation Accounts.
5.1 We tag our virtual machine accordingly
5.2 We look at our PowerShell code after being signed in to Azure and we run our command
5.3 We used the "-Simulate $true" flag which shows us what would have happened. If we want to run this in production, we can simulate first and when we are happy with our testing we can stop simulating by switching the "-Simulate $false"
6. Conclusion
Automating VM shutdown schedules using Azure tags helps optimize resource usage and reduce costs. By following this guide, you can implement a similar solution in your Azure environment. If you have any questions or feedback, feel free to leave a comment below. You can find a copy of this code in my GitHub Repo --> RallTheory/StartStopVMs/StartStopVMsBasedOnTag.ps1 at main · WernerRall147/RallTheory (github.com)
Disclaimer
The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts or Power BI Dashboards are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts or Power BI Dashboards be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. This blog post was written with the help of generative AI.
