![](/img/trans.png)
[英]Local or remote execution of powershell script with generic parameters
[英]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.