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

如何用PowerShell 5.1远程启动Azure VM服务并解决权限问题

问题概述

需要远程启动Azure虚拟机(Azure VM)上的服务,操作必须以管理员身份运行PowerShell才能成功,但当前只能使用PowerShell 5.1版本——该版本的Set-Service命令不支持像7.x那样传入-Credential参数。手中的凭据拥有VM管理员权限,但不知道如何通过命令传递。

现有执行命令

通过以下命令触发远程操作($action取值为stop或start):

$runCommand = Invoke-AzVMRunCommand `
            -ResourceGroupName $rg `
            -VMName $vm `
            -CommandId 'RunPowerShellScript' `
            -ScriptPath $scriptPath `
            -Parameter @{action = $action}
关联脚本逻辑

对应的服务操作脚本:

$serviceNames = @("service1, service2")

foreach($serviceName in $serviceNames){
    $service = Get-Service -Name $serviceName
    if($service){
        if($action -ieq "start"){
             Set-Service -InputObject $service -Status "Running"
        }
    }
    else{
        Write-Output "Service $serviceName not found!"
    }
}
执行场景结果
  • 本地笔记本运行:执行挂起
  • Azure门户“运行命令”执行:执行挂起
  • VM本地直接运行:提示“Service '' cannot be configured due to the following error: Access is denied”
  • VM本地以管理员身份启动PowerShell运行:操作成功
解决方案

针对PowerShell 5.1的限制,提供两种可行方法:

方法一:使用CIM命令(推荐)

PowerShell 5.1的CIM系列cmdlet支持-Credential参数,可直接传递管理员凭据操作服务,适配远程执行场景:

param($action)

$serviceNames = @("service1", "service2")
# 从Azure Key Vault获取凭据(需提前配置密钥保管库及凭据)
$secret = Get-AzKeyVaultSecret -VaultName "你的密钥保管库名称" -Name "管理员凭据密钥名"
$cred = [System.Management.Automation.PSCredential]::new($secret.Content.UserName, $secret.Content.SecretValue)

foreach($serviceName in $serviceNames){
    $service = Get-CimInstance -ClassName Win32_Service -Filter "Name='$serviceName'"
    if($service){
        switch($action.ToLower()){
            "start" { $service | Invoke-CimMethod -MethodName StartService -Credential $cred }
            "stop" { $service | Invoke-CimMethod -MethodName StopService -Credential $cred }
        }
    }
    else{
        Write-Output "Service $serviceName not found!"
    }
}

说明:禁止明文存储凭据,优先用Azure Key Vault存储并获取,保障安全性。

方法二:启动管理员权限子进程

通过Start-Process启动带管理员权限的PowerShell子进程执行服务操作,适用于本地或需要UAC提权的场景:

param($action)

$serviceNames = @("service1", "service2")

foreach($serviceName in $serviceNames){
    $execScript = @"
        `$targetService = Get-Service -Name '$serviceName'
        if(`$targetService){
            if('$action' -ieq 'start'){
                Set-Service -InputObject `$targetService -Status Running
            } elseif('$action' -ieq 'stop'){
                Set-Service -InputObject `$targetService -Status Stopped
            }
        } else {
            Write-Output 'Service $serviceName not found!'
        }
"@
    # 以管理员身份启动子进程执行脚本
    Start-Process powershell.exe -ArgumentList "-Command", $execScript -Verb RunAs -Wait
}

说明:通过Azure Run Command执行时,若默认Local System权限不足,此方法需结合凭据传递,优先推荐方法一。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:26:06