簡體   English   中英

使用通用參數執行遠程通用Powershell腳本

[英]Execute a remote generic Powershell script with generic parameters

我需要編寫一個Powershell腳本(我們稱其為“控制器腳本”),該腳本能夠調用傳遞通用參數的通用遠程Powershell腳本。 控制器腳本接受主機名,憑據,遠程腳本路徑和遠程腳本的參數作為哈希表作為參數。

相反,遠程腳本可以是接受任何字符串參數的任何腳本。

在控制器腳本中使用hashtable參數非常有用,因為我可以傳遞一個動態參數字典(取決於控制器調用),同時讓PS將字典“轉換”為字符串參數列表,例如-Param1 Value1 -Param2 Value2

我從這個答案中得到了一些想法, 就是我所做的(“控制器”腳本):

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 你有什么主意嗎? 我做了一些試驗,但沒有任何效果。

我終於找到了解決方案

controller.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

我建議在Invoke-Command中使用FilePath參數,而不要在腳本塊中使用。 這樣,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

編輯:這可能是您正在尋找的更多:

第一個問題似乎是您沒有正確的腳本路徑,或者您的用戶帳戶無權訪問該路徑。 那就是您所看到的錯誤。 我已經在我的系統上測試了幾種不同的方式,並且.dot源應該可以工作。

前一種方法太早擴展了變量,以至於無法使用展開。 這是如何進行噴濺工作的方法:

Invoke-command -ScriptBlock {$a = $args[0]; & D:\full\path\to\testscript.ps1 @a $args[1]} -ArgumentList $Parameters,$additionalArgs

確保在參數中獲取哈希表而不是字符串

[HashTable] $ Parameters

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM