I am writing a simple script that checks for a local user account. I would like to use the try_catch error to handle errors but I am not able to figure out why the catch block in my script won't print out the warning message in the script. Any guidance is appreciated.
function checkAccount($user)
{
try {
Get-CimInstance Win32_UserAccount| Where-Object -Property Name -Contains $user |Select-Object -ExpandProperty Name -ErrorAction Stop
}
catch {
Write-Warning -Message "Oops, ran into an issue"
}
}
CodePudding user response:
There are two commands that could report non-terminating errors in your pipeline -
Get-CimInstance
andSelect-Object
[1] - so you should use-ErrorAction Stop
with both.A simpler alternative is to set the
$ErrorActionPreference
preference variable to'Stop'
for your entire function:
function checkAccount($user)
{
# Make all errors in this scope (and descendant scopes) (script)-terminating,
# which enables them to be caught with try / catch.
$ErrorActionPreference = 'Stop'
try {
Get-CimInstance Win32_UserAccount |
Where-Object -Property Name -eq $user |
Select-Object -ExpandProperty Name
}
catch {
Write-Warning -Message "Oops, ran into an issue"
}
}
Also note that I've replaced -Contains
with -eq
, given that the -contains
operator is for testing if a collection contains a given value, whereas you're processing the user accounts one by one.
If, by contrast, your intent is to perform substring matching, use something -like *$user*
instead.
Caveat:
- Advanced (cmdlet-like) functions imported from script modules do not see preference variables, unless they happen to be defined in the global scope - see GitHub issue #4568 for a discussion of this problematic behavior.
If, by contrast, your intent was simply to test if a given user account exists, you could define your function as follows, using the approved verb Test
and - accordingly - making the function return a [bool]
value ($true
or $false
):
function Test-Account($user)
{
[bool] (
Get-CimInstance Win32_UserAccount |
Where-Object -Property Name -eq $user
)
}
The commands involved will not report errors under normal conditions, so there's no need for explicit error handling.
The
[bool]
cast takes advantage of PowerShell's to-Boolean conversion rules and the fact that a (non-primitive) object converts to$true
, whereas lack of output or$null
convert to$false
- see the bottom section of this answer for a summary of the conversion rules.
[1] Get-CimInstance
should normally only report an error for an invalid class name, and Select-Object -ExpandProperty
only for a non-existent property name (unlike with -Property
). The Where-Object
call should never report an error, given that it doesn't enforce the existence of the specified property (however, with invalid syntax any cmdlet call would report a statement-terminating error).