I have run into the problem a couple of times where it's not "easy" to add a reference to System.Management.Automation in order to execute PowerShell scripts from .NET code. I found a way around it which works for simple scenarios where you might just want to execute some script and read the standard output plus error output.
System.Management.Automation can be an issue because you may need to install a Windows SDK in order to get the DLL on your machine (http://stackoverflow.com/a/1187978/281177). Then there can be versioning issues also. One workaround seems to be to hack the csproj file to just reference it and hope that Visual Studio knows what to do, for example this solution: http://stackoverflow.com/a/1372061/281177.
Here is some sample code on how to execute a PowerShell script and get the error plus standard output from it using System.Management.Automation:
An alternative is to write some simple code that just executes a batch file, where the batch file kicks off running PowerShell, and take one argument which is the batch file to run:
The batch file can either run the default PowerShell detected:
Or you could try and force it to use a particular "powershell.exe" version by specifying a full path:
DISCLAIMER: I only tested this on a very simple scenario and it was a quick way around the problem. I would be interested to know if you end up using this scenario how it goes for you. Please leave a comment!
System.Management.Automation can be an issue because you may need to install a Windows SDK in order to get the DLL on your machine (http://stackoverflow.com/a/1187978/281177). Then there can be versioning issues also. One workaround seems to be to hack the csproj file to just reference it and hope that Visual Studio knows what to do, for example this solution: http://stackoverflow.com/a/1372061/281177.
Here is some sample code on how to execute a PowerShell script and get the error plus standard output from it using System.Management.Automation:
An alternative is to write some simple code that just executes a batch file, where the batch file kicks off running PowerShell, and take one argument which is the batch file to run:
The batch file can either run the default PowerShell detected:
Or you could try and force it to use a particular "powershell.exe" version by specifying a full path:
DISCLAIMER: I only tested this on a very simple scenario and it was a quick way around the problem. I would be interested to know if you end up using this scenario how it goes for you. Please leave a comment!
Hi Andrew, I'm looking at using your .bat file version of the code and will be putting it into a console or windows app (VS2010).
ReplyDeleteMy code will be nothing more than your snippet.
Because of this I cant get past the Main method. The program runs, jumps in/out of main and then exists. Can you recommend some wrapper code I could put around your code that I could then call from within the main method please?
Hi Jay, sorry for some reason the Gists from GitHub were showing all 4 files when I specifically told them to include one file, so the blog post looked a bit wacky. I have fixed it now by splitting them into separate Gists.
ReplyDeleteAnyhow, so my understanding is that you would like a sample console app that does this? I will just create a little app that does it and post the steps I follow here:
1. Create the new console app in Visual Studio.
2. Add a batch file called 'PowerShellRunner.bat' to the project with contents 'powershell "%1"'. I prefer to create the batch file in windows explorer then include it in the project, sometimes Visual Studio gives the file a different encoding and it won't run.
3. Also add your powershell file to the project same as the batch file. For my example I am adding a file called 'TestPowerShell.ps1' and the contents of the file are as follows: '"This text proves powershell has been run" > Success.txt'. So when this powershell file runs, it will spit out a file called 'Success.txt' with that string in it. You would obviously put the contents of the script you want to run here.
4. Select the batch file and the powershell file and in the 'Properties' window change 'Copy to output directory' to 'Copy if newer' to ensure the files end up next to your exe.
5. Copy and paste the code from this gist: https://gist.github.com/nootn/4713988 into your 'Program.cs'. I won't paste the code in this comment because it would be ugly.
I just built and ran this little app following these steps now and it worked fine.
Let me know how you go! I hope this helps you.