【问题标题】:Batch launching PowerShell with a multiline command parameter使用多行命令参数批量启动 PowerShell
【发布时间】:2012-02-20 18:02:47
【问题描述】:

我想将批处理文件中的几行代码作为 -command 参数传递给 powershell.exe。

例如这样的代码:

SET LONG_COMMAND=
if ($true)
{
Write-Host "Result is True"
}
else
{
Write-Host "Result is False"
}

START Powershell -noexit -command "%LONG_COMMAND%"

我想不创建 PowerShell 脚本文件,只创建一个批处理文件。
有可能吗?

谢谢。

【问题讨论】:

    标签: powershell command-line batch-file


    【解决方案1】:

    您可以添加“^”以继续分配给变量的字符串。这会将命令创建为单行,因此您需要使用 ';'语句之间:

    @ECHO off
    SET LONG_COMMAND= ^
    if ($true) ^
    { ^
    Write-Host "Result is True"; ^
    Write-Host "Multiple statements must be separated by a semicolon." ^
    } ^
    else ^
    { ^
    Write-Host "Result is False" ^
    }
    
    START Powershell -noexit -command %LONG_COMMAND%
    

    如果您需要执行的唯一代码是 PowerShell,您可以使用类似的代码:

    ;@Findstr -bv ;@F "%~f0" | powershell -command - & goto:eof
    
    if ($true){
        Write-Host "Result is True" -fore green
    }
    else{
        Write-Host "Result is False" -fore red
    }
    
    Start-Sleep 5
    

    将所有不以“;@F”开头的行通过管道传输到 PowerShell。

    编辑:我能够在单独的窗口中启动 PowerShell 并允许 cmd 退出:

    @@ECHO off
    @@setlocal EnableDelayedExpansion
    @@set LF=^
    
    
    @@SET command=#
    @@FOR /F "tokens=*" %%i in ('Findstr -bv @@ "%~f0"') DO SET command=!command!!LF!%%i
    @@START powershell -noexit -command !command! & goto:eof
    
    if ($true){
        Write-Host "Result is True" -fore green
    }
    else{
        Write-Host "Result is False" -fore red
    }
    

    请注意,设置 'LF' 变量后必须有 2 个空格,因为我们正在为变量分配换行符。

    【讨论】:

    • 我认为你的第二个例子正是我想要的。 ;@ 在批处理文件中的意义是什么?谢谢。
    • @ 告诉 cmd 在执行时不要回显该行。 ; 只是一个参数分隔符;也可以使用,=。它只是减少了文件中其他内容与被过滤掉的字符串匹配的机会。该行可以以@;=, 的任意组合开头。示例:;;@@,==@,;
    • 这很好用。只有一个小缺点。通过以这种方式启动 powershell,我运行了两个进程:powershell.exe 和 cmd.exe。此外,窗口中没有 powershell 提示。是否可以“启动”powershell.exe 并退出 cmd.exe?
    • 嗯,我认为在最新示例中,EnableDelayedExpansion 可能会干扰 powershell 代码中的感叹号。如果我将“结果为真”更改为“结果为真!”,则不显示感叹号。否则,它工作得很好。
    • 是的,我没想到会导致感叹号出现问题。 Jay Bazuzi 对在批处理文件中嵌入 PowerShell 有一个很好的回答。我会在他的脚本中将join(';'替换为join([char]10,您可以将其更改为START powershell并添加-noexit该脚本还处理参数:stackoverflow.com/a/2611487/291709
    【解决方案2】:

    使用

    start powershell -NoExit -EncodedCommand "aQBmACAAKAAkAHQAcgB1AGUAKQAKAHsACgBXAHIAaQB0AGUALQBIAG8AcwB0ACAAIgBSAGUAcwB1AGwAdAAgAGkAcwAgAFQAcgB1AGUAIgAKAH0ACgBlAGwAcwBlAAoAewAKAFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAiAFIAZQBzAHUAbAB0ACAAaQBzACAARgBhAGwAcwBlACIACgB9AAoA"
    

    引用powershell /?

    # To use the -EncodedCommand parameter:
    $command = 'dir "c:\program files" '
    $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
    $encodedCommand = [Convert]::ToBase64String($bytes)
    powershell.exe -encodedCommand $encodedCommand
    

    您可以使用通过-EncodedCommand 进行尴尬转义的命令,只需提供 Base64 编码的字符串即可。

    【讨论】:

    • 我想我说错了。我的意思是:“我想不创建 PowerShell 脚本文件,只创建一个批处理文件。”那么,如何在批处理文件中编码所有这些 powershell 代码?
    • 我认为你看错了。请参阅上面的第一行代码。其余代码只是从帮助中引用的,并向您展示如何创建这样一个编码的命令字符串。
    • 好的,但是如何在批处理文件中找到该编码字符串?谢谢。
    • 作为一次性设置,您可以从 PowerShell 命令行或 PS1 命令运行类似于 Joey 提供的第二段代码的内容。这会将多行脚本转换为单个编码字符串。一旦您生成了该字符串一次,从那时起您就可以简单地将编码版本用作单行。这完成了您正在寻找的内容,但不幸的是,当您查看 1-liner 时,它会掩盖意图。
    • 是的,命令改变了。我希望将此批处理文件用作模板,因此我只需要更改 LONG_COMMAND 变量的值即可。我想我可以编写一个实用程序来生成该编码字符串并将其粘贴到批处理文件中,但它会不太清楚。
    【解决方案3】:

    您可以使用-Command -,它会导致 ps 从标准输入读取它的命令。将您的命令放在一个文件中,然后调用

    powershell -Command - <myCommandFile
    

    【讨论】:

    • 这可能会起作用,但它仍然需要一个额外的文件。我希望批处理文件是独立的。谢谢。
    • 在这种情况下,您可以使用-File,这样更容易。
    • @Joey 从安全角度来看,我认为运行脚本(与 -File 一样)与运行命令不同,但我可能错了,我不是 PS 专家。
    • 嗯,好久没玩过执行策略了。也许
    【解决方案4】:

    Joey 的方式是万无一失的,但你也可以在你的情况下使用简单的多行命令

    这里需要空行(就像在 Rynant 的 LF 示例中一样)

    powershell -command if ($true)^
    
    {^
    
    Write-Host "Result is True"^
    
    }^
    
    else^
    
    {^
    
    Write-Host "Result is False"^
    
    }
    

    这里是Long commands split over multiple lines的解释

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-24
      • 2019-08-05
      • 1970-01-01
      • 2022-08-21
      • 2017-03-06
      相关资源
      最近更新 更多