Wednesday, 29 September 2010

Powershell: Error-handling in modules

I've recently started using modules for my Powershell commands for managing my custom commands, since I this neing a great way to encapsulate and distribute such commands. Besides, I can choose the purpose of my session by selecting what modules to import.

However, there seems to be a BIG caveat with modules: the global variables seems not to be available. In particular, the automatic $error variable cannot be used inside modules. You can try this example:
New-Module -ScriptBlock {
    function div ($number) {
       try { 1/$number }
       catch { Write-Host $Error[0] }
    }
} -name DivMod | Import-module

PS > div 1

1

PS > div 0

Note the empty line: the $Error variable is empty! I need to dig further into this, but since not even Googling seems to have any answers(!), I think I've come up with a workaround, at least: use Invoke-Expression with the -ErrorVariable parameter for 'sensitive' commands (e.g. those that you need good error-handling for).
New-Module -ScriptBlock {
   function div ($number) {
      try { Invoke-Expression '1/$number' -ErrorVariable e }
      catch { Write-Error $e }
   }
} -name DivMod | Import-module

PS > div 1

1

PS > div 0
System.Management.Automation.CmdletInvocationException: Attempted to divide by zero...
Using this, you can use try..catch in modules almost as you would in scripts.

If anyone out there has a better solution (I'd really like to be able to use the $error variable...) don't hesitate to comment/point me in the right direction!

1 comment:

  1. Try using the $_ variable inside the catch block.

    Alternatively, use $Global:error. See here for details...

    http://stackoverflow.com/a/11457624/81595

    ReplyDelete