In this article, I describe how to check if an Active Directory user exists or not with the PowerShell cmdlet Get-ADUser, and show how to handle the quirks, such as the one that -ErrorAction Stop does not work, nor does setting $ErrorActionPreference = 'Stop', and using try {} catch {}.
The AD cmdlets are inconsistent with PowerShell standards in some ways. Missing -WhatIf support on critical cmdlets, "-Properties" instead of "-Property" (you're supposed to use the singular form; this is seen on other parameters as well here and there) , -ErrorAction doesn't behave as many expect, and possibly things I don't know about, to mention a few.This information is valid as per 2016-01-28, with 2008 R2 and 2012 R2 servers using the built-in Get-ADUser cmdlet. PowerShell versions 2, 3, 4, and 5.
I revisited this problem now on 2017-03-12 and, to my surprise, now the try/catch block works on 2012 R2 on a fresh install against a Server 2016 AD controller. The screenshot below, showing the failures, is from 2012 R2, but against a 2016 AD in the new lab, still on 2012 R2 (fresh install), it works. I'm not sure if the AD cmdlets have somehow been updated (I didn't think that was possible, but can it happen via Windows Update now??) or if it's because the AD controller itself is Server 2016.tl;dr:
[bool] (Get-ADUser -Filter { SamAccountName -eq $SomeSamAccountName })
It also demonstrates one of the successful verification methods I document more extensively below in this article.
Import-Module ActiveDirectory $SamAccountName = 'doesNotExist' try { $User = Get-ADUser -Filter { SamAccountName -eq $SamAccountName } -ErrorAction Stop } catch { Write-Warning -Message "User does not exist." }
Except it does not print the warning. Setting $ErrorActionPreference = 'Stop' does not work either. This is a bug/flaw with at least this AD cmdlet. I suppose the reason would be that it doesn't fail to execute the query, it just doesn't find the user.
These tests were performed on a 2012 R2 computer with PSv5 in January 2016. Now that it's March 2017, also see the new behavior.if (@(Get-ADUser -Filter { SamAccountName -eq $SamAccountName }).Count -eq 0) { Write-Warning -Message "User $SamAccountName does not exist." }
This works.
You can also simply cast what's returned to a [bool] type; that's a so-called boolean value that can either be true or false (respectively traditionally represented by the numbers 1 and 0).
$SamAccountName = 'doesnotexist' [bool] (Get-ADUser -Filter { SamAccountName -eq $SamAccountName }) # returns false $SamAccountName = 'joakimbs' [bool] (Get-ADUser -Filter { SamAccountName -eq $SamAccountName }) # returns trueSo you can check in an if statement (I also tossed in a foreach loop) like you see below. Remove the "-not" to invert the logic and check if a user exists.
foreach ($SamAccountName in 'doesNotExist', 'joakimbs') { if (-not [bool] (Get-ADUser -Filter { SamAccountName -eq $SamAccountName })) { Write-Warning -Message "User ${SamAccountName} does not exist." } }
Another example (PSv3 on Server 2008 R2):
PS C:\> $users = 'joakimbs', "blabla" PS C:\> $users | foreach { [bool] (Get-ADUser -Filter { SamAccountName -eq $_ } ) } True False
Image example of how you can now do it:
As text:
PS C:\temp> $UserList = @("DoesNotExist", "TestUser0001") foreach ($u in $UserList) { try { $ADUser = Get-ADUser -Identity $u -ErrorAction Stop } catch { if ($_ -like "*Cannot find an object with identity: '$u'*") { "User '$u' does not exist." } else { "An error occurred: $_" } continue } "User '$($ADUser.SamAccountName)' exists." # Do stuff with $ADUser } User 'DoesNotExist' does not exist. User 'testuser0001' exists. PS C:\temp>
I base my example on what I found here and have amended a few things based on the query to target only users that I looked up in my own wiki article here.
First I tried what Richard Mueller mentions, and did this:PS D:\> $SamAccountName = 'test'PS D:\> $Searcher = [adsisearcher] "(sAMAccountName=$SamAccountName)"
PS D:\> if (@($Searcher.FindOne()).Count -eq 1) { "$SamAccountName exists" } else { "$SamAccountName does not exist" } test exists PS D:\> get-aduser test get-aduser : Cannot find an object with identity: 'test' under: 'DC=ad,DC=example,DC=org'.
So "test" is found as a SAM account name, but is not an actual AD user object (another type of object, see below). Since the SAM account name is unique per AD, I suppose the distinction is not always needed between a user or other type of object, but if it is, here's how to verify it really is a '''user''':
# I was wondering what kind of object "test" is. PS D:\> (Get-ADObject -Filter { SamAccountName -eq 'test' }).ObjectClass group PS D:\> $SamAccountName = "test" PS D:\> $Searcher = [adsisearcher] "(&(objectCategory=Person)(objectClass=User)(sAMAccountName=$SamAccountName))" PS D:\> if (@($Searcher.FindOne()).Count -eq 1) { "$SamAccountName exists" } else { "$SamAccountName does not exist" } test does not exist
The only difference is in the LDAP query, where I added "(objectClass=user)", which targets users, and "(objectCategory=Person)", which filters out "contact" type AD objects that would otherwise be part of the results. You can use other LDAP queries that might be better than what I've been using.
Powershell Windows AD All CategoriesMinimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.