我需要编写一个 Powershell 脚本(我们称之为“控制器脚本”),它能够调用传递通用参数的通用远程 Powershell 脚本。
控制器脚本接受主机名、凭据、远程脚本路径和远程脚本参数(作为哈希表)作为参数。
相反,远程脚本可以是接受任何字符串参数的任何脚本。
对控制器脚本使用哈希表参数很有用,因为我可以传递参数的动态字典(取决于控制器调用),同时使 PS 执行将字典“转换”为字符串参数列表的工作,例如-Param1 Value1 -Param2 Value2
.
我得到了一些想法this答案,这就是我所做的(“控制器”脚本):
Param(
[string] $ComputerName,
[string] $Username,
[string] $Password,
[string] $ScriptPath,
[string] $Parameters
)
$EncPassword = ConvertTo-SecureString $Password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($Username,$EncPassword)
$ScriptBlock = [Scriptblock]::Create(".$ScriptPath $(&{$args} @Parameters)")
Invoke-Command -ComputerName $ComputerName -Credential $cred -Scriptblock $ScriptBlock
然后我通过 PS 提示符执行它:
.\controller.ps1 -ComputerName MACHINE_NAME -Username USERNAME -Password PASSWORD -ScriptPath "D:\TestScript.ps1" -Parameters @{AParameter = "asd"}
执行失败并出现以下错误:
术语“.D:\TestScript.ps1”未被识别为
cmdlet、函数、脚本文件或可操作程序。检查拼写
名称,或者如果包含路径,请验证该路径是否为
正确并重试。
所以看来Scriptblock
指本地脚本(在控制器的计算机上),而不是指目标脚本所在的远程计算机。
有没有办法让我使用 hashtable 参数执行远程 PS 脚本,这是所需的灵活性要求?
UPDATE 1
我在点和点之间添加了一个空格$ScriptPath
变量在ScriptBlock
定义但错误是相同的(没有点)。
$ScriptBlock = [Scriptblock]::Create(". $ScriptPath $(&{$args} @Parameters)")
术语“D:\TestScript.ps1”未被识别为
cmdlet、函数、脚本文件或可操作程序。检查拼写
名称,或者如果包含路径,请验证该路径是否为
正确并重试。
UPDATE 2
我找到了一种无需参数即可调用远程脚本的方法。
Param(
[string] $ComputerName,
[string] $Username,
[string] $Password,
[string] $ScriptPath,
[hashtable] $Parameters
)
$EncPassword = ConvertTo-SecureString $Password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($Username,$EncPassword )
Invoke-Command -ComputerName $computerName -Credential $cred -ScriptBlock {Invoke-Expression $args[0]} -ArgumentList $ScriptPath
我得到不带参数的远程脚本输出。现在剩下要做的就是散列表$Parameters
远程调用远程路径中的脚本时$ScriptPath
。你有什么主意吗?我做了一些尝试,但没有任何效果。