简体   繁体   English

如何使用 powershell 运行空间将参数正确传递给脚本块?

[英]How do I properly pass arguments to a scriptblock using powershell runspaces?

While using runspaces I would like to pass predictable arguments to my scriptblock from outside.在使用运行空间时,我想从外部将可预测的参数传递给我的脚本块。 In order to do this without utilizing $args (to avoid making the code less readable), I am storing my argument in a variable called $var and adding the variable to the InitialSessionState of the RunspacePool.为了在不使用$args 的情况下执行此操作(以避免降低代码可读性),我将我的参数存储在名为$var的变量中,并将该变量添加到 RunspacePool 的 InitialSessionState。 To do this I am using the Add method of System.Management.Automation.Runspaces.InitialSessionState.Create().Variables为此,我使用System.Management.Automation.Runspaces.InitialSessionState.Create().VariablesAdd方法

This works for my purposes, but I also noticed the PowerShell.AddParameter method of [PowerShell]::Create() which would add my parameter to each powershell process as it is created.这适用于我的目的,但我也注意到了[PowerShell]::Create()PowerShell.AddParameter方法,它会在[PowerShell]::Create()将我的参数添加到每个 powershell 进程中。

And finally there is the PowerShell.AddArgument which I could use like AddParameter , and use a param() block.最后是PowerShell.AddArgument ,我可以像AddParameter一样使用它,并使用param()块。 this would work, however, each argument will be passed in order, and ends up working as well as $args .这会起作用,但是,每个参数都将按顺序传递,并最终与$args 一样工作

So my question is what is the recommended way of passing arguments\\parameters\\variables into a scriptblock for the purposes I have defined?所以我的问题是,为了我定义的目的,推荐的将参数\\参数\\变量传递到脚本块的方法是什么? Is there a performance advantage of one over the other?一个比另一个有性能优势吗? Can you expand on what purpose you may use one over the other?你能扩展一下你可以使用一个的目的吗?

You can use cmdlet binding inside of the script block definition. 您可以在脚本块定义中使用cmdlet绑定。

$ScriptBlock = {
    Param (
        [int]$NumberofHours,
        [string]$ClientName
    )
    $LogPath = 'd:\Program Files\Exchange\Logging\RPC Client Access\*.LOG'
    $today = (Get-Date).AddHours($NumberofHours)
}

Then define call these parameters when you execute the script block. 然后在执行脚本块时定义调用这些参数。

Invoke-Command -ComputerName $servers -ScriptBlock $ScriptBlock -ArgumentList -1,$cn -ErrorAction SilentlyContinue

Here's my $.02.这是我的 $.02。 I know this thread is old but I came across it unanswered while searching for something else.我知道这个线程很旧,但我在寻找其他东西时遇到了它而没有得到答复。

This example uses a runspace pool to demonstrate how to pass parameters to the script block while using a runspace.此示例使用运行空间池来演示如何在使用运行空间时将参数传递给脚本块。 The function this comes from passes a datatable to a script block for processing.它来自的函数将数据表传递给脚本块进行处理。 Some variable names were changed to help with out-of-context readability.更改了一些变量名称以帮助实现上下文外的可读性。

$maxThreads = 5
$jobs = New-Object System.Collections.ArrayList

$rsp = [runspacefactory]::CreateRunspacePool(1,$maxThreads)
$rsp.open()

$params = New-Object 'System.Collections.Generic.Dictionary[string, string]'
$params.Add('Data', $myDataTable)
$params.Add('TableName', $myTableName)

$PS = [powershell]::Create()
$PS.Runspacepool = $rsp
$PS.AddScript($myScriptBlockCode)AddParameters($parameters)

Another option would be to forgo the iDictionary step and simply call .AddParameter repeatedly.另一种选择是放弃 iDictionary 步骤并简单地重复调用 .AddParameter。

$PS.AddScript($myScriptBlockCode).AddParame'ter(Data',$myDataTable).AddParameter('tableName',$myTableName)

A third way is to pass the parameters as arguments in the order they are defined in your script block第三种方法是按照它们在脚本块中定义的顺序将参数作为参数传递

$PS.AddScrip(t$myScriptBlockCode).AddArgument($myDataTable).AddArgument($myTableName)

I hope this helps someone out.我希望这可以帮助某人。 I welcome comments as to ways to do this better.我欢迎关于如何更好地做到这一点的评论。 As long as the comment doesn't suggest turning it into some amateurish one-liner that no one can read....只要评论不建议把它变成一些没人能看懂的业余单行......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM