如何用PowerShell查询Azure VMSS中VM的运行时长(筛选超6小时实例)
解决方案:获取VMSS实例运行时长并筛选超6小时的实例
我之前也碰到过类似的情况,Get-AzureRmLog有时候因为日志保留策略、事件筛选范围或者权限问题,拿不到准确的VM启动时间。相比之下,直接从虚拟机内部读取启动时间会更可靠——不管是Linux还是Windows,都能通过系统自身命令或Azure实例元数据服务(IMDS)获取。下面给你一个完整的PowerShell脚本,帮你实现需求:
# 1. 连接到Azure(如果还未连接) Connect-AzureRmAccount # 2. 配置目标VMSS信息,替换为你的实际值 $vmssName = "Your-VMSS-Name" $resourceGroupName = "Your-Resource-Group-Name" $thresholdHours = 6 # 运行时长阈值,这里设为6小时 # 3. 获取VMSS中的所有虚拟机实例 $vmssInstances = Get-AzureRmVmssVM -ResourceGroupName $resourceGroupName -VMScaleSetName $vmssName # 4. 初始化结果数组,用来存储符合条件的VM $longRunningVMs = @() # 5. 遍历每个VM实例,计算运行时长并筛选 foreach ($vm in $vmssInstances) { # 跳过已解除分配的实例(这类实例无法执行命令获取启动时间) if ($vm.Statuses[1].Code -ne "PowerState/running") { Write-Host "跳过已解除分配的实例: $($vm.Name)" continue } try { # 根据OS类型执行对应命令获取启动时间 if ($vm.OsProfile.WindowsConfiguration) { # Windows VM:通过PowerShell读取系统启动时间 $commandResult = Invoke-AzureRmVMRunCommand -ResourceGroupName $resourceGroupName -VMName $vm.Name ` -CommandId 'RunPowerShellScript' -ScriptString "Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime" $startTime = [DateTime]::Parse($commandResult.Value[0].Message) } elseif ($vm.OsProfile.LinuxConfiguration) { # Linux VM:通过系统运行时间反推启动时间 $commandResult = Invoke-AzureRmVMRunCommand -ResourceGroupName $resourceGroupName -VMName $vm.Name ` -CommandId 'RunShellScript' -ScriptString "date -d `$(cat /proc/uptime | awk '{print $1}') seconds ago --iso-8601=seconds" $startTime = [DateTime]::Parse($commandResult.Value[0].Message) } else { Write-Host "无法识别实例 $($vm.Name) 的OS类型" continue } # 计算运行时长,保留两位小数 $uptimeHours = [math]::Round(((Get-Date) - $startTime).TotalHours, 2) # 筛选超过阈值的实例 if ($uptimeHours -gt $thresholdHours) { $longRunningVMs += [PSCustomObject]@{ VMName = $vm.Name OSType = if ($vm.OsProfile.WindowsConfiguration) { "Windows" } else { "Linux" } StartTime = $startTime UptimeHours = $uptimeHours ResourceGroupName = $resourceGroupName VMScaleSetName = $vmssName } } } catch { Write-Host "获取实例 $($vm.Name) 启动时间失败: $_" continue } } # 6. 输出最终结果 Write-Host "`n运行时长超过$thresholdHours小时的VM实例:" $longRunningVMs | Format-Table -AutoSize
关键注意事项:
- 确保你拥有
Microsoft.Compute/virtualMachines/runCommand/action权限,否则无法执行Invoke-AzureRmVMRunCommand命令。 - 如果你的Azure模块是较新的Az系列(推荐升级),只需把所有
AzureRm前缀替换为Az即可(比如Connect-AzAccount、Get-AzVmssVM)。 - Linux VM的命令依赖
proc文件系统和awk工具,主流发行版默认都包含这些组件。
如果你仍想尝试用Get-AzureRmLog的方式,可以试试以下命令(需要指定足够宽的时间范围),但这种方式受限于日志保留期(默认90天)和事件完整性:
Get-AzureRmLog -ResourceGroupName $resourceGroupName -ResourceName $vm.Name -ResourceType "Microsoft.Compute/virtualMachines" ` -StartTime (Get-Date).AddDays(-30) -EndTime (Get-Date) | Where-Object {$_.OperationName.Value -eq "Microsoft.Compute/virtualMachines/start/action"} ` | Select-Object EventTimestamp, ResourceName | Sort-Object EventTimestamp -Descending | Select-Object -First 1
内容的提问来源于stack exchange,提问作者Bindu
相关产品推荐
相关产品推荐

