![了解使用参数在批处理中执行 PowerShell](https://linux22.com/image/1501768/%E4%BA%86%E8%A7%A3%E4%BD%BF%E7%94%A8%E5%8F%82%E6%95%B0%E5%9C%A8%E6%89%B9%E5%A4%84%E7%90%86%E4%B8%AD%E6%89%A7%E8%A1%8C%20PowerShell.png)
我已经研究了一段时间,但我不明白这是如何工作的。我需要的是:
- 能够运行批处理文件
- 批处理文件应该有参数
- 参数应从批处理文件传递到同一文件中的 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!!
更多资源
-
批处理脚本中的 %* 指的是所有参数(例如 %1 %2 %3 %4 %5 ...%255),只有参数 %1 到 %9 可以用数字引用。
答案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
- 将批处理的参数保存到某些环境变量中(
_args_
如下例所示) - 将批处理文件读入字符串:
${%~f0} | out-string
ScriptBlock
从字符串创建一个- 解包参数:
@(iex('&{$args} ' + $env:_args_))
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]