【发布时间】:2018-08-20 15:29:18
【问题描述】:
我需要编写一个能够调用通用远程 Powershell 脚本并传递通用参数的 Powershell 脚本(我们称之为“控制器脚本”)。 控制器脚本接受作为参数的主机名、凭据、远程脚本路径和远程脚本的参数作为哈希表。
相反,远程脚本可以是任何接受任何字符串参数的脚本。
对控制器脚本使用 hashtable 参数很有用,因为我可以传递参数的动态字典(取决于控制器调用),同时让 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 脚本,这是所需的灵活性要求吗?
更新 1
我在ScriptBlock 定义中的点和$ScriptPath 变量之间添加了一个空格,但错误是相同的(没有点)。
$ScriptBlock = [Scriptblock]::Create(". $ScriptPath $(&{$args} @Parameters)")
术语“D:\TestScript.ps1”未被识别为 cmdlet、函数、脚本文件或可运行的程序。检查拼写 的名称,或者如果包含路径,请验证该路径是 正确并重试。
更新 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
我得到没有参数的远程脚本输出。现在剩下要做的就是在远程路径$ScriptPath 处调用脚本时远程喷射哈希表$Parameters。你有什么主意吗?我做了一些试验,但没有任何效果。
【问题讨论】:
-
.$ScriptPath->. $ScriptPath。你需要一个空间来点源。 -
@gms0ulman 我修复了它但有同样的错误(见更新的问题)
-
@gms0ulman 我更新了答案并取得了一些进展。
-
干得好 - 看起来你已经整理好了,建议你接受这个答案。
标签: powershell