如何使用 Invoke-Command 传递多个参数
How can I pass multi args with Invoke-Command
我想在我的桌面上创建一些快捷方式,它在本地工作。但是当我在远程 PC 上尝试时,我只有一个第一个目标的快捷方式 (path1
),并且脚本忽略了 path2
变量。
$Servers = Get-Content D:.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"
}
您还可以使用 -ArgumentList
参数,或简称 -args
,将多个参数发送到您的脚本块。您只需要在脚本块内处理它们。
查看这个简短示例,了解它是如何完成的
Invoke-Command -ArgumentList "Application",10 -ScriptBlock {
param([string]$log,[int]$lines)
Get-EventLog $log -Newest $lines
}
这里-ArgumentList包含两个参数
- 字符串"Application"和
- 整数 10
它们作为参数发送到脚本块,因此在脚本块的开头定义。
您现在可以像普通参数一样在脚本块中访问它们:
$log
和
$lines
我觉得你的语法和代码没问题,你确定远程计算机上存在 path2
的目标吗?如果目标无效,则无法创建快捷方式。
一方面,您应该在脚本块中定义您的函数。我不确定 PowerShell v5+,但在 PowerShell v4 和更早版本中有一个命令
Invoke-Command -Computer bar -Scriptblock {function:foo}
会抛出错误,因为该函数在脚本块中无法识别。
此外,您需要实际将参数传递给您正在调用的函数。基本上有两种方法可以处理:
通过 automatic variable $args
:
将参数传递给函数
Invoke-Command -Computer $server -ScriptBlock {
function add-sc {
Param([string[]]$Targets)
Process {
...
}
}
add-sc $args
} -ArgumentList 'path1', 'path2'
将参数作为单个数组传递给脚本块,然后splat将它们传递给函数:
Invoke-Command -Computer $server -ScriptBlock {
function add-sc {
Param([string[]]$Targets)
Process {
...
}
}
add-sc @args
} -ArgumentList @('path1', 'path2')
这两种方法的区别在于前者接受所有参数并将它们作为单个数组传递给函数,而后者将所有参数接受到脚本块并将它们作为单独的参数传递给函数。因此在后一种情况下需要将参数作为单个数组传递给脚本块。
在您的场景中,这两种方法是等效的,但是如果您的函数需要数组以外的第二个参数,您需要第二种方法并将参数作为 -ArgumentList @('a','b'), 'c'
.
传递给脚本块
我想在我的桌面上创建一些快捷方式,它在本地工作。但是当我在远程 PC 上尝试时,我只有一个第一个目标的快捷方式 (path1
),并且脚本忽略了 path2
变量。
$Servers = Get-Content D:.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"
}
您还可以使用 -ArgumentList
参数,或简称 -args
,将多个参数发送到您的脚本块。您只需要在脚本块内处理它们。
查看这个简短示例,了解它是如何完成的
Invoke-Command -ArgumentList "Application",10 -ScriptBlock {
param([string]$log,[int]$lines)
Get-EventLog $log -Newest $lines
}
这里-ArgumentList包含两个参数
- 字符串"Application"和
- 整数 10
它们作为参数发送到脚本块,因此在脚本块的开头定义。
您现在可以像普通参数一样在脚本块中访问它们:
$log
和$lines
我觉得你的语法和代码没问题,你确定远程计算机上存在 path2
的目标吗?如果目标无效,则无法创建快捷方式。
一方面,您应该在脚本块中定义您的函数。我不确定 PowerShell v5+,但在 PowerShell v4 和更早版本中有一个命令
Invoke-Command -Computer bar -Scriptblock {function:foo}
会抛出错误,因为该函数在脚本块中无法识别。
此外,您需要实际将参数传递给您正在调用的函数。基本上有两种方法可以处理:
通过 automatic variable
将参数传递给函数$args
:Invoke-Command -Computer $server -ScriptBlock { function add-sc { Param([string[]]$Targets) Process { ... } } add-sc $args } -ArgumentList 'path1', 'path2'
将参数作为单个数组传递给脚本块,然后splat将它们传递给函数:
Invoke-Command -Computer $server -ScriptBlock { function add-sc { Param([string[]]$Targets) Process { ... } } add-sc @args } -ArgumentList @('path1', 'path2')
这两种方法的区别在于前者接受所有参数并将它们作为单个数组传递给函数,而后者将所有参数接受到脚本块并将它们作为单独的参数传递给函数。因此在后一种情况下需要将参数作为单个数组传递给脚本块。
在您的场景中,这两种方法是等效的,但是如果您的函数需要数组以外的第二个参数,您需要第二种方法并将参数作为 -ArgumentList @('a','b'), 'c'
.