同时使用FilePath将参数传递给Invoke-Command

时间:2015-08-24 15:00:08

标签: powershell powershell-v2.0

我有一个PowerShell(v2)脚本,我希望能够自己调用,但是在远程计算机上运行第二次调用。我需要能够将几个(~10个)命名参数传递给第二个调用。

过去,在处理作业时,我使用“splatting”来创建值的hashmap并将它们传递给作业。我尝试过与Invoke-Command类似的东西,但它没有按预期工作。我创建了一个简单的脚本来说明我的观点,将其保存为test.ps1。如果不是远程机器,打印变量,并调用远程调用,远程调用只打印它收到的内容。

param([string]$paramA, [string]$paramB, [bool]$remote = $false)

if(!$remote)
{
    Write-Host "LOCAL: paramA is $paramA"
    Write-Host "LOCAL: paramB is $paramB"
    Write-Host "LOCAL: remote is $remote"
}
else
{
    Write-Host "REMOTE: paramA is $paramA"
    Write-Host "REMOTE: paramB is $paramB"
    Write-Host "REMOTE: remote is $remote"  
}

if(!$remote)
{
    $sess = New-PSSession -computername MACHINENAME -credential CREDENTIALS
    #w/o hashmap
    $responseObject = Invoke-Command -session $sess -FilePath .\test.ps1 -ArgumentList($paramA,$paramB,$true) -AsJob 

    #with hashmap (this doesn't work)
    #$arguments = @{paramA = $paramA; paramB = $paramB; remote = $true}
    #$responseObject = Invoke-Command -session $sess -FilePath .\test.ps1 -ArgumentList $arguments -AsJob 

    while($responseObject.State -ne "Completed")
    {
    }

    $result = Receive-Job -Id $responseObject.Id
    Write-Host  $result

    Remove-PSSession -Session $sess
}

运行脚本我会看到这一点,但取消注释hashmap部分失败(永不返回)。

.\test.ps1  -paramA "First" -paramB "Second"
LOCAL: paramA is First
LOCAL: paramB is Second
LOCAL: remote is False
REMOTE: paramA is First
REMOTE: paramB is Second
REMOTE: remote is True

我尝试过使用scriptblocks等的变体,但我遗漏了一些东西。

2 个答案:

答案 0 :(得分:2)

不幸的是ArgumentList参数需要一个数组(对象),而不是哈希表(或者你说的哈希表)。因此哈希表被分配给第一个参数,而不是在所有参数上进行分割。如果这样做会很好。考虑在http://connect.microsoft.com上提交建议。

答案 1 :(得分:0)

我在脚本中添加了一个附加参数(位置0),如果该参数是HashTable,则使用哈希表中的参数更新局部变量。它现在有效。谢谢大家。

param($paramMap, [string]$paramA, [string]$paramB, [bool]$remote = $false)

...

Function configureVariables()
{
    if($paramMap.GetType().FullName -eq "System.Collections.HashTable")
    {
        $variables = get-variable -Scope "Script"

        foreach($param in $paramMap.GetEnumerator())
        {
            foreach($variable in $variables)
            {
                if($param.key -eq $variable.Name)
                {
                    $variable.Value = $param.value
                }
            }
        }
    }
}