为何PowerShell命令直接运行正常,通过powershell.exe -Command执行失败?
问题:PowerShell命令直接运行正常,但通过
powershell.exe -Command执行失败 以下命令直接在PowerShell中运行完全正常:
Get-NetAdapter | Where-Object {$_.InterfaceDescription -match 'Ethernet' -or $_.InterfaceDescription -match 'Wireless'}
但尝试通过任务计划程序(或在cmd/PowerShell中调用powershell.exe -Command)执行该命令时,却执行失败,报错信息如下:
- 报错片段:
... etAdapter | Where-Object {.InterfaceDescription -match 'Ethernet'-or ... - 详细错误:
CategoryInfo : ObjectNotFound: (.InterfaceDescription:String) [Where-Object], CommandNotFoundException FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.WhereObjectCommand
将代码转为Base64字符串执行时,也出现相同错误。请问为何直接运行正常,通过上述方式执行却失败?
原因与解决办法
核心原因
- cmd环境的变量解析冲突:当在cmd中调用
powershell.exe -Command时,cmd会优先解析命令字符串中的$符号(cmd中$是变量引用标记),导致原命令中的$_(PowerShell的管道对象变量)被错误处理,最终传递给PowerShell的内容里$_变成了.,所以PowerShell会把.InterfaceDescription当成一个不存在的命令,抛出CommandNotFoundException。 - Base64编码格式错误:转Base64后仍报错,大概率是编码格式不对——PowerShell要求
-EncodedCommand参数接收的Base64字符串必须是**UTF-16LE(Unicode)**编码的字符串转码而来,如果用了UTF-8编码生成Base64,会导致解析错误,同样出现变量丢失的问题。
解决办法
办法1:在cmd中转义$符号
给命令中的$加上cmd的转义符^,让cmd不解析该符号,直接传递给PowerShell:
powershell.exe -Command "Get-NetAdapter | Where-Object {^$_.InterfaceDescription -match 'Ethernet' -or ^$_.InterfaceDescription -match 'Wireless'}"
办法2:用单引号包裹PowerShell命令
cmd不会解析单引号内部的内容,因此可以用单引号把整个PowerShell命令包起来,同时把命令内部的单引号换成双引号避免冲突:
powershell.exe -Command 'Get-NetAdapter | Where-Object {$_.InterfaceDescription -match "Ethernet" -or $_.InterfaceDescription -match "Wireless"}'
办法3:生成正确的Base64编码
对于复杂命令,推荐用-EncodedCommand参数,需先在PowerShell中生成符合要求的Base64字符串:
$command = "Get-NetAdapter | Where-Object `$_.InterfaceDescription -match 'Ethernet' -or `$_.InterfaceDescription -match 'Wireless'" $bytes = [System.Text.Encoding]::Unicode.GetBytes($command) [Convert]::ToBase64String($bytes)
复制生成的Base64字符串后,用以下命令执行:
powershell.exe -EncodedCommand <生成的Base64字符串>
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

