PowerShell Pass Named parameters to ArgumentList

前端 未结 7 1959
没有蜡笔的小新
没有蜡笔的小新 2021-02-20 08:14

I have a PowerShell script that accepts 3 named parameters. Please let me know how to pass the same from command line. I tried below code but same is not working. It assigns the

7条回答
  •  我在风中等你
    2021-02-20 09:05

    The code by mjolinor works great, but it took me several minutes to understand it.

    The code makes a simple thing - generates a content of script block with built-in parameters:

    &{
        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
    

    Then this script block is passed to Invoke-Command.

    To simplify the code:

    ".{$(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)
    

    Let's make a basic C# implementation:

    void Run()
    {
        var parameters = new Dictionary
        {
            ["P1"] = "1",
            ["P2"] = "2",
            ["P3"] = "3"
        };
    
        var scriptResult = InvokeScript("Test.ps1", "server", parameters)
        Console.WriteLine(scriptResult);
    }
    
    string InvokeScript(string filePath, string computerName, Dictionary 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 = $@"-ExecutionPolicy Bypass -File ""{tempFile}""",
                RedirectStandardOutput = true,
                UseShellExecute = false
            };
    
        var process = Process.Start(psi);
        var responseText = process.StandardOutput.ReadToEnd();
    
        File.Delete(tempFile);
    
        return responseText;
    }
    

    The code generates a temporary script and executes it.

    Example script:

    $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
    

提交回复
热议问题