Tuesday, March 6, 2012

When to code and when to script?

When I describe PowerShell to someone new, I tend to refer to it as a glue language.  It is very good for tying different types of technology together.  In practical use, I have found that it is very beneficial for describing custom business logic to a problem.

Now it is true that in PowerShell you can embed C#, VB, F# and the like.  You are sitting in .NET land so you can reasonably do anything in PowerShell that you can do in C#.  The question is; where do you draw the line?  Fortunately PowerShell has many shades of color between your Visual Studio work, and your ISE work. Picture the rainbow.

What we really need to consider, is the proper choice between the following.
1.     Pure C#.
2.     C# with PowerShell Classes implemented (http://msdn.microsoft.com/en-us/library/windows/desktop/ee706563(v=vs.85).aspx)
3.     PowerShell with a compiled Module
4.     PowerShell Module written in PowerShell calling C#
5.     Script with C#
6.     PowerShell Module written in PowerShell with no add-type definitions.
7.     Pure PowerShell

What attribute of our processes do we want to consider?
1.     Platform (Web based , win forms, WPF, console)
2.     Complexity
3.     What do you know how to do?
4.     How are you going to deploy it?
5.     Do you want to own this process forever?
6.     Do you centrally maintain source code?
7.     How much of this process is potentially going to change.

WMF 3.0 has the ability to make a web service in PowerShell, but if you want a rich web based UI, do it in visual studio.  If you want something else you can probably do it in PowerShell with a sliding scale of things getting crazy.  

Complexity is probably the most important item to consider and potentially the most difficult to determine.  Sometimes very simple things can be subject to scope creep (http://en.wikipedia.org/wiki/Scope_creep).  If you are going to use something that is best implemented via object oriented abstractions, then you may want to consider doing your classes in Visual Studio.

What do you know how to do? How much do you know about how things work, vs. what you need to get done?  These are two simple questions, but they should still be considered.  If you want to have a dialog box for user import, this can probably be done easily enough in PowerShell using ShowUI (http://showui.codeplex.com/) or directly with the Windows.Forms classes.  Now if you don't know anything about these, download VS2010 Express, select a library assembly, draw your form, and mark your UI elements as public.  It is a bunch of extra steps, but using a UI to wire up the GUI can make a big difference in headaches and subtle bugs.   

Remember, if you need to, you can just save the .CS file and pull it in via "Add-Type -TypeDefinition".  VS could be used just to author the form.  Keep in mind that there is a designer partial class that will need to be loaded also, just append the two files before your Add-Type.  I recommend that if you are importing more than a few lines of code via a TypeDefinition, that you keep this in an external file.  The PowerShell ISE won't syntax check your C#, and won't be much help in debugging either.

Does deployment matter?  If I am going to do automation for another team in the office, it is very crucial that they have access to everything needed to maintain the item.  It may be years from now, but a random EXE sitting in accounting is going to get thrown away if things change.  If it is implemented in a script, they have everything.  They have my name in comments and the entire source to change or pass to someone else.  True you could zip any source and pass it around with the EXE, or embed it as a resource with an option to extract it... but that gets a little convoluted.  It also requires that someone have Visual Studio or some variant.  Ownership is closely paired with this.  A script, if it can be done cleanly can much more easily be moved to another process owner if there is no corporate process for managing things like this.  If you do centrally manage your source code across anyone that may use your automation, then some of this doesn't apply.

The second largest question is looking at how much of what you are going to do will change.  Sure, if you have 5 lines of script and it never changes, then this is a bit mote. But if you are powering Excel to graph frequencies of log entries in a pivot table, and someone asks why you used “THAT” font.  A tweak in a script is easier than an application recompile.

I need to think about these attributes some.  Then I will look at trying to build some better ideas about how to choose between the options.

1 comment:

  1. posted this to: http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/69cfd5a3-f155-4e7a-ae60-95af93cf2021 for feedback.

    Justin Rich (http://jrich523.wordpress.com) contributed that simplified process in the compiled languages such as LINQ should be considered.

    Also load times for the process you are looking at should be considered.

    C# is compiled to IL, but PoweShell has a loader, an additional file read, and then the text has to be run through the Tokenizer ( [system.management.automation.psparser]::Tokenize ).

    Obfuscation as EXE to prevent modification or to hide meaning.

    He also mentioned Compiled PS, which is a hosted PowerShell process that pulls a script from a hard coded string or an internal resource.

    ReplyDelete