如何使用 Invoke-Command 传递命名参数? [英] How do I pass named parameters with Invoke-Command?

查看:124
本文介绍了如何使用 Invoke-Command 传递命名参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以通过 Invoke-Command 远程运行的脚本

I have a script that I can run remotely via Invoke-Command

Invoke-Command -ComputerName (Get-Content C:\Scripts\Servers.txt) `
               -FilePath C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1

只要我使用默认参数,它就可以正常工作.但是,该脚本有 2 个名为 [switch] 的参数(-Debug 和 -Clear)

As long as I use default parameters, it works fine. However, the script has 2 named [switch] parameters (-Debug and -Clear)

如何通过 Invoke-Command 传递切换的参数?我试过 -ArgumentList 但我遇到了错误,所以我一定是语法错误或什么的.非常感谢任何帮助.

How can I pass the switched parameters via the Invoke-Command? I've tried the -ArgumentList but I'm getting errors so I must have the syntax wrong or something. Any help is greatly appreciated.

推荐答案

-ArgumentList 基于与 scriptblock 命令一起使用,例如:

-ArgumentList is based on use with scriptblock commands, like:

Invoke-Command -Cn (gc Servers.txt) {param($Debug=$False, $Clear=$False) C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 } -ArgumentList $False,$True

当你用 -File 调用它时,它仍然像一个愚蠢的 splatted 数组一样传递参数.我已经提交了一个 功能请求 将其添加到命令中(请投票赞成).

When you call it with a -File it still passes the parameters like a dumb splatted array. I've submitted a feature request to have that added to the command (please vote that up).

所以,你有两个选择:

如果你有一个看起来像这样的脚本,在远程机器可访问的网络位置(注意 -Debug 是隐含的,因为当我使用 Parameter 属性时,脚本隐式获取 CmdletBinding,因此获取所有公共参数):

If you have a script that looked like this, in a network location accessible from the remote machine (note that -Debug is implied because when I use the Parameter attribute, the script gets CmdletBinding implicitly, and thus, all of the common parameters):

param(
   [Parameter(Position=0)]
   $one
,
   [Parameter(Position=1)]
   $two
,
   [Parameter()]
   [Switch]$Clear
)

"The test is for '$one' and '$two' ... and we $(if($DebugPreference -ne 'SilentlyContinue'){"will"}else{"won't"}) run in debug mode, and we $(if($Clear){"will"}else{"won't"}) clear the logs after."

不必纠结于 $Clear 的含义……如果您想调用它,您可以使用以下 Invoke-Command 语法之一:

Without getting hung up on the meaning of $Clear ... if you wanted to invoke that you could use either of the following Invoke-Command syntaxes:

icm -cn (gc Servers.txt) { 
    param($one,$two,$Debug=$False,$Clear=$False)
    C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 @PSBoundParameters
} -ArgumentList "uno", "dos", $false, $true

在那一个中​​,我在 scriptblock 中复制我关心的所有参数,以便我可以传递值.如果我可以对它们进行硬编码(这就是我实际所做的),则无需这样做并使用 PSBoundParameters,我只需传递我需要的参数即可.在下面的第二个示例中,我将传递 $Clear 一个,只是为了演示如何传递 switch 参数:

In that one, I'm duplicating ALL the parameters I care about in the scriptblock so I can pass values. If I can hard-code them (which is what I actually did), there's no need to do that and use PSBoundParameters, I can just pass the ones I need to. In the second example below I'm going to pass the $Clear one, just to demonstrate how to pass switch parameters:

icm -cn $Env:ComputerName { 
    param([bool]$Clear)
    C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 "uno" "dos" -Debug -Clear:$Clear
} -ArgumentList $(Test-Path $Profile)

另一种选择

如果脚本在您的本地机器上,并且您不想将参数更改为位置,或者您想要指定的参数是公共参数(因此您无法控制它们),您将希望获得该脚本的内容并将其嵌入到您的 scriptblock 中:

$script = [scriptblock]::create( @"
param(`$one,`$two,`$Debug=`$False,`$Clear=`$False)
&{ $(Get-Content C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 -delimiter ([char]0)) } @PSBoundParameters
"@ )

Invoke-Command -Script $script -Args "uno", "dos", $false, $true

后记:

如果你真的需要为脚本名称传入一个变量,你会做什么将取决于变量是在本地还是远程定义的.一般来说,如果你有一个带有脚本名称的变量 $Script 或环境变量 $Env:Script,你可以用调用操作符 (&): &$Script&$Env:Script

PostScript:

If you really need to pass in a variable for the script name, what you'd do will depend on whether the variable is defined locally or remotely. In general, if you have a variable $Script or an environment variable $Env:Script with the name of a script, you can execute it with the call operator (&): &$Script or &$Env:Script

如果它是一个已经在远程计算机上定义的环境变量,那就是它的全部内容.如果它是一个本地变量,那么你必须把它传递给远程脚本块:

If it's an environment variable that's already defined on the remote computer, that's all there is to it. If it's a local variable, then you'll have to pass it to the remote script block:

Invoke-Command -cn $Env:ComputerName { 
    param([String]$Script, [bool]$Clear)
    & $ScriptPath "uno" "dos" -Debug -Clear:$Clear
} -ArgumentList $ScriptPath, (Test-Path $Profile)

这篇关于如何使用 Invoke-Command 传递命名参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆