You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求编写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失败而中断。

使用前注意事项

  1. 确保已安装并登录Azure CLI:az login
  2. 确保当前账号拥有目标订阅下VM的Microsoft.Compute/virtualMachines/runCommand/action权限
  3. 将VARIASUIT_CHECK_WINDOWS.ps1脚本放在当前脚本的同一目录下,或者指定完整路径(如@C:\Scripts\VARIASUIT_CHECK_WINDOWS.ps1)
  4. 目标VM必须能正常响应Azure Run Command(需满足网络、代理等要求)

内容的提问来源于stack exchange,提问作者woodyboow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:07:22