2015-01-06 53 views
4

我有一個接受3個命名參數的PowerShell腳本。請讓我知道如何從命令行傳遞相同的內容。我嘗試了下面的代碼,但同樣不工作。它僅將整個值分配給P3。我的要求是P1應該包含1,P2應該2和P3應該被分配3.PowerShell將參數傳遞給參數列表

Invoke-Command -ComputerName server -FilePath "D:\test.ps1" -ArgumentList {-P1 1 -P2 2 -P3 3} 

以下是腳本文件代碼。

Param (
    [string]$P3, 
    [string]$P2, 
    [string]$P1 
) 
Write-Output "P1 Value :" $P1 
Write-Output "P2 Value:" $P2 
Write-Output "P3 Value :" $P3 
+0

可能重複http://stackoverflow.com/questions/4225748/how-do-i-pass- named-parameters-with-invoke-command) –

回答

9

一個選項:

$params = @{ 
P1 = 1 
P2 = 2 
P3 = 3 
} 

$ScriptPath = 'D:\Test.ps1' 

$sb = [scriptblock]::create(".{$(get-content $ScriptPath -Raw)} $(&{$args} @params)") 

Invoke-Command -ComputerName server -ScriptBlock $sb 
+0

是的我能夠使用上面的代碼實現結果。 –

+1

您可以讓我知道如何使用C#代碼實現相同的功能,因爲我的要求是從C#運行此PowerShell腳本。 –

+0

對不起,不知道C#足夠好轉換爲你。 – mjolinor

3

使用哈希表:

icm -ComputerName test -ScriptBlock{$args} -ArgumentList @{"p1"=1;"p2"=2;"p3"=3} 
+0

可以請你提供更多的細節。 –

+0

看這個帖子http://stackoverflow.com/a/4226027/381149 –

2

通過mjolinor代碼的偉大工程,但我花了幾分鐘的時間去了解它。

的代碼,使一個簡單的事情 - 生成腳本塊帶有內置參數的內容:

&{ 
    Param (
     [string]$P3, 
     [string]$P2, 
     [string]$P1 
    ) 
    Write-Output "P1 Value:" $P1 
    Write-Output "P2 Value:" $P2 
    Write-Output "P3 Value:" $P3 
} -P1 1 -P2 2 -P3 3 

那麼這個腳本塊被傳遞給調用命令。

爲了簡化代碼:

".{$(get-content $ScriptPath -Raw)} $(&{$args} @params)" 

$scriptContent = Get-Content $ScriptPath -Raw 
$formattedParams = &{ $args } @params 
# The `.{}` statement could be replaced with `&{}` here, because we don't need to persist variables after script call. 
$scriptBlockContent = ".{ $scriptContent } $formattedParams" 
$sb = [scriptblock]::create($scriptBlockContent) 

讓我們做一個基本的C#實現:

void Run() 
{ 
    var parameters = new Dictionary<string, string> 
    { 
     ["P1"] = "1", 
     ["P2"] = "2", 
     ["P3"] = "3" 
    }; 

    var scriptResult = InvokeScript("Test.ps1", "server", parameters) 
    Console.WriteLine(scriptResult); 
} 

string InvokeScript(string filePath, string computerName, Dictionary<string, string> parameters) 
{ 
    var innerScriptContent = File.ReadAllText(filePath); 
    var formattedParams = string.Join(" ", parameters.Select(p => $"-{p.Key} {p.Value}")); 
    var scriptContent = "$sb = { &{ " + innerScriptContent + " } " + formattedParams + " }\n" + 
     $"Invoke-Command -ComputerName {computerName} -ScriptBlock $sb"; 

    var tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".ps1"); 
    File.WriteAllText(tempFile, scriptContent); 

    var psi = new ProcessStartInfo 
     { 
      FileName = "powershell", 
      Arguments = [email protected]"-ExecutionPolicy Bypass -File ""{tempFile}""", 
      RedirectStandardOutput = true, 
      UseShellExecute = false 
     }; 

    var process = Process.Start(psi); 
    var responseText = process.StandardOutput.ReadToEnd(); 

    File.Delete(tempFile); 

    return responseText; 
} 

的代碼生成臨時腳本並執行它。

示例腳本:

$sb = { 
    &{ 
     Param (
      [string]$P3, 
      [string]$P2, 
      [string]$P1 
     ) 
     Write-Output "P1 Value:" $P1 
     Write-Output "P2 Value:" $P2 
     Write-Output "P3 Value:" $P3 
    } -P1 1 -P2 2 -P3 3 
} 
Invoke-Command -ComputerName server -ScriptBlock $sb 
的[?我如何通過與調用命令的命名參數(