使用通用参数执行远程通用Powershell脚本
我需要编写一个Powershell脚本(我们称之为“控制器脚本”),它能够调用传递通用参数的通用远程Powershell脚本。 控制器脚本接受主机名、凭据、远程脚本路径和作为哈希表的远程脚本参数作为参数 相反,远程脚本可以是接受任何字符串参数的任何脚本 为控制器脚本使用哈希表参数非常有用,因为我可以传递参数的动态字典(取决于控制器调用),同时让PS将字典“转换”为字符串参数列表,如使用通用参数执行远程通用Powershell脚本,powershell,Powershell,我需要编写一个Powershell脚本(我们称之为“控制器脚本”),它能够调用传递通用参数的通用远程Powershell脚本。 控制器脚本接受主机名、凭据、远程脚本路径和作为哈希表的远程脚本参数作为参数 相反,远程脚本可以是接受任何字符串参数的任何脚本 为控制器脚本使用哈希表参数非常有用,因为我可以传递参数的动态字典(取决于控制器调用),同时让PS将字典“转换”为字符串参数列表,如-Param1 Value1-Param2 Value2 我从答案中得到了一些想法,这就是我所做的(“控制器”脚本)
-Param1 Value1-Param2 Value2
我从答案中得到了一些想法,这就是我所做的(“控制器”脚本):
然后我通过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
变量之间添加了一个空格,但是错误是相同的(没有点)
术语“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
我得到了没有参数的远程脚本输出。现在剩下的事情是在远程路径调用脚本时远程扩展哈希表
$Parameters
。你知道吗?我做了一些尝试,但没有任何效果。我建议在Invoke命令中使用FilePath参数,而不是scriptblock。这样PSRemoting就完成了所有的繁重工作
Invoke-Command -ComputerName $ComputerName -Credential $cred -FilePath $ScriptPath -ArgumentList $Parameters,$args
否则,您可以使用会话复制文件并运行文件
$Session = New-PSSession -ComputerName $Computer -Credential $credential
Copy-Item -Path $ScriptPath -Destination $Dest -ToSession $Session
Invoke-Command -Session $Session -ScriptBlock $ScriptBlock
编辑:这可能是您所寻找的更多内容:
第一个问题似乎是您没有正确的脚本路径,或者您的用户帐户没有访问该路径的权限。这就是你看到的错误。我已经在我的系统上测试了几种不同的方法,点源应该可以工作
前面的方法扩展变量太早,无法使用splatting。这是如何让挥霍工作:
Invoke-command -ScriptBlock {$a = $args[0]; & D:\full\path\to\testscript.ps1 @a $args[1]} -ArgumentList $Parameters,$additionalArgs
确保在参数中获取哈希表而不是字符串
[哈希表]$Parameters我终于找到了解决方案 控制器.ps1
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 {
$params = $Using:Parameters
Invoke-Expression "$Using:ScriptPath @params"
}
正如您在这里看到的,我们使用
ScriptBlock
中的$Using
变量来检索外部变量($ScriptPath
和$Parameters
),然后我们调用远程脚本来显示参数哈希表。$ScriptPath
->$脚本路径
。您需要一个空格来点源。@gms0ulman我修复了它,但出现了相同的错误(请参阅更新的问题)@gms0ulman我更新了答案,并取得了一些进展。做得很好-看起来您已经对其进行了排序,建议您接受该答案。我尝试了此解决方案,但出现了以下错误:Invoke命令:找不到驱动器。名为“D”的驱动器不存在
我不会使用会话在远程计算机上复制文件,因为目标脚本已在目标计算机上。提示:在本地我没有D
驱动器,而在远程目标上我有它。我认为错误是证明-FilePath
参数和ScriptBlock
定义试图在本地读取路径,而不是远程读取路径(这是我所需要的)。我的建议假设您也在本地读取路径,因为这将简化您的工作。是的,这样会更简单,但在我的例子中,我在不同的机器上有不同的脚本,每个可能都有不同的版本,所以我需要使用通用参数调用通用远程脚本
Invoke-command -ScriptBlock {$a = $args[0]; & D:\full\path\to\testscript.ps1 @a $args[1]} -ArgumentList $Parameters,$additionalArgs
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 {
$params = $Using:Parameters
Invoke-Expression "$Using:ScriptPath @params"
}