如何使用Invoke-Command传递多个args

时间:2018-04-04 07:44:18

标签: powershell powershell-remoting invoke-command

我想在桌面上创建一些快捷方式,它可以在本地运行。但是当我在远程PC上尝试时,我只获得了第一个目标的一个快捷方式(path1),而脚本忽略了path2变量。

$Servers = Get-Content D:\1.txt

function add-sc {
    param ([string[]]$Targets) 
    BEGIN {}
    PROCESS {
        foreach ($a in $Targets) {
            $WshShell = New-Object -comObject WScript.Shell
            $b = $a.Substring($a.length - 5)
            $Shortcut = $WshShell.CreateShortcut("$Home\Desktop\$b.lnk")
            $Shortcut.TargetPath = $a
            $Shortcut.Save()
        }
    }
    END {}
}

foreach ($server in $Servers) {
    Invoke-Command -ComputerName $server -ScriptBlock ${function:add-sc} -Args "path1", "path2"
}

3 个答案:

答案 0 :(得分:1)

首先,您应该在scriptblock中定义您的函数。我不确定PowerShell v5 +,但在PowerShell v4和更早版本的命令

Invoke-Command -Computer bar -Scriptblock {function:foo}

会抛出错误,因为在scriptblock中无法识别该函数。

此外,您需要将参数实际传递给您正在调用的函数。基本上有两种方法可以解决这个问题:

  • 通过automatic variable $args

    将参数传递给函数
    Invoke-Command -Computer $server -ScriptBlock {
        function add-sc {
            Param([string[]]$Targets)
            Process {
                ...
            }
        }
        add-sc $args
    } -ArgumentList 'path1', 'path2'
    
  • 将参数作为单个数组传递给scriptblock,并将splat传递给函数:

    Invoke-Command -Computer $server -ScriptBlock {
        function add-sc {
            Param([string[]]$Targets)
            Process {
                ...
            }
        }
        add-sc @args
    } -ArgumentList @('path1', 'path2')
    

两种方法之间的区别在于前者采用所有参数并将它们作为单个数组传递给函数,而后者将所有参数传递给scriptblock并将它们作为单独的参数传递给函数。因此,在后一种情况下需要将参数作为单个数组传递给scriptblock。

在您的场景中,两种方法都是等效的,但如果您的函数需要第二个参数,那么您需要第二种方法并将参数作为-ArgumentList @('a','b'), 'c'传递给脚本块。

答案 1 :(得分:0)

您还可以使用-ArgumentList参数或简称-args向您的scriptblock发送多个参数。您只需要在scriptblock中处理它们。

请参阅这个简短的例子,了解它是如何完成的

Invoke-Command -ArgumentList "Application",10 -ScriptBlock {
    param([string]$log,[int]$lines)
    Get-EventLog $log -Newest $lines
}

这里-ArgumentList包含两个参数

  • String" Application"和
  • 整数10

它们作为参数发送到scriptblock,因此在其开头定义。

您现在可以像普通参数一样在scriptblock中访问它们:

  • $log
  • $lines

答案 2 :(得分:0)

您的语法和代码对我来说很好,您确定远程计算机上存在_links的目标吗?如果目标无效,则无法创建快捷方式。