Friday, May 11, 2012

An easy way to become a PowerShell programmer

I admit – I barely use PowerShell. I am not an administrator and most things I do involve compiled code rather than scripting.

However, from time to time there is something to be done at production servers like “connect to Sql Server, do this, this and that” or “find all files in a specified folder and perform a regex replace”.

From my perspective, such tasks are easily handled in a high-level programming language but there’s a caveat – what I can do is I can compile my code and give the executable file to my colleague who is an administrator. He has to trust that the executable contains only the code to perform the required task.

An alternative approach involves writing shell scripts, old good vbs/js scripts or PowerShell scripts. An advantage of a script is that it can be easily examined against any unwanted code. A distadvantage of a script is that every few weeks/months I need to write one, I start from the same basic tutorials just to refresh my memory on what’s the syntax, how to define variables, how to create object instances, invoke methods etc.

Until now.

I just stumbled upon a simple way to easily embed C# code to PowerShell scripts. This involves the Add-Type cmdlet which is supposed to define types in a PowerShell session. What I wasn’t aware of is that the cmdlet is capable of creating types from C# strings.

#test.ps1
$code = @"
    using System;
    public class Foo
    {
        public void Bar( int x )
        {
            Console.WriteLine( x );
            Console.ReadLine();
        }
    }    
"@
 
Add-Type -TypeDefinition $code
 
$foo = New-Object Foo
$foo.Bar( 5 )

As always, to run the script I have to bypass the signing requirement, from the command line:

powershell.exe -ExecutionPolicy bypass -File ./test.ps1 

or from within the PowerShell console:

Set-ExecutionPolicy unrestricted
./test.ps1

An example of referring to Windows.Forms:

#test2.ps1
$code = @"
    public class TestForm : System.Windows.Forms.Form
    {
        
    }
"@
 
Add-Type -TypeDefinition $code -ReferencedAssemblies "System.Windows.Forms"
 
$form = New-Object TestForm
$form.ShowDialog();

Great. Now I can finally be a PowerShell programmer :)

2 comments:

Dominik Dalek said...

It's more like "still being a regular C# programmer and cheating PowerShell into running your code". ;P

notYourBusiness said...

well, this is going to be very handy. No more reading tutorials every regarding PowerShell. Thanks