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

Azure PowerShell Runbook无法访问VM本地C盘脚本文件求助

问题根源分析

你遇到的问题核心在于Azure Runbook的执行环境和你本地PowerShell环境的本质差异:
当你在本地运行Invoke-AzVMRunCommand时,-ScriptPath指向的是你本地电脑上的脚本文件,Azure会自动把这个脚本上传到目标VM的临时目录执行;但在Azure Runbook中,Runbook是在Azure托管的独立沙箱环境里运行的,这个沙箱完全访问不到你虚拟机C盘里的C:\stopservice.ps1,所以才会出现找不到文件的错误。

解决方案

下面提供几种可行的解决办法,按推荐程度排序:

方案1:直接嵌入脚本内容(最简便)

把stopservice.ps1的内容直接作为字符串传入-ScriptString参数,不需要依赖任何外部文件,Runbook可以直接把脚本内容发送到VM执行:

IF ($VmAction -eq "Shutdown") { 
    try { 
        # 用Here-String嵌入脚本内容,转义内部$避免提前解析
        $scriptContent = @"
try { 
    Stop-Service -Name SSASTELEMETRY 
} catch { 
    throw "Error: `$(`$_.Exception.Message)" 
}
"@
        Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VmName -CommandId 'RunPowerShellScript' -ScriptString $scriptContent -ErrorVariable result 
        Stop-AzVM -Name $VmName -ResourceGroupName $ResourceGroupName -Force 
    } catch { 
        throw "Error: $($_.Exception.Message)" 
    }
}

方案2:让VM执行本地已有的脚本

如果你坚持要使用VM里已经存在的C:\stopservice.ps1,可以通过-ScriptString参数让VM直接运行本地脚本——本质是在VM内部执行一条调用本地脚本的命令:

IF ($VmAction -eq "Shutdown") { 
    try { 
        # 让VM执行自身C盘的脚本文件
        Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VmName -CommandId 'RunPowerShellScript' -ScriptString "C:\stopservice.ps1" -ErrorVariable result 
        Stop-AzVM -Name $VmName -ResourceGroupName $ResourceGroupName -Force 
    } catch { 
        throw "Error: $($_.Exception.Message)" 
    }
}

⚠️ 注意:这个方案的前提是VM里确实存在C:\stopservice.ps1,并且RunCommand使用的系统账户有执行该脚本的权限。

方案3:从存储账户加载脚本(适合复杂/需版本管理的脚本)

如果你的脚本很长或者需要版本控制,可以把脚本上传到Azure存储账户的Blob容器,再通过两种方式调用:

方式A:Runbook下载脚本到沙箱再传入VM

IF ($VmAction -eq "Shutdown") { 
    try { 
        # 1. 从存储账户下载脚本到Runbook沙箱临时目录
        $storageAccountName = "你的存储账户名"
        $containerName = "你的容器名"
        $scriptName = "stopservice.ps1"
        $localPath = Join-Path $env:TEMP $scriptName

        $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -UseConnectedAccount
        Get-AzStorageBlobContent -Container $containerName -Blob $scriptName -Destination $localPath -Context $storageContext -Force

        # 2. 调用下载好的脚本
        Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VmName -CommandId 'RunPowerShellScript' -ScriptPath $localPath -ErrorVariable result 
        Stop-AzVM -Name $VmName -ResourceGroupName $ResourceGroupName -Force 
    } catch { 
        throw "Error: $($_.Exception.Message)" 
    }
}

方式B:让VM直接从存储下载并执行脚本

IF ($VmAction -eq "Shutdown") { 
    try { 
        # 生成存储Blob的临时SAS链接(确保有读取权限)
        $storageAccountName = "你的存储账户名"
        $containerName = "你的容器名"
        $scriptName = "stopservice.ps1"
        
        $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -UseConnectedAccount
        $sasToken = New-AzStorageBlobSASToken -Container $containerName -Blob $scriptName -Permission r -ExpiryTime (Get-Date).AddHours(1) -Context $storageContext
        $scriptUrl = "https://$storageAccountName.blob.core.windows.net/$containerName/$scriptName$sasToken"

        # 让VM下载脚本并执行
        $scriptContent = @"
Invoke-WebRequest -Uri '$scriptUrl' -OutFile 'C:\temp\stopservice.ps1'
& 'C:\temp\stopservice.ps1'
"@
        Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VmName -CommandId 'RunPowerShellScript' -ScriptString $scriptContent -ErrorVariable result 
        Stop-AzVM -Name $VmName -ResourceGroupName $ResourceGroupName -Force 
    } catch { 
        throw "Error: $($_.Exception.Message)" 
    }
}
额外排查提示
  • 可以在Invoke-AzVMRunCommand后添加-ShowOutput参数,查看VM返回的执行日志,快速定位脚本执行中的问题。
  • 确保Runbook使用的服务主体/托管身份有足够权限:比如调用Invoke-AzVMRunCommand需要VM的Microsoft.Compute/virtualMachines/runCommand/action权限,操作存储账户需要对应的存储数据读取权限。

内容的提问来源于stack exchange,提问作者E.C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:13:13