了解使用参数在批处理中执行 PowerShell

了解使用参数在批处理中执行 PowerShell

我已经研究了一段时间,但我不明白这是如何工作的。我需要的是:

  1. 能够运行批处理文件
  2. 批处理文件应该有参数
  3. 参数应从批处理文件传递到同一文件中的 PowerShell 脚本

我为什么需要这个?因为我需要运行一个简单的批处理文件来做一些事情,但我需要只能通过 PowerShell 运行的高级功能。具体来说:我需要SaveFileDialog某个应用程序。

以下是我现在所拥有的,我剥离了复杂的部分SaveFileDialog,并留下了一个简单的批处理 + PowerShell 部分:

<# : 

@echo off
setlocal

powershell -noprofile "iex (${%~f0} | out-string)"
goto :EOF

#>

Write-Host "Hello, I'm PowerShell!"

如果我将所有这些都放入批处理文件中,例如myfile.bat。它会运行并调用 PowerShell 并写入该消息。

我的问题/请求:如何运行myfile.bat param1 param2 param3,并将这些参数/参数传递给我的 PowerShell 脚本?我真的很感激一个仅通过 PowerShell 打印参数的最小示例write-host

答案1

我如何运行 myfile.bat param1 param2 param3,并将这些参数/参数传递给我的 PowerShell 脚本?


构建批处理脚本来接受参数

你显然需要扩大批处理参数随后SET arg#=%~#

我使示例批处理脚本显示参数设置变量,并将它们传递给 PS 脚本,该脚本稍后将与最终结果结合起来,以期在该答案的末尾帮助澄清更多内容。

批处理脚本示例

@ECHO ON

SET arg1=%~1
SET arg2=%~2
SET arg3=%~3
SET arg4=%~4

SET PSScript=C:\Users\User\Desktop\Test.ps1

SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%' '%arg1%' '%arg2%' '%arg3%' '%arg4%'"
EXIT /B

构建 PowerShell 脚本以接受参数

你显然需要扩大PowerShell 参数随后$arg#=$args[#]

PowerShell 脚本示例

$arg1=$args[0]
$arg2=$args[1]
$arg3=$args[2]
$arg4=$args[3]

Write-Host "$arg1 is a beauty!!"
Write-Host "$arg2 is cool!!"
Write-Host "$arg3 has body odor!!"
Write-Host "$arg4 is a beast!!"

把它们联系在一起

  • 将参数传递给批处理脚本:

    • c:\users\user\desktop\test.cmd "Selena" "Justin" "Donald" "Bernie"
  • 将参数传递给 PowerShell 脚本:

  • Powershell -ExecutionPolicy Bypass -Command "& 'C:\Users\User\Desktop\Test.ps1' 'Selena' 'Justin' 'Donald' 'Bernie'
    
  • 完整结果回响于:

  • c:\users\user\desktop\test.cmd "Selena" "Justin" "Donald" "Bernie"
    
    SET arg1=Selena
    
    SET arg2=Justin
    
    SET arg3=Donald
    
    SET arg4=Bernie
    
    SET PSScript=C:\Users\User\Desktop\Test.ps1
    
    SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
    
    CD /D "C:\Windows\System32\WindowsPowerShell\v1.0"
    
    Powershell -ExecutionPolicy Bypass -Command "& 'C:\Users\User\Desktop\Test.ps1' 'Selena' 'Justin' 'Donald' 'Bernie'"
    Selena is a beauty!!
    Justin is cool!!
    Donald has body odor!!
    Bernie is a beast!!
    

    在此处输入图片描述


更多资源

答案2

通过批处理脚本将多个参数传递给 PowerShell 脚本

您可能能够使用类似下面的方法,因为我能够使用该语法让批处理脚本将参数传递给 PS 脚本。

它确实必须在顶部构建一个动态 PS 脚本(例程:DynamicPSScriptBuild),如果它已经存在,它就会删除它,并且在完成所有执行后也会删除它。

我不得不使用 PS-file而不是-iex(PS1 文件需要存在的原因及其动态构建),但当我测试它将适用的参数逐一传递给脚本时,它可以按预期工作,每个参数都是一个 PS 脚本执行迭代。

我不确定是否需要将所有参数传递给 PS 脚本一个接一个地或者全部一次性通过或者您的 PS 脚本逻辑如何处理在同一执行期间传递给它的多个参数,但这也许会为您提供足够的细节以进行相应的调整。

以下脚本的一部分将FOR %%A IN ("Hello I'm PowerShell!", "Goodbye I'm Leaving", "Come with it and get some more"是您将每个字符串用作参数的部分,每次执行迭代时将其一个接一个地传递给 PS 脚本,其中每个字符串值都放在双引号中并用逗号分隔。


脚本示例

(你可能想转@ECHO OFF并取出pause命令,因为我用它们来帮助显示每次迭代的所有内容,以确认一切都按预期工作)

<# : 

@ECHO ON
SETLOCAL

:DynamicPSScriptBuild
SET PSScript=%~f0.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO param($a)        >>"%PSScript%" 
ECHO Write-Host "$a"  >>"%PSScript%" 

:SetPSScriptArguments
FOR %%A IN (    "Hello I'm PowerShell!", 
                "Goodbye I'm Leaving", 
                "Come with it and get some more"
) DO CALL :Powershell "%%~A"
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
GOTO :EOF

:PowerShell
PowerShell -NoProfile -ExecutionPolicy Bypass -file "%PSScript%" "%~1"
pause
GOTO :EOF

更多资源

答案3

将批处理变量从批处理文件中直接传递到 Powershell 行。为了测试这一点,我将 cmdletWrite-Host作为参数传递。

foo.bat

@echo off

set arg1=%1

powershell.exe %1 "this is from powershell"

pause

发起.bat一个论点,

.\foo.bat Write-Host

输出:

this is from powershell
Press any key to continue . . .

答案4

  1. 将批处理的参数保存到某些环境变量中(_args_如下例所示)
  2. 将批处理文件读入字符串:${%~f0} | out-string
  3. ScriptBlock从字符串创建一个
  4. 解包参数:@(iex('&{$args} ' + $env:_args_))
  5. Invoke带有参数数组的 ScriptBlock

如果您想传递引用的参数,则步骤 1 和 4 是必需的。(例如myfile.bat param1 "param2 with spaces" param3

<# :
@echo off
setlocal
set _args_=%*
powershell -noprofile "[ScriptBlock]::Create((${%~f0} | out-string)).Invoke(@(iex('&{$args} ' + $env:_args_)))"
goto :EOF
#>

Write-Host "Hello, I'm PowerShell!"
Write-Host "And these are arguments: "
Write-Host $args[0]
Write-Host $args[1]
Write-Host $args[2]

相关内容