解决PowerShell中Start-Process执行带变量命令的术语未识别错误
问题描述
我需要执行以下命令查找指定用户的远程桌面会话ID并输出:
$uid = Get-RDUserSession | Where-Object -filter {$_.UserName -eq 'pedro.vieira'} | select -ExpandProperty UnifiedSessionID; $uid
该命令在管理员权限PowerShell中可正常运行,非管理员权限下会提示需提升权限,符合预期。
为了以管理员身份执行该命令,我尝试用Start-Process -Wait -PassThru -Verb RunAs powershell作为前缀,命令如下:
Start-Process -Wait -PassThru -Verb RunAs powershell "$uid = Get-RDUserSession | Where-Object -filter {$_.UserName -eq 'pedro.vieira'} | select -ExpandProperty UnifiedSessionID; $uid; Start-Sleep -Seconds 5"
但执行后出现错误:
=: The term '=' is not recognized as the name of a cmdlet, function, script file, or operable program
我尝试转义$符号,又出现\字符未被识别的错误。但执行无变量的简单命令(如Start-Process -Wait -PassThru -Verb RunAs powershell "Get-RDUserSession")完全正常,请问哪里操作有误?
解决方法
出错原因
用双引号包裹命令字符串时,当前PowerShell会话会提前解析字符串里的$变量(比如$uid、$_),导致传递给管理员PowerShell的命令已经被篡改,出现语法错误。
可行方案
方案1:用单引号包裹命令字符串
单引号在PowerShell中不会解析内部变量,能完整传递命令到新会话,注意内部单引号要用两个单引号转义:
Start-Process -Wait -PassThru -Verb RunAs powershell '$uid = Get-RDUserSession | Where-Object -filter {$_.UserName -eq ''pedro.vieira''} | select -ExpandProperty UnifiedSessionID; $uid; Start-Sleep -Seconds 5'
方案2:使用Here-String定义命令
用Here-String可以原样保留命令内容,无需转义变量或引号,可读性更强:
$command = @' $uid = Get-RDUserSession | Where-Object -filter {$_.UserName -eq 'pedro.vieira'} | select -ExpandProperty UnifiedSessionID $uid Start-Sleep -Seconds 5 '@ Start-Process -Wait -PassThru -Verb RunAs powershell -ArgumentList "-Command", $command
方案3:转义$符号
如果坚持用双引号,需要用反引号()转义所有$`,让当前会话不解析这些变量:
Start-Process -Wait -PassThru -Verb RunAs powershell -ArgumentList "-Command", "`$uid = Get-RDUserSession | Where-Object -filter {`$_.UserName -eq 'pedro.vieira'} | select -ExpandProperty UnifiedSessionID; `$uid; Start-Sleep -Seconds 5"
内容的提问来源于stack exchange,提问作者TiagoRibeiro
相关产品推荐
相关产品推荐

