Archives
-
Why every .net developer should learn some PowerShell
It has been 8 years since PowerShell v.1 was shipped in 2006. I have looked into PowerShell closely except for using it in the Nuget Console. Recently, I was forced to have a much closer look at PowerShell because we use a product that exposes its only interface in PowerShell.
Then I realized that PowerShell is such a wonderful product that every .net developer should learn some. Here are some reasons:
- PowerShell is a much better language that the DOS batch language. PowerShell is real language with variable, condition, looping and function calls.
- According to Douglas Finke in Windows Powershell for Developers by O’Reilly, PowerShell is a stop ship event, meaning no Microsoft server products ship without a PowerShell interface.
- PowerShell now has a pretty good Integrated Scripting Environments (ISE). We can create, edit, run and debug PowerShell. Microsoft has release OneScript, a script browser and analyzer that could be run from PowerShell ISE.
- We can call .NET and COM objects from PowerShell. That is an advantage over VBScript.
- PowerShell has a wonderful pipeline model with which we can filter, sort and convert results. If you love LINQ, you would love PowerShell.
- It is possible to call PowerShell script from .net, even ones on a remote machine.
Recently, I have to call some PowerShell scripts on a remote server. There are many piecewise information on the internet, but no many good examples. So I put a few pointers here:
- When connecting to remote PowerShell, the uri is : http://SERVERNAME:5985/wsman.
- It is possible to run PowerShell in a different credential using the optional credential.
- Powershell remoting only runs in PowerShell 2.0 or later. So download the PowerShell 2.0 SDK (http://www.microsoft.com/en-us/download/details.aspx?id=2560). When installed, it actually updates the 1.0 reference assemblies . On my machine, they are in: C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0
So the complete code runs like:
using System.Management.Automation; // Windows PowerShell namespace using System.Management.Automation.Runspaces; // Windows PowerShell namespace using System.Security; // For the secure password using Microsoft.PowerShell; Runspace remoteRunspace = null; //System.Security.SecureString password = new System.Security.SecureString(); //foreach (char c in livePass.ToCharArray()) //{ // password.AppendChar(c); //} //PSCredential psc = new PSCredential(username, password); //WSManConnectionInfo rri = new WSManConnectionInfo(new Uri(uri), schema, psc); WSManConnectionInfo rri = new WSManConnectionInfo(new Uri(""http://SERVERNAME:5985/wsman")); //rri.AuthenticationMechanism = AuthenticationMechanism.Kerberos; //rri.ProxyAuthentication = AuthenticationMechanism.Negotiate; remoteRunspace = RunspaceFactory.CreateRunspace(rri); remoteRunspace.Open(); using (PowerShell powershell = PowerShell.Create()) { powershell.Runspace = remoteRunspace; powershell.AddCommand(scriptText); Collection
results = powershell.Invoke(); remoteRunspace.Close(); foreach (PSObject obj in results) { foreach (PSPropertyInfo psPropertyInfo in obj.Properties) { Console.Write("name: " + psPropertyInfo.Name); Console.Write("\tvalue: " + psPropertyInfo.Value); Console.WriteLine("\tmemberType: " + psPropertyInfo.MemberType); } } }