Share

I recently built a graphical application entirely in Windows PowerShell.  While this may sound like a daunting task, it really wasn’t.  The GUI itself is constructed using the same .NET classes that you would use in C# or VB.  You can cut down your dev time by using a form designer like Sapien’s PrimalForms.  Why build an entire app in PowerShell?

Well, to be honest, part of my motivation was just to see if I could. The other was that my initial script was heavily dependent on Quest’s ActiveRoles Management PowerShell Snapin.  Sure, I could have built the application in C# or VB and then imported the PowerShell namespace for some of this, if I really wanted to, but I’m still new to PowerShell and I saw no reason to port most of my code over when I would still be dependent on PowerShell and QARMS anyway.

So naturally, when I went to build an installer for this application, I had to consider that I couldn’t count on the end user having QARMS installed, nor could I assume that every user (especially prior to Windows Vista) would have PowerShell 1.0 or higher installed.

I usually build on my installers in the wonderful Nullsoft Scriptable Install System.  It is VERY powerful, extensible, and open source.  Plus it was originally developed by Nullsoft (of WinAMP fame).  Since PowerShell is the primary external dependency for my application, one of the first things I would need to do is to check to make sure PowerShell is installed.  After googling around for a simple solution and not finding one, I decided to just write a function to do the check myself.  As I expected, everything I needed to know was in the Registry.  So I just look for the appropriate value and return either a “1″ (True) or a “0″ (False).

Like so:

Function IsPowerShellInstalled
  Push $0
  ReadRegDWORD $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\PowerShell\1" "Install"
  StrCmp $0 "" psNotInstalled psInstalled
  psNotInstalled:
    Push 0
    Goto psCheckDone
  psInstalled:
    Push 1
  psCheckDone:
    Return
FunctionEnd

And here is how you would use it:

Section "Windows PowerShell 1.0" SEC02
  DetailPrint "Checking to see if PowerShell is already installed..."
  Call IsPowerShellInstalled
  Pop $0
  StrCmp $0 0 _psNotInstalled _psInstalled
  _psNotInstalled:
    SetOutPath "$TEMP"
    SetOverwrite ifnewer
    DetailPrint "Installing Windows PowerShell..."
    File "WindowsXP-KB926139-v2-x86-ENU.exe"
    ExecWait '$TEMP\WindowsXP-KB926139-v2-x86-ENU.exe'
    Goto EndPSInstalled
  _psInstalled:
    DetailPrint "PowerShell is installed.  Skipping installation..."
  EndPSInstalled:
SectionEnd

This, of course, would need to be modified if you need to install a different version of PowerShell (64-bit, for example) or if you need to check for PowerShell v2.0 instead of 1.0, but you get the jist of it.