Imagine this: You’re responsible for overseeing a range of virtual machines (VMs) in your Azure environment. However, you’re also someone who values efficiency. Why spend time on manual tasks when automation can make your life easier? In this article, we’ll introduce a script that streamlines the process of stopping, starting, and checking the status of your Azure VMs.
Why the drama?
Before we dive into the script, let’s answer a crucial question: why perform these operations on Azure VMs? In the realm of the cloud, managing Azure VMs can be similar to tending to digital pets, especially when handling a multitude of them without a fixed schedule for starting, stopping, or status checks.
- Cost Control: Every second your VMs run, coins are drained from your Azure treasure chest. Stopping idle VMs saves you shiny gold.
- Maintenance Marvel: VMs need TLC. Updates, patches, and configurations often require them to be stopped and started.
- Health and Sanity: Sometimes, VMs decide to take a stroll on the wild side. Checking their status ensures awareness of your VM state.
Let’s script
To simplify the process, we’ll utilize Azure Cloud Shell. Let’s assume you have a substantial number of VMs, possibly hundreds distributed across various resource groups and environments (e.g., production, development). An approach will be to filter the VMs for operations based on pre-existing tags. In this article, we’ll instead us an Excel sheet containing the list of VMs for querying. Here is mine called VMlists.csv:
Start VMs:
The below script starts the VMs based on the user input. It loops through each VMs in the CSV file. The operation would be run based on the OS type and the action (stop/start/status) specified.
Write-Host "`nWelcome, this script allows you to start, stop and check status of multiple VMs in various resource groups in parallel. `n"
Write-Host "`nEnter action (start/stop/status):"
$Action = Read-Host
Write-Host "`nSpecify environment(prod/dev):"
$OS_TYPE = Read-Host
$VirtualMachinesDetails = Import-Csv .\VMLists.csv #Imports csv file from the specified path
if ($Action -eq "start"){
Write-Host "Please specifiy the environment (Prod/Dev)"
$VM_Environment = Read-Host
Write-Host "`nStarting all $OS_TYPE Virtual machines in the $VM_Environment environment..."
$VirtualMachinesDetails | Where-Object {($_.VM_OS -eq $OS_TYPE) -and ($_.VM_Environment -eq $VM_Environment)} | ForEach-Object -parallel { #filters and fetches the csv files content based on the OS type.
$checkIfVMExistInRG = get-azvm -ResourceGroupName $_.VM_RG -name $_.VM_Name -ErrorVariable notPresent -ErrorAction SilentlyContinue # Checks if the VM exists in the RG
if ($notPresent){
continue
}
else {
Start-AzVM -ResourceGroupName $_.VM_RG -Name $_.VM_Name
}
} -ThrottleLimit 10
}
The VMs are started in parallel (10 at once, instead of one by one). The limit was set to 10 to manage your compute resources.
Stop VMs:
The below script loops through the VMs based on user inputs and stop the VMs.
elseif ($Action -eq "stop"){
$OS_TYPE = "Windows"
Write-Host "Please specifiy the environment (Prod/Dev/Test):"
$VM_Environment = Read-Host
Write-Host "`nStopping all $OS_TYPE Virtual machines in the $VM_Environment environment..."
$VirtualMachinesDetails | Where-Object {($_.VM_OS -eq $OS_TYPE) -and ($_.VM_Environment -eq $VM_Environment)} | ForEach-Object -parallel {
$checkIfVMExistInRG = get-azvm -ResourceGroupName $_.VM_RG -name $_.VM_Name -ErrorVariable notPresent -ErrorAction SilentlyContinue
if ($notPresent){
continue
}
else {
Stop-AzVM -ResourceGroupName $_.VM_RG -Name $_.VM_Name -Confirm:$false -ErrorAction SilentlyContinue -Force
}
} -ThrottleLimit 10
}
Get VM status:
The below script loops through the VMs and get their current state. It checks if they are running properly or in a bad state.
elseif($Action -eq "status"){
Write-Host "`nGetting status of all Virtual machines..."
$Rg_Exist = @()
$Vm_Exist = @()
$vmStatuses = @()
$VirtualMachinesDetails | ForEach-Object {
if ($Rg_Exist.Contains($_.ResourceGroupName) -and $Vm_Exist.Contains($_.VM_Name)) {
return
}
else {
$VMstatus = Get-AzVM -Name $_.VM_Name -ResourceGroupName $_.ResourceGroupName -Status
$VMdetails = Get-AzVM -Name $_.VM_Name -ResourceGroupName $_.ResourceGroupName
$Environment = $_.VM_Environment
$vmInfo = [PSCustomObject]@{
ResourceGroupName = $vmStatus.ResourceGroupName
Name = $vmStatus.Name
Environment = $Environment
Location = $VMdetails.Location
OsType = $VMdetails.StorageProfile.OsDisk.OsType
Disk_Status = $vmStatus.Disks.Statuses.code
VMAgentStatus = $vmStatus.VMAgent.Statuses.DisplayStatus
PowerState = $vmStatus.Statuses[1].DisplayStatus
Provisioning = $vmStatus.Statuses[0].DisplayStatus
MaintenanceAllowed = $vmStatus.MaintenanceRedeployStatus.IsCustomerInitiatedMaintenanceAllowed
}
$vmStatuses += $vmInfo
$Rg_Exist += $_.ResourceGroupName
$Vm_Exist += $_.VM_Name
}
}
$vmStatuses | Format-Table -AutoSize
}
else {
Write-Host "action not recognized"
}
You can modify the script based on your use case. For the full script, check my GitHub: https://github.com/Toch-vybe/Powershell-scripts/blob/9a993126ba967746db9f0bad0998b1fd933a7004/vm-manager.ps1
Now let’s try the script out in the cloud shell.
Login into your Azure account and click the cloud shell icon at the top.
You will have to create or select an existing storage account where your scripts would be stored.
Upload the csv file containing the VMs and the PowerShell script into the cloud shell:
Now open the editor to confirm your uploaded files:
Next, run the script in the shell and follow the prompt using:
./<the name of your script>.ps1
Below is how it should look like when you run the scripts:
Conclusion
In the world of Azure, scripts are valuable tools that can simplify your administrative tasks. They allow you to manage your Azure resources efficiently, saving time and effort. So, I encourage you to embrace the power of automation. Your Azure VMs will benefit, and you’ll free up more time for other pursuits, whether it’s conquering new digital challenges or enjoying some well-deserved relaxation.
Until next time, keep scripting, and continue to excel in your Azure endeavors!
Top comments (0)