|
2 | 2 | #Requires -Modules Az.Resources |
3 | 3 | #Requires -Modules Az.Compute |
4 | 4 |
|
5 | | -<#`n.SYNOPSIS |
6 | | - Check VM health |
| 5 | +<# |
| 6 | +.SYNOPSIS |
| 7 | + Check Azure VM health and status |
7 | 8 |
|
8 | 9 | .DESCRIPTION |
9 | | - Check VM health |
| 10 | + Retrieves comprehensive health information for an Azure Virtual Machine |
| 11 | + including power state, provisioning state, and detailed status information |
| 12 | + Author: Wes Ellis (wes@wesellis.com) |
| 13 | + Version: 1.0 |
10 | 14 |
|
| 15 | +.PARAMETER ResourceGroupName |
| 16 | + Name of the resource group containing the VM |
11 | 17 |
|
12 | | - Author: Wes Ellis (wes@wesellis.com) |
13 | | -[CmdletBinding()] |
| 18 | +.PARAMETER VMName |
| 19 | + Name of the virtual machine to check |
14 | 20 |
|
15 | | -$ErrorActionPreference = 'Stop' |
| 21 | +.PARAMETER Detailed |
| 22 | + Show detailed status information including all status codes |
| 23 | +
|
| 24 | +.PARAMETER OutputFormat |
| 25 | + Output format: Console (default), JSON, or Table |
| 26 | +
|
| 27 | +.EXAMPLE |
| 28 | + .\Azure-VM-Health-Monitor.ps1 -ResourceGroupName "rg-prod" -VMName "vm-web01" |
| 29 | + Gets basic health status for the specified VM |
| 30 | +
|
| 31 | +.EXAMPLE |
| 32 | + .\Azure-VM-Health-Monitor.ps1 -ResourceGroupName "rg-prod" -VMName "vm-web01" -Detailed |
| 33 | + Gets detailed health status including all status codes |
| 34 | +
|
| 35 | +.EXAMPLE |
| 36 | + .\Azure-VM-Health-Monitor.ps1 -ResourceGroupName "rg-prod" -VMName "vm-web01" -OutputFormat JSON |
| 37 | + Outputs health status in JSON format |
16 | 38 |
|
| 39 | +.NOTES |
| 40 | + Requires Az.Compute module and appropriate permissions |
| 41 | +#> |
| 42 | + |
| 43 | +[CmdletBinding()] |
| 44 | +param( |
| 45 | + [Parameter(Mandatory = $true)] |
| 46 | + [ValidateNotNullOrEmpty()] |
17 | 47 | [string]$ResourceGroupName, |
18 | | - [string]$VmName |
| 48 | + |
| 49 | + [Parameter(Mandatory = $true)] |
| 50 | + [ValidateNotNullOrEmpty()] |
| 51 | + [string]$VMName, |
| 52 | + |
| 53 | + [Parameter()] |
| 54 | + [switch]$Detailed, |
| 55 | + |
| 56 | + [Parameter()] |
| 57 | + [ValidateSet("Console", "JSON", "Table")] |
| 58 | + [string]$OutputFormat = "Console" |
19 | 59 | ) |
20 | | -$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VmName -Status |
21 | | -Write-Output "VM Name: $($VM.Name)" |
22 | | -Write-Output "Resource Group: $($VM.ResourceGroupName)" |
23 | | -Write-Output "Location: $($VM.Location)" |
24 | | -Write-Output "Power State: $($VM.PowerState)" |
25 | | -Write-Output "Provisioning State: $($VM.ProvisioningState)" |
26 | | -foreach ($Status in $VM.Statuses) { |
27 | | - Write-Output "Status: $($Status.Code) - $($Status.DisplayStatus)"`n} |
| 60 | + |
| 61 | +$ErrorActionPreference = 'Stop' |
| 62 | + |
| 63 | +function Write-LogMessage { |
| 64 | + param( |
| 65 | + [Parameter(Mandatory = $true)] |
| 66 | + [string]$Message, |
| 67 | + |
| 68 | + [Parameter()] |
| 69 | + [ValidateSet("INFO", "WARN", "ERROR", "SUCCESS")] |
| 70 | + [string]$Level = "INFO" |
| 71 | + ) |
| 72 | + |
| 73 | + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" |
| 74 | + $colorMap = @{ |
| 75 | + "INFO" = "Cyan" |
| 76 | + "WARN" = "Yellow" |
| 77 | + "ERROR" = "Red" |
| 78 | + "SUCCESS" = "Green" |
| 79 | + } |
| 80 | + |
| 81 | + if ($OutputFormat -eq "Console") { |
| 82 | + Write-Host "[$timestamp] [$Level] $Message" -ForegroundColor $colorMap[$Level] |
| 83 | + } |
| 84 | +} |
| 85 | + |
| 86 | +try { |
| 87 | + Write-LogMessage "Retrieving VM health status..." -Level "INFO" |
| 88 | + Write-LogMessage "Resource Group: $ResourceGroupName" -Level "INFO" |
| 89 | + Write-LogMessage "VM Name: $VMName" -Level "INFO" |
| 90 | + |
| 91 | + # Get VM with status |
| 92 | + $vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName -Status -ErrorAction Stop |
| 93 | + |
| 94 | + if (-not $vm) { |
| 95 | + throw "VM '$VMName' not found in resource group '$ResourceGroupName'" |
| 96 | + } |
| 97 | + |
| 98 | + # Build health status object |
| 99 | + $healthStatus = [PSCustomObject]@{ |
| 100 | + VMName = $vm.Name |
| 101 | + ResourceGroup = $vm.ResourceGroupName |
| 102 | + Location = $vm.Location |
| 103 | + PowerState = ($vm.Statuses | Where-Object { $_.Code -like "PowerState/*" } | Select-Object -First 1).DisplayStatus |
| 104 | + ProvisioningState = $vm.ProvisioningState |
| 105 | + VMSize = $vm.HardwareProfile.VmSize |
| 106 | + OSType = $vm.StorageProfile.OsDisk.OsType |
| 107 | + CheckTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss" |
| 108 | + Statuses = @() |
| 109 | + } |
| 110 | + |
| 111 | + # Add detailed statuses if requested |
| 112 | + if ($Detailed) { |
| 113 | + $healthStatus.Statuses = $vm.Statuses | ForEach-Object { |
| 114 | + [PSCustomObject]@{ |
| 115 | + Code = $_.Code |
| 116 | + Level = $_.Level |
| 117 | + DisplayStatus = $_.DisplayStatus |
| 118 | + Message = $_.Message |
| 119 | + Time = $_.Time |
| 120 | + } |
| 121 | + } |
| 122 | + } |
| 123 | + |
| 124 | + # Output in requested format |
| 125 | + switch ($OutputFormat) { |
| 126 | + "JSON" { |
| 127 | + $healthStatus | ConvertTo-Json -Depth 5 |
| 128 | + } |
| 129 | + "Table" { |
| 130 | + Write-Host "`n=== VM Health Status ===" -ForegroundColor Cyan |
| 131 | + $healthStatus | Format-List VMName, ResourceGroup, Location, PowerState, ProvisioningState, VMSize, OSType, CheckTime |
| 132 | + |
| 133 | + if ($Detailed) { |
| 134 | + Write-Host "`n=== Detailed Statuses ===" -ForegroundColor Cyan |
| 135 | + $healthStatus.Statuses | Format-Table Code, DisplayStatus, Level -AutoSize |
| 136 | + } |
| 137 | + } |
| 138 | + "Console" { |
| 139 | + Write-Host "`n=== VM Health Status ===" -ForegroundColor Cyan |
| 140 | + Write-Host "VM Name: $($healthStatus.VMName)" -ForegroundColor White |
| 141 | + Write-Host "Resource Group: $($healthStatus.ResourceGroup)" -ForegroundColor White |
| 142 | + Write-Host "Location: $($healthStatus.Location)" -ForegroundColor White |
| 143 | + Write-Host "VM Size: $($healthStatus.VMSize)" -ForegroundColor White |
| 144 | + Write-Host "OS Type: $($healthStatus.OSType)" -ForegroundColor White |
| 145 | + |
| 146 | + # Color-code power state |
| 147 | + $powerStateColor = switch -Wildcard ($healthStatus.PowerState) { |
| 148 | + "*running*" { "Green" } |
| 149 | + "*deallocated*" { "Yellow" } |
| 150 | + "*stopped*" { "Red" } |
| 151 | + default { "White" } |
| 152 | + } |
| 153 | + Write-Host "Power State: $($healthStatus.PowerState)" -ForegroundColor $powerStateColor |
| 154 | + Write-Host "Provisioning State: $($healthStatus.ProvisioningState)" -ForegroundColor White |
| 155 | + Write-Host "Check Time: $($healthStatus.CheckTime)" -ForegroundColor Gray |
| 156 | + |
| 157 | + if ($Detailed) { |
| 158 | + Write-Host "`n=== Detailed Statuses ===" -ForegroundColor Cyan |
| 159 | + foreach ($status in $vm.Statuses) { |
| 160 | + $statusColor = switch ($status.Level) { |
| 161 | + "Info" { "Cyan" } |
| 162 | + "Warning" { "Yellow" } |
| 163 | + "Error" { "Red" } |
| 164 | + default { "White" } |
| 165 | + } |
| 166 | + Write-Host " [$($status.Level)] $($status.Code): $($status.DisplayStatus)" -ForegroundColor $statusColor |
| 167 | + if ($status.Message) { |
| 168 | + Write-Host " Message: $($status.Message)" -ForegroundColor Gray |
| 169 | + } |
| 170 | + } |
| 171 | + } |
| 172 | + Write-Host "" |
| 173 | + } |
| 174 | + } |
| 175 | + |
| 176 | + # Return the health status object |
| 177 | + return $healthStatus |
| 178 | + |
| 179 | +} catch { |
| 180 | + Write-LogMessage "Failed to retrieve VM health: $($_.Exception.Message)" -Level "ERROR" |
| 181 | + throw |
| 182 | +} |
0 commit comments