I'm certainly not a PowerShell expert but I have been finding my way around it lately. Once I got a few interesting scripts put together and saved to a file the next thing I ran up against was how do I launch these without loading them into the interactive environment by hand? By default when you install PowerShell it associates script files (.ps1 files) with notepad. Great for editing, not so great if you want to execute them. My guess is that after the 'Monad/PowerShell virus' story a year back or so that Microsoft got a little too freaked out to just let these things launch when clicked on. Unfortunately this decision also makes it more difficult to schedule a PowerShell script in the task scheduler too. To top it all off it's not quite as simple as just passing your script as a command line argument to PowerShell either. There are two separate steps necessary to enable you to launch PowerShell scripts from the Windows shell.

First you have to set up a file association in the Windows shell to change the default behavior for .ps1 files. However the PowerShell command line doesn't know what to do with a script file. By default it simple takes statements to execute. We can leverage this to our advantage though and construct a statement to cause our script file to be loaded and executed. That statement looks something like this:

powershell -command "& 'MyScript.psa1' "

If you update the file association with this you can then launch script files from the command line or by clicking on them. You can use the Tools | Folder Options dialog to do this but why not use PowerShell instead? Here are two simple lines of code to update your system registry to tell it how to execute .ps1 script files.

Note: This of course updates your system registry so you should back things up first.

new-item Registry::hkey_classes_root\microsoft.powershellscript.1\shell

new-item Registry::hkey_classes_root\microsoft.powershellscript.1\shell\open

new-item Registry::hkey_classes_root\microsoft.powershellscript.1\shell\open
\command -value ('"' + $PSHOME + '\powershell.exe" -command "& ''%1''"')

If you run these two PowerShell lines and then try and click on a .ps1 script file you'll see that we're not quite there yet. PowerShell has an execution policy that by default is set to "Restricted." In restricted mode no scripts are allowed to execute, only interactive commands may be executed. By using the PowerShell "set-executionpolicy" cmdlet you can change it to something more sensible like RemoteSigned which allows all locally generated scripts to execute but will only allow downloaded scripts to execute if they have been signed by a trusted source. In PowerShell you can execute the "help  about_signing" command for more info on this.

Once these two steps are done you can now launch PowerShell scripts directly without having to start up the interactive environment first. In addition you can also use this method to schedule PowerShell scripts in the task scheduler.

Many larger applications having scripting capabilities built in to allow you to automate repetitive tasks but what do you do if you need to script a repetitive task for an application that doesn't have a scripting or macro language built in?  You could use VBScript and the SendKeys function. This works for simple things but it isn't always robust enough. What if you need to do something more complex, for instance: launch an application, wait for the main window to open, resize the window, send some keystrokes, and then click on a specific UI element? Unfortunately VBScript and its set of built-in functions don't always cut it when you need to move beyond SendKeys.

When your needs go beyond what VBScript can do natively you might want to take a look at AutoIt. AutoIt is a small suite of tools, the main component being a stand-alone scripting language. What sets AutoIt apart from other scripting languages is that it is targeted at GUI application scripting and its built-in set of functions enable the finer level of control lacking in VBScript and other scripting languages. The AutoIt scripting language is very VB-like and easy to pick up if you're already familiar with VB. AutoIt has a rich feature set including (taken from the AutoIt web site):

  • Provide a general-purpose scripting language for all Windows versions
  • Simulate keystrokes (supports most keyboard layouts)
  • Simulate mouse movements and clicks
  • Move, resize and manipulate windows
  • Interact directly with "controls" on a window (set/get text from edit controls, check boxes and radio buttons, select items in drop-down lists, etc.)
  • Create complex user interfaces (GUI's)
  • Work with the clipboard to cut/paste text items
  • Provide a scriptable RunAs function for Windows 2000/XP/2003

However what is really interesting to me is that AutoIt also includes a scriptable COM object essentially making its core application scripting capabilities available to any other COM capable languages including VBA, VBScript, PowerShell, or .Net. The COM interface on this object seems well thought out and is very easy to use. I started using AutoIt for this feature as I needed to automate an application from within Outlook's VBA scripting. Using the AutoIt COM object I was able to write Outlook VBA code to control another application including starting the application, waiting for its main window to launch, and intelligently sending data to the right parts of its UI.

And best of all, AutoIt is free. It can be found here.

Note: PowerShell is on the horizon and by all accounts it should be a very powerful tool but it also seems to lack some of this finer level of control for scripting GUI applications. You can however access the AutoIt COM object as well as the full .Net library.

Flux and Mutability

The mutable notebook of David Jade