【问题标题】:Running Powershell from CMD Causing Command Line to Not Parse Correctly从 CMD 运行 Powershell 导致命令行无法正确解析
【发布时间】:2019-10-25 07:09:55
【问题描述】:

我正在尝试通过 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'"

从错误中可以看出,它似乎并没有尝试运行整个命令,因为它似乎是在尝试运行我的日志命令:

!https://imgur.com/y62FzB2

如果我运行一些简单的东西,它可以毫无问题地工作。如下:

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

【问题讨论】:

  • 这是一个有趣的问题,但请务必发布您正在执行的实际命令,以及您收到的错误消息,而不是(仅)屏幕截图。

标签: powershell cmd


【解决方案1】:

至于你尝试了什么

  • 当从cmd.exe 调用时,PowerShell code 传递给 Windows PowerShell 的 CLI,powershell.exepwsh.exe 用于 PowerShell Core必须是 单行

    • 您的屏幕截图表明您确实使用了一行,但 您缺少; 字符。在您的陈述之间;每当您想在一行中放置多个语句时,都需要这些语句分隔符
  • 您的下一个问题与将代码作为 individual 参数传递给 -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 编码表示。

不幸的是,这样的表示在批处理文件中并不容易。

【讨论】:

    【解决方案2】:

    我一直无法通过 cmd 调用多行 PowerShell 脚本。

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

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

    否则,您可以将每一行 ECHO 输出到一个 .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"
    

    【讨论】:

    • 也感谢您的解释和示例。很有用!
    猜你喜欢
    • 1970-01-01
    • 2018-03-14
    • 2021-09-13
    • 2019-04-17
    • 2014-09-16
    • 2020-02-12
    • 2018-04-11
    • 2016-07-13
    • 1970-01-01
    相关资源
    最近更新 更多