Executing PowerShell Scripts via C#

By on 11/13/2009

When Dave asked me for some help with a little side project of his that he was researching, I jumped at the chance.  The requirement was to execute a powershell script programmatically and pass in some parameters that were gathered from a simple form.

I had been wanting to learn more about powershell since it came out (the original codename was called monad) and this was the perfect opportunity.  The end result is a simple little static class that you can use to execute a powershell script and pass in some parameters in a strongly typed fashion.

Here's a sample usage:
string result = PowerShell.Execute(
    () => new
        server = formserver,
        fname = formname
Although there are quite a few little nuances involved in the execution from a command line, once you figure them out it's quite easy.  The class basically just does a Process.Execute on the PowerShell.exe command and passes in some command line arguments that executes the ps1 file.

I opted to do this instead of the cleaner API that is available via hosting the powershell runtime because that has an additional requirement on System.Management.Automation.dll which must be installed with the windows sdk.  I didn't want to introduce this dependency for the project, so the command line method was preferrable.

Below is the class ... you'll obviously have to include a few extra using statements at the top of your file, but you can find those easily.  Enjoy!
public static class PowerShell
    public static string Execute(string scriptPath, Expression<Func<object>> parameters)
        string shellPath = "powershell.exe";
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("\"& '{0}'\" ", scriptPath);

NewExpression n = parameters.Body as NewExpression;

for (int i = 0; i < n.Members.Count; i++) { var member = n.Members[i]; var value = n.Arguments[i]; string paramValue; if (value is MemberExpression) { paramValue = Expression.Lambda(value).Compile().DynamicInvoke().ToString(); } else { paramValue = value.ToString().Replace("\"", string.Empty); } sb.AppendFormat(" -{0} {1}", member.Name.Replace("get_", ""), paramValue); }

string result = ExecuteCommand(shellPath, sb.ToString()); return result; }

private static string ExecuteCommand(string shellPath, string arguments) { arguments = "-noprofile " + arguments; var process = new Process(); var info = process.StartInfo;

process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = shellPath; process.StartInfo.Arguments = arguments; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true;


var output = process.StandardOutput; var error = process.StandardError;

string result = output.ReadToEnd(); process.WaitForExit(); return result; } }

See more in the archives