从CMD运行Powershell导致命令行无法正确解析

时间:2019-06-10 21:44:59

标签: powershell cmd

我正在尝试通过CMD shell运行以下PowerShell代码:

$logfile = "x:\test.log"
try {
get-service
Add-Content - Path $logfile -Value "It Worked"
} catch {
Add-Content -Path $logfile -Value $_.Exception.Message
}

我从CMD脚本中按如下方式调用该脚本:

Powershell.exe -executionpolicy bypass -command "I paste the code above 
here"

我也尝试过如下操作:

Powershell.exe -executionpolicy bypass -command "& 'Command From Above'"

从错误中您可以看到,它似乎并没有试图运行整个命令,因为它似乎正在试图运行我的log命令:

https://imgur.com/y62FzB2

如果我运行简单的程序,它将正常工作。如下:

Powershell.exe -executionpolicy bypass -command "get-service"

2 个答案:

答案 0 :(得分:0)

我一直很难通过cmd调用多行PowerShell脚本。

我已经看到人们将其脚本转换为base64并从PowerShell中运行该字符串,但我不记得如何。

最简单的方法是将脚本另存为.PS1并运行PowerShell -NoProfile -ExecutionPolicy Bypass -file "C:\ps.ps1"

否则,您可以将每一行回显到.ps1文件,然后运行它。可以用作.bat文件。

@echo off
set WD=%~dp0
ECHO $logfile = "x:\test.log" >> "%WD%Script.ps1"
ECHO try { >> "%WD%Script.ps1"
ECHO     get-service; >> "%WD%Script.ps1"
ECHO     Add-Content - Path $logfile -Value "It Worked" >> "%WD%Script.ps1"
ECHO } catch { >> "%WD%Script.ps1"
ECHO     Add-Content -Path $logfile -Value $_.Exception.Message >> "%WD%Script.ps1"
ECHO } >> "%WD%Script.ps1"
powershell.exe -ExecutionPolicy Bypass -File "%WD%Script.ps1"
del "%WD%Script.ps1"

答案 1 :(得分:0)

关于您尝试过的事情

  • cmd.exe调用PowerShell 代码时,您将传递到Windows PowerShell的CLI powershell.exepwsh.exe用于PowerShell Core 必须为单行

    • 您的屏幕快照表明您确实使用了一行,但是您缺少了;个字符。在您的陈述之间;每当您要将多条语句放在一行上时,都需要这些语句分隔符
  • 您的下一个问题与将代码作为单个参数传递给-command并由PowerShell在执行之前组合在一起(而不是尝试传递单个参数)带有外部双引号)。

    • 在单独传递参数 时,PowerShell解析时会剥离所有封闭的"..." ,以便"x:\test.log"变成x:\test.log-没有引号-导致您看到错误。

解决方案

通过:

  • 使用;正确分隔语句
  • 转义"字符。在您的命令中以\"(原文如此)

您可以使命令生效:

powershell -c $logfile = \"x:\test.log\"; try { get-service; Add-Content -Path $logfile -Value \"It Worked\" } catch { Add-Content -Path $logfile -Value $_.Exception.Message }

但是,通常请注意,如果您的代码恰好包含cmd.exe中保留的字符(也),尤其是& | < > % ^-您将必须单独^进行转义。

要在命令行上正确报价是具有挑战性的,并且最终是唯一可靠的解决方案-不能通过创建(临时)脚本文件来避免此问题- 使用PowerShell的
-EncodedCommand CLI parameter
,该代码采用UTF-16LE字符编码对PowerShell代码进行Base64编码表示。

不幸的是,在批处理文件中很难获得这样的表示。