Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Variables from C# to Powershell

I am working on a C# project that that is supposed to grab a string variable (file path) and pass it to PowerShell script to have further commands done with it. I have been looking around online and through Stack and have not been able to find something that works for me...

Here is my C# code as it stands right now:

string script = System.IO.File.ReadAllText(@"C:\my\script\path\script.ps1");

using (Runspace runspace = RunspaceFactory.CreateRunspace())
{

    runspace.Open();
    PowerShell ps = PowerShell.Create();
    ps.Runspace = runspace;
    ps.AddScript(script);
    ps.Invoke();
    ps.AddCommand("LocalCopy");

    foreach (PSObject result in ps.Invoke())
    {
        Console.WriteLine(result);
    }
}                   

Here is my PowerShell script:

Function LocalCopy
{
    Get-ChildItem -path "C:\Users\file1\file2\file3\" -Filter *.tib -Recurse | 
    Copy-Item -Destination "C:\Users\file1\file2\local\"
}

What I want to do is have the first part of the the script: "C:\Users\file1\file2\file3\" replaced with (what i am assuming would be) a variable that I could pass from the C# code to the PowerShell script. I am very new to working with PowerShell and am not quite sure how I would go about doing something like this.

---EDIT---

I am still having issues with my code, but i am not getting any errors. I believe that it is because the variable is still not being passed through...

C# code:

string script = System.IO.File.ReadAllText(@"C:\my\script\path\script.ps1");

using (Runspace runspace = RunspaceFactory.CreateRunspace())
{

    runspace.Open();
    PowerShell ps = PowerShell.Create();
    ps.Runspace = runspace;
    ps.AddScript(script);
    ps.Invoke();
    ps.AddArgument(FilePathVariable);
    ps.AddCommand("LocalCopy");

    foreach (PSObject result in ps.Invoke())
    {
        Console.WriteLine(result);
    }
}

PowerShell code:

Function LocalCopy
{
    $path = $args[0]
    Get-ChildItem -path $path -Filter *.tib -Recurse | 
    Copy-Item -Destination "C:\Users\file1\file2\local\"
}

Any help would be much appreciated. Thanks!

like image 258
scapegoat17 Avatar asked Dec 20 '22 01:12

scapegoat17


2 Answers

I would go the route Anand has shown to pass a path into your script. But to answer the question posed by your title, here's how you pass variable from C#. Well this is really how you set the variable in the PowerShell engine.

ps.Runspace.SessionStateProxy.SetVariable("Path", @"C:\Users\file1\file2\file3\");

Note: in C# for file paths you really want to use verbatim @ strings.

Update: based on your comments, try this:

runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.AddScript(script, false); // Use false to tell PowerShell to run script in current 
                             // scope otherwise LocalCopy function won't be available
                             // later when we try to invoke it.
ps.Invoke();
ps.Commands.Clear();
ps.AddCommand("LocalCopy").AddArgument(FilePathVariable);
ps.Invoke();
like image 189
Keith Hill Avatar answered Dec 22 '22 15:12

Keith Hill


ps.AddArgument("C:\Users\file1\file2\file3\");

you can use args to fetch the argument in powershell.

$path = $args[0]

MSDN

like image 24
Anand Avatar answered Dec 22 '22 15:12

Anand