Showing posts with label Preference Variables. Show all posts
Showing posts with label Preference Variables. Show all posts

Monday, July 28, 2008

More Preference Variables

I covered $ErrorActionPreference in the last post, but there are a few other preference variables that you might want to be aware of.  The full list can be found here.


$ConfirmPreference  (default value = 'High')

$ConfirmPreference sets the default level for the -Confirm option on cmdlets.  When a developer makes a cmdlet they have the option of setting the impact level to 'Low', 'Medium', or 'High'.  When a command is run, if the impact level is greater than or equal to the level in $ConfirmPreference, a confirmation prompt appears before the action is executed.  The confirmation prompt will look something like this:

Are you sure you want to perform this action?
Performing operation "Stop-Process" on Target "calc (5852)".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): 

To suppress confirmation prompts altogether, you can set $ConfirmPreference to $false, which is especially useful when scripting High impact operations.


$OFS (default value = ' ')

$OFS is the Output Record Separator.  Let's say I make an array and then print it, like so: 

PS C:\Users\tojo2000\Documents> $array = ('T', 'O', 'J', 'O')
PS C:\Users\tojo2000\Documents> echo $array
T
O
J
O

Each element of the array was echoed.  Notice what happens if we embed our array in a double-quoted string, though.
 
PS C:\Users\tojo2000\Documents> "My name is $array."
My name is T O J O.

Because the default value of $OFS is a single space, each element of the array is printed with a single space between.  We can set $OFS to be whatever we want, however:

PS C:\Users\tojo2000\Documents> $OFS = ' to the '
PS C:\Users\tojo2000\Documents> "My name is $array."
My name is T to the O to the J to the O.


$DebugPreference (default value = 'SilentlyContinue')
$ProgressPreference (default value = 'Continue')
$VerbosePreference (default value = 'SilentlyContinue')
$WarningPreference (default value = 'Continue')

These preference variables tell PowerShell what to do if it comes across a Debug, Progress (when using the Write-Progress cmdlet, for example), Verbose, or Warning message.  

The possible options are:
  • Inquire - print the message, then prompt to continue
  • Continue - print the message, then continue
  • SilentlyContinue - suppress the message, then continue
  • Stop - error out of the script or cmdlet

Wednesday, July 23, 2008

Handling Errors in PowerShell

Powershell gives you a few ways to handle errors in your scripts.  The most powerful tool in your arsenal is the exception trap, I'm sure, but it's a bit complicated and I can't claim to be a master of PowerShell exceptions, but I'll go over that too.  We'll start off with something you'll use a lot more though, even though you may not know it.


PowerShell has a number of Preference Variables that you can use to determine the way it behaves.  If you have the v2 CTP version installed then you can run 'help about_Preference_Variables' to see the list, but for the rest of us use the link above.  $ErrorActionPreference sets the way PowerShell will respond when hitting a non-terminating error.  This won't affect errors that terminate a script.  

The allowable values for $ErrorActionPreference are 'Continue' (default), 'SilentlyContinue', 'Inquire', and 'Stop'.

Which errors are terminating and which aren't?  Well there's no definitive list, but take this example to show you how it works:

PS HKLM:\> dir


   Hive: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE

SKC  VC Name                           Property
---  -- ----                           --------
  7   4 COMPONENTS                     {StoreFormatVersion, StoreArchitecture, PublisherPolicyChangeTime, LastScavengeCookie}
  4   0 HARDWARE                       {}
  1   0 SAM                            {}
Get-ChildItem : Requested registry access is not allowed.
At line:1 char:3
+ dir <<<<
 17   0 SOFTWARE                       {}
  9   0 SYSTEM                         {}

______________________________________________________

PS HKLM:\> $ErrorActionPreference = 'SilentlyContinue'
PS HKLM:\> dir


   Hive: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE

SKC  VC Name                           Property
---  -- ----                           --------
  7   4 COMPONENTS                     {StoreFormatVersion, StoreArchitecture, PublisherPolicyChangeTime, LastScavengeCookie}
  4   0 HARDWARE                       {}
  1   0 SAM                            {}
 17   0 SOFTWARE                       {}
  9   0 SYSTEM                         {}

______________________________________________________

PS HKLM:\> $ErrorActionPreference = 'Inquire'
PS HKLM:\> dir


   Hive: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE

SKC  VC Name                           Property
---  -- ----                           --------
  7   4 COMPONENTS                     {StoreFormatVersion, StoreArchitecture, PublisherPolicyChangeTime, LastScavengeCookie}
  4   0 HARDWARE                       {}
  1   0 SAM                            {}

Confirm
Requested registry access is not allowed.
[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"): y
Get-ChildItem : Requested registry access is not allowed.
At line:1 char:3
+ dir <<<<
 17   0 SOFTWARE                       {}
  9   0 SYSTEM                         {}


As you can see, the default is to print an error and continue, while 'SilentlyContinue' will suppress error messages, which is similar to the old 'On Error Resume Next' in VBScript.

One nice side-effect of having this Preference Variable is that you can change the behavior for just one code block or function within your script.  Once the variable inside of the block goes out of scope, $ErrorActionPreference reverts to the original value.

PS HKLM:\> function suppress_errors ([string]$path) {
>> $ErrorActionPreference = 'SilentlyContinue'
>>  echo "`$ErrorActionPreference = $ErrorActionPreference"
>>}
>>
PS HKLM:\> echo "`$ErrorActionPreference = $ErrorActionPreference"
$ErrorActionPreference = Continue
PS HKLM:\> suppress_errors
$ErrorActionPreference = SilentlyContinue
PS HKLM:\> echo "`$ErrorActionPreference = $ErrorActionPreference"
$ErrorActionPreference = Continue


NOTE: You can also use the -ErrorAction (or -ea) switch that is ubiquitous across cmdlets with the same values if you want to change PowerShell's behavior for a particular command.