When you change variables, you might need to clean up later and ensure that you reverted them back to some default value – unless you use custom scopes. Yesterday, we looked at how console application errors can be handled, and when you look at the code again, you see that a lot of effort was taken to restore the $ErrorActionPreference system variable:
try { # set the preference to STOP $old = $ErrorActionPreference $ErrorActionPreference = 'Stop' # RUN THE CONSOLE EXE THAT MIGHT EMIT AN ERROR, # and redirect the error channel #2 to the # output channel #1 net user doesnotexist 2>&1 } catch [System.Management.Automation.RemoteException] { # catch the error emitted by the EXE, # and do what you want $errmsg = $_.Exception.Message Write-Warning $errmsg } finally { # reset the erroractionpreference to what it was before $ErrorActionPreference = $old }
A much easier way would be a custom scope:
& { try { # set the preference to STOP $ErrorActionPreference = 'Stop' # RUN THE CONSOLE EXE THAT MIGHT EMIT AN ERROR, # and redirect the error channel #2 to the # output channel #1 net user doesnotexist 2>&1 } catch [System.Management.Automation.RemoteException] { # catch the error emitted by the EXE, # and do what you want: $errmsg = $_.Exception.Message Write-Warning $errmsg } }
The construction & { [code] } creates a new scope, and any variable defined inside of it will be deleted again once the scope exits. This is why in above example, $ErrorActionPreference is automatically restored to whatever it was before.