从bat文件传递参数给PowerShell

6

我将竭尽全力将批处理文件中的参数传递给PowerShell脚本,该脚本检查Windows服务是否正在运行。

这是我的完全可操作的命令:

.\nsrservices.ps1 -cmd running nsrexecd,stisvc

但问题在于该命令的行为:

  • 在PowerShell窗口中,服务名称被视为两个(或更多),因此先检查'nsrexecd',然后检查'stisvc'
  • 在批处理文件中,服务名称作为唯一值传递给PowerShell,因此检查'nsrexecd,stisvc'

以下是我的批处理文件:

powershell.exe -File .\nsrservices.ps1 -cmd running nsrexecd,stisvc
ECHO.%ERRORLEVEL%
exit /B %ERRORLEVEL%

在我的PS文件中,参数是这样定义的:

param([string]$cmd=$(throw "Type d'action manquante !"),[string[]]$srv)

在一个日志文件中,我得到了这两个结果(抱歉输出是法语)。
从PowerShell窗口:
24/12/2015 09:02:50-Paramètres appelés : cmd=running srv=stisvc nsrexecd
24/12/2015 09:02:50-Début test de l'état running du service : stisvc
24/12/2015 09:02:50-    Début évaluation de l'état du service : stisvc
24/12/2015 09:02:50-    Fin évaluation de l'état du service : stisvc
24/12/2015 09:02:50-Le service tourne
24/12/2015 09:02:50-Fin test de l'état running du service : stisvc
24/12/2015 09:02:50-Début test de l'état running du service : nsrexecd
24/12/2015 09:02:50-    Début évaluation de l'état du service : nsrexecd
24/12/2015 09:02:50-    Fin évaluation de l'état du service : nsrexecd
24/12/2015 09:02:50-Le service tourne
24/12/2015 09:02:50-Fin test de l'état running du service : nsrexecd

这意味着服务是按顺序进行测试的。

从.bat文件中:

24/12/2015 09:04:24-Paramètres appelés : cmd=running srv=nsrexecd,stisvc
24/12/2015 09:04:24-Début test de l'état running du service : nsrexecd,stisvc
24/12/2015 09:04:24-    Début évaluation de l'état du service : nsrexecd,stisvc
24/12/2015 09:04:24-        Le service nsrexecd,stisvc n'existe pas !
24/12/2015 09:04:24-    Fin évaluation de l'état du service : nsrexecd,stisvc
24/12/2015 09:04:24-Fin test de l'état running du service : nsrexecd,stisvc

这意味着名为“nsrexecd,stisvc”的服务不存在。
当使用.bat文件时,我的两个名称之间的逗号似乎会引起混淆。
所以我正尽力寻找一种解决方法来对抗这个可恶的.bat文件。
我尝试过引号、单引号、-File、-Command等,但都没有成功。
如果您有任何线索或解决方案,将不胜感激,因为我在这个论坛上的研究并没有给我带来可用的东西。
当然,在那之后,我想调用带有参数的.bat文件。

1
你可以尝试在批处理调用中不使用逗号,并将参数$srv更改为ValueFromRemainingArguments=$true。你可以在这里查看更多内容https://technet.microsoft.com/en-us/library/hh847743.aspx。或者只需将其作为单个字符串引入,并使用`-split ","`。 - Matt
为什么要从批处理文件中调用PowerShell脚本?直接从PowerShell中运行即可。 - Bill_Stewart
@Bill_Stewart:我的问题是关于在.bat文件中包含PowerShell,因为我必须这样做。该脚本是从正在运行的程序启动的,该程序不接受除.bat和.cmd文件之外的其他内容... - Denis.A
.cmdе’Њ.bat文件дёҚиѓҢ独立执иҰЊпәЊж‚Ёеү…йҰ»дҢүз”Ёcmd.exeжқӨиүђиҰЊе®ѓд»¬гЂ‚ - Bill_Stewart
@Bill_Stewart:抱歉,我想说的是我的程序只能启动cmd.exe。 - Denis.A
3个回答

2
在您的情况下,我会使用以下内容:
[parameter(Mandatory=$true,
           ValueFromRemainingArguments=$true)]
[String[]]
$services

你的批量调用将如下所示:
powershell.exe -File .\nsrservices.ps1 -cmd running nsrexecd stisvc

欲了解更多详情,请参考有关高级参数的函数


很棒的解决方案;据我所知,这是唯一一种可以直接从 PowerShell 外部传递值数组的方法。值得注意的一点是:使用此方法时,实际上不能在调用中使用参数名称(例如 -services)。 - mklement0

-1
通常情况下,我会从BAT文件中调用PowerShell脚本。
PowerShell .\script.ps1 -arg 1234 -arg2 5678

或者

PowerShell C:\path\to\script.ps1 -arg 1234 -arg2 5678

你的PowerShell脚本文件应该有类似于以下内容

param([string]$arg, [string]$arg2)

在脚本的开头和顶部。
在我的 param([string]$arg, [string]$arg2) 中,我分别将 switch 的名称定义为 arg 和 arg2。因此,BAT 文件将把 -arg 后面的任何内容赋给 $arg,把 -arg2 后面的任何内容赋给 $arg2。
我们可以根据您的脚本将其更改为更方便的内容。例如,在 PowerShell 脚本中,我们可以将其更改为:
param([string]$computer, [string]$filename)

在我们的BAT文件中,我们可以像上面那样调用PowerShell,但是我们将使用-computer和-filename而不是-arg和-arg2。

请记住它的顺序特定,所以您可以使用参数调用脚本:

PowerShell .\script.ps1 -computer MyComputer -filename MyFileName

或者

PowerShell .\script.ps1 -filename MyFileName -computer MyComputer

-filename将始终转到$filename

-computer将始终转到$computer。

希望这可以帮助您。


OP已经知道如何从批处理文件中调用PS脚本_一般地_,正如问题所示。他的问题是特别针对一个_数组_参数,而你的答案并没有解决这个问题。 此外,在PowerShell中,参数名称_不_区分大小写。 - mklement0

-1

最后,我改变了我的方式。 由于我的服务名称中有空格(而且我必须在.bat文件中包含我的.ps1),我决定将参数控制放在主要部分,并只留下

param([string]$cmd,[string[]]$srv)

没有控制的行。

感谢大家。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接