如何将命令行参数传递给PowerShell ps1文件

Dan*_*ith 82 powershell command-line arguments

多年来,我一直使用cmd/DOS/Windowsshell并将命令行参数传递给批处理文件.例如,我有一个文件,zuzu.bat并在其中,我访问%1,%2等等.现在,我想,当我叫做同样的PowerShell脚本when I am in a Cmd.exe shell.我有一个脚本,xuxu.ps1(我已经将PS1添加到我的PATHEXT变量和与PowerShell关联的PS1文件).但无论我做什么,我似乎都无法从$args变量中得到任何东西.它的长度始终为0.

如果我在PowerShellshell中,而不是cmd.exe,它可以工作(当然).但我还不够舒服,无法全时在PowerShell环境中生活.我不想打字powershell.exe -command xuxu.ps1 p1 p2 p3 p4.我想打字xuxu p1 p2 p3 p4.

这是可能的,如果是的话,怎么样?

我无法工作的样本很简单,foo.ps1:

Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
    Write-Host "Arg: $arg";
}
Run Code Online (Sandbox Code Playgroud)

结果总是如下:

C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
Run Code Online (Sandbox Code Playgroud)

Arj*_*Arj 31

这篇文章有帮助.特别是这一节:

-文件

在本地作用域("dot-sourced")中运行指定的脚本,以便脚本创建的函数和变量在当前会话中可用.输入脚本文件路径和任何参数.文件必须是命令中的最后一个参数,因为在File参数名称后键入的所有字符都被解释为脚本文件路径,后跟脚本参数.

powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3
Run Code Online (Sandbox Code Playgroud)

表示运行文件myfile.ps1和arg1 arg2&arg3是PowerShell脚本的参数.

  • 这仍然对操作员想要的东西没有帮助(“我想输入`xuxu p1 p2 p3 p4`”)。 (3认同)

EBG*_*een 18

好的,首先这是打破PowerShell中的基本安全功能.有了这个理解,这是你如何做到这一点:

  1. 打开Windows资源管理器窗口
  2. 菜单工具 - > 文件夹选项 - >选项卡文件类型
  3. 找到PS1文件类型,然后单击高级按钮
  4. 单击"新建"按钮
  5. 行动投入:开放
  6. 对于应用程序放置:"C:\ WINNT\system32\WindowsPowerShell\v1.0\powershell.exe"" - file""%1"%*

-NoProfile根据您的个人资料的不同,您可能还想在其中添加一个参数.

  • 要添加到EBGreen的评论中,PowerShell试图避免的基本安全问题是人们双击附加到电子邮件的PS1文件并运行脚本.这就是PS1文件默认只与编辑器关联的原因.微软真的不想要一个版本的ILoveYou病毒的PowerShell版本,例如"LOVE-LETTER-FOR-YOU.TXT.ps1" (6认同)
  • 我认为关键是在第6步中将参数传递给powershell.exe.Daniel说他已经将PS1文件与PowerShell相关联,但如果没有额外的%1%*规范,则不会传递参数.另请注意,-File参数在V1中不可用.这是V2的新功能. (4认同)

Ran*_*rck 18

在深入了解PowerShell文档后,我发现了一些有关此问题的有用信息.你不能使用$argsparam(...)在文件开头使用的那个; 相反,你需要使用$PSBoundParameters.我将您的代码复制/粘贴到PowerShell脚本中,它在PowerShell版本2中的效果正如您所期望的那样(我不确定您遇到此版本时的版本).

如果您正在使用$PSBoundParameters(并且只有param(...)在脚本开头使用时才有效),那么它不是数组,它是一个哈希表,因此您需要使用键/值对来引用它.

param($p1, $p2, $p3, $p4)
$Script:args=""
write-host "Num Args: " $PSBoundParameters.Keys.Count
foreach ($key in $PSBoundParameters.keys) {
    $Script:args+= "`$$key=" + $PSBoundParameters["$key"] + "  "
}
write-host $Script:args
Run Code Online (Sandbox Code Playgroud)

当被召唤时......

PS> ./foo.ps1 a b c d
Run Code Online (Sandbox Code Playgroud)

结果是......

Num Args:  4
$p1=a  $p2=b  $p3=c  $p4=d
Run Code Online (Sandbox Code Playgroud)

  • @EricHansen我不知道你的意思,我得到相同的结果: ` Powershell>powershell.exe .\ParamTest.ps1 val1 val2 val3 val4 Num Args: 4 $p1=val1 $p2=val2 $p3=val3 $p4=val4 ` (2认同)

V.B*_*V.B 10

在文件中声明你的参数,比如param([string] $ para1 ....... [string] $ param2).

现在调用PowerShell文件.\temp.ps1 para1 para2....para10,等等.


gui*_*ooo 6

也许你可以将PowerShell调用包装在这样的.bat文件中:

rem ps.bat
@echo off
powershell.exe -command "%*"
Run Code Online (Sandbox Code Playgroud)

如果您随后将此文件放在您的文件夹下PATH,则可以像这样调用PowerShell脚本:

ps foo 1 2 3
Run Code Online (Sandbox Code Playgroud)

尽管如此,引用可能会有点混乱:

ps write-host """hello from cmd!""" -foregroundcolor green
Run Code Online (Sandbox Code Playgroud)