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

Time:01-21

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?

CodePudding user response:

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));

CodePudding user response:

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"
  • Related