求编写Azure订阅内批量执行VM脚本并导出结果的PowerShell脚本
批量在Azure订阅VM上运行脚本并导出结果
问题说明
我有一个名为VARIASUIT_CHECK_WINDOWS.ps1的脚本,在Windows VM上运行后会返回CSV格式的检查结果:
"Server Name","GPO_HARMOR","BIOMEDIC_AGENT","EDWARD_STATUS","SENSOR_STATUS","SENTINEL_STATUS"
"TEST-AZ-VM","OK","OK","OK","OK","OK"
现在需要编写脚本,自动获取指定Azure订阅下的所有Windows VM,在每台VM上运行该检查脚本,并将所有结果汇总写入CSV文档。之前尝试的单VM执行脚本可以运行,但添加遍历订阅内所有VM的循环后未成功。
尝试的单VM代码:
$vmId = "/subscriptions/xxxxxxxx/resourceGroups/TESTRG/providers/Microsoft.Compute/virtualMachines/TEST-AZ-VM" # Run the "VARIASUIT_CHECK_WINDOWS.ps1" file on the Virtual Machine using the Azure CLI $scriptResult = az vm run-command invoke ` --command-id RunPowerShellScript ` --ids $vmId ` --scripts VARIASUIT_CHECK_WINDOWS.ps1 Write-Host $scriptResult
解决方案脚本
以下是修正后的批量执行脚本,解决了循环遍历和脚本上传的问题:
# 1. 设置目标Azure订阅ID $targetSubscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 设置结果输出文件路径 $outputCsvPath = ".\VM_Check_Results.csv" # 2. 切换到目标订阅 az account set --subscription $targetSubscriptionId # 3. 获取订阅下所有处于运行状态的Windows VM(过滤掉Linux和已停止的VM) $vms = az vm list --query "[?storageProfile.osDisk.osType=='Windows' && powerState=='VM running'].id" --output tsv # 4. 初始化结果文件,写入表头(如果你的检查脚本会返回表头,可跳过这行,避免重复) "Server Name","GPO_HARMOR","BIOMEDIC_AGENT","EDWARD_STATUS","SENSOR_STATUS","SENTINEL_STATUS" | Out-File -FilePath $outputCsvPath -Encoding utf8 # 5. 遍历每台VM执行检查脚本 foreach ($vmId in $vms) { Write-Host "正在处理VM: $vmId" try { # 执行脚本:注意用@符号指定本地脚本文件,Azure CLI会自动上传到VM执行 $rawResult = az vm run-command invoke ` --command-id RunPowerShellScript ` --ids $vmId ` --scripts @VARIASUIT_CHECK_WINDOWS.ps1 ` --query "value[0].message" ` --output tsv # 解析结果:去掉多余的换行和空格,只提取CSV数据行 $cleanResult = $rawResult -split "`n" | Where-Object { $_ -match '^"[^"]+"(,"[^"]+")+$' } # 如果结果中有表头,只取数据行(避免重复写入表头) if ($cleanResult[0] -eq '"Server Name","GPO_HARMOR","BIOMEDIC_AGENT","EDWARD_STATUS","SENSOR_STATUS","SENTINEL_STATUS"') { $dataRow = $cleanResult[1] } else { $dataRow = $cleanResult[0] } # 将数据行追加到结果文件 $dataRow | Out-File -FilePath $outputCsvPath -Encoding utf8 -Append Write-Host "VM处理完成,结果已写入文件" } catch { Write-Host "处理VM $vmId 时出错: $_" # 将错误信息写入结果文件(可选) "`"$($vmId.Split('/')[-1])`",`"ERROR`",`"ERROR`",`"ERROR`",`"ERROR`",`"ERROR`"" | Out-File -FilePath $outputCsvPath -Encoding utf8 -Append } } Write-Host "所有VM处理完成,结果文件路径: $outputCsvPath"
关键修正点
- 脚本上传方式:使用
@VARIASUIT_CHECK_WINDOWS.ps1替代直接写文件名,Azure CLI会将本地脚本文件上传到目标VM执行,这是之前单VM代码可能未生效的核心原因之一。 - VM过滤:只筛选运行中的Windows VM,避免对已停止或Linux VM执行脚本导致错误。
- 结果解析:处理az命令返回的原始输出,提取有效的CSV数据行,避免写入多余的日志信息。
- 错误处理:捕获执行过程中的异常,将错误状态写入结果文件,确保脚本不会因单台VM失败而中断。
使用前注意事项
- 确保已安装并登录Azure CLI:
az login - 确保当前账号拥有目标订阅下VM的
Microsoft.Compute/virtualMachines/runCommand/action权限 - 将
VARIASUIT_CHECK_WINDOWS.ps1脚本放在当前脚本的同一目录下,或者指定完整路径(如@C:\Scripts\VARIASUIT_CHECK_WINDOWS.ps1) - 目标VM必须能正常响应Azure Run Command(需满足网络、代理等要求)
内容的提问来源于stack exchange,提问作者woodyboow
相关产品推荐
相关产品推荐

