简体   繁体   中英

How to supply parameters to powershell script (System.Management.Automation.Powershell)?

I have a need to run PowerShell scripts from C# application . I like using method AddScript for this. And it works quite nice. However, it does not seem to work as expected when I added parameters to script with method AddParameters .

Here is test payload ( PowerShell ):

param ([string]$Arg1, [string]$Arg2, [switch]$ArgParamless)
$filename = "payload_with_params.txt"
$filepath = $env:temp
$fullpath = Join-Path -Path $filepath -ChildPath $filename

$dt = Get-Date -Format "yyyy.MM.dd HH:mm:ss"
$val = $dt+' '+$Arg1+' '+$Arg2+' '+$ArgParamless
Add-Content -Path $fullpath -Value "$val"

It works just fine if I push it from PS like this:

.\payload_with_params.ps1 -Arg1 "Bla 1" -Arg2 "Bla 2" -ArgParamless

Result:

2023.01.19 16:58:10 Bla 1 Bla 2 True

The C# code (oversimplified):

string command = File.ReadAllText(pathToPS1);

List<CommandParameter> paramList = new List<CommandParameter>();
paramList.Add(new CommandParameter("Arg1", "Bla 1"));
paramList.Add(new CommandParameter("Arg2", "Bla 2"));
paramList.Add(new CommandParameter("ArgParamless"));

using (PowerShell ps = PowerShell.Create())
{
    //Adding script file content to object
    ps.AddScript(command);
    if (paramList != null)
    {
        if (paramList.Count > 0)
        {
            //Adding Params to object;
            ps.AddParameters(paramList);    
        }
    }
    //Launching
    ps.Invoke();
}

And the result:

2023.01.19 16:54:00 System.Management.Automation.Runspaces.CommandParameter System.Management.Automation.Runspaces.CommandParameter False

So.. it's not working as I expected. How should I supply parameters to script?

For [switch] parameters, you'll want to bind a bool - PowerShell will interpret true as "Present" and false as "Absent":

paramList.Add(new CommandParameter("ArgParamless", true));

Well, it turns out AddParameter(CommandParameter) approach doesn't work.

This approach is working:

string command = File.ReadAllText(pathToPS1);
using (PowerShell ps = PowerShell.Create())
{
    //Adding script file content to object
    ps.AddScript(command);
    if (paramList != null)
    {
        if (paramList.Count > 0)
        {
            //Adding Params to object;
            ps.AddArgument("-Arg1 XXXXXX");
        }
    }
    //Launching
    ps.Invoke();
}

On PowerShell end this arguments can be extracted for usage from $args array:

$arglist = $args -join " "

Even better approach using hashtable:

string command = File.ReadAllText(pathToPS1);
using (PowerShell ps = PowerShell.Create())
{
    //Adding script file content to object
    ps.AddScript(command);
    if (paramList != null)
    {
        if (paramList.Count > 0)
        {
            //Adding Params to object;
            var hashtable = new Hashtable {
                { "Arg1", "XXXXXX" },
                { "Arg2", "YYYYYY" },
                { "ArgParamless", true }
            };
            ps.AddArgument(hashtable);
        }
    }
    //Launching
    ps.Invoke();
}

And that's what you do on PS side to use it:

function Wrapper-Test ([string]$Arg1, [string]$Arg2, [switch]$ArgParamless) {
    $Result = $Args1+' '+$Args2+' '+$ArgParamless
    return $Result
}

$MyArgs = "";
$MyArg = $args[0]
$MyArgs = Wrapper-Test @MyArg;

$filename = "payload_with_params.txt"
$filepath = $env:temp
$fullpath = Join-Path -Path $filepath -ChildPath $filename

$dt = Get-Date -Format "yyyy.MM.dd HH:mm:ss"
$arglist = $args -join " "
$val = $dt + " " + $MyArgs
Add-Content -Path $fullpath -Value "$val"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM