Use Powershell to check whether and AD user exists

We're trying to clean up roaming profile folders, and as part of the task I need to check whether the user actually exists in AD.  I have tried 3 different methods and so far none of them work.

Either the empty result of the search doesn't equal $null (e.g. If ($objUser -eq $null) resolves to false) or Powershell crashes (like when I try to run that If statement).  So is there an AD User equivalent to Test-Path?

RF

January 28th, 2012 1:18am

In PowerShell V2 I would use something similar to below:

 

$Name = "jsmith"
$User = Get-ADUser -LDAPFilter "(sAMAccountName=$Name)"
If ($User -eq $Null) {"User does not exist in AD"}
Else {"User found in AD"}

-----

 

Free Windows Admin Tool Kit Click here and download it now
January 28th, 2012 1:46am

I should add, if you want to use PowerShell filter syntax, you can use:

 

$Name = "jsmith"
$User = Get-ADUser -Filter {sAMAccountName -eq $Name}
If ($User -eq $Null) {"User does not exist in AD"}
Else {"User found in AD"}

-----

 

And if you only have PowerShell V1, you can use the following:

 

$Name = "jsmith"
$Searcher = [ADSISearcher]"(sAMAccountName=$Name)"
$Results = $Searcher.FindOne()
If ($Results -eq $Null) {"Users does not exist in AD"}
Else {"User found in AD"}

-----

 

In all cases I assume you are checking the "pre-Windows 2000 logon" name, not the Common Name (the value of the cn attribute, which does not uniquely identify the object in AD).

 

January 28th, 2012 4:29am

Thanks for the quick replies.  Now on the 2003 server where I need to run the script, Get-Aduser and Get-ADdomainController don't appear to exist (not a recognized cmdlet).  (I checked: it's Powershell 2.0)

On my workstation (Windows 7) both cmdlets exist.  Get-ADdomainController works, but Get-ADuser still says it can't find a domain controller.  And I can't find any way to relate the 2 cmdlets.

Last, of course, is the problem so far is in this line:

If ($User -eq $Null) {"User does not exist in AD"}

A user that doesn't exist does not actually -eq $null.

RF

Free Windows Admin Tool Kit Click here and download it now
January 30th, 2012 7:15pm

if (dsquery user -samid $user){"Found user"}

else {"Did not find user"}

January 30th, 2012 7:24pm

http://jrich523.wordpress.com/2011/06/01/methods-for-working-with-active-directory-in-powershell/   thats a good place to get started and help asking for solutions   in your case you could use ADSI   $searcher = [adsisearcher]"(samaccountname=$name)" $rtn = $searcher.findall()   if($rtn.count -gt 0) { "found"} else {"not found"}    
Free Windows Admin Tool Kit Click here and download it now
January 30th, 2012 8:29pm

This one worked:

if (dsquery user -samid $user){"Found user"}

else {"Did not find user"}

January 30th, 2012 11:24pm

$a =(dsquery user -samid $user)
 if ($a -eq $null) {"It does not exist"} else {"Account already exists"}

Kind of late for this answer but here it goes, by doing it this way you are verifying that the user exists,  you store it in variable $a then confirm that it is not $null or blank.  This is good for when you create new accounts and if the user already exists then you can stop the script.

Free Windows Admin Tool Kit Click here and download it now
August 23rd, 2012 6:39am

while we are proposing solutions that use facilities outside of powershell (like dsquery) here is another possibility:

net user /domain $samid

August 23rd, 2012 8:00am

I was looking for a similar script and settled for the below.

# Script to check if a user from a txt file exists in a domain.  Txt file uses samaccount with no header.
Clear
Import-CSV "C:\CSV Files\Users.txt" -header ("UserName") | % {
  $UserN = $_.UserName
  $ObjFilter = "(&(objectCategory=person)(objectCategory=User)(samaccountname=$UserN))"
  $User = Get-ADUser -Filter {sAMAccountName -eq $UserN}
$objSearch = New-Object System.DirectoryServices.DirectorySearcher
$objSearch.Filter = $ObjFilter  
$objSearch.SearchRoot = "LDAP://ou=Remove this if you dont want only users in a OU returned,dc=Domain,dc=co,dc=uk"
$AllObj = $objSearch.findOne()
$user = [ADSI] $AllObj.path
$ErrorActionPreference = "silentlycontinue"
If ($User -eq $Null) {Write-host "Domain\$UserN does not exist in AD"}
Else {Write-host "Domain\$UserN found in AD"}
}
  • Edited by GB786 Thursday, September 13, 2012 12:19 PM
Free Windows Admin Tool Kit Click here and download it now
September 13th, 2012 1:18pm

@GB786: Just a few notes on your script -

1. One doesn't normally include the -Header parameter for a regular csv file.  You would just use the field names from the csv.

2. You can use the ADSI accellerator:

$as = [adsisearcher]"(&(objectCategory=person)(objectCategory=User)(samaccountname=$UserN))" 

From there on, you simply need to call the method $as.FindOne().

3. You don't need to set the pagesize because you are only retrieving one object.

September 13th, 2012 1:32pm

@GB786: Just a few notes on your script -

1. One doesn't normally include the -Header parameter for a regular csv file.  You would just use the field names from the csv.

2. You can use the ADSI accellerator:

$as = [adsisearcher]"(&(objectCategory=person)(objectCategory=User)(samaccountname=$UserN))" 

From there on, you simply need to call the method $as.FindOne().

3. You don't need to set the pagesize because you are only retrieving one object.

Free Windows Admin Tool Kit Click here and download it now
September 13th, 2012 3:21pm

You specify the filter as the constructor for the accellerator:

$as = [adsisearcher]"(&(objectCategory=person)(objectCategory=User)(samaccountname=$UserN))"

$as.FindOne()

That's all you need.  In fact you don't need all that other stuff either.  All you do is:

if ($as.FindOne()) { "User exists" }

September 13th, 2012 3:25pm

I'm not getting why all the adsi bits are necessary at all. 

   This line:

 $User = Get-ADUser -Filter {sAMAccountName -eq $UserN}

implicitly says the AD module is installed, so:

get-content "C:\CSV Files\Users.txt" |
 foreach {
             if (Get-ADUser -Filter {sAMAccountName -eq $_}){
                 Write-Host ""Domain\$UserN found in AD"}
              else {
                   Write-host "Domain\$UserN does not exist in AD"
                   }
 }

Free Windows Admin Tool Kit Click here and download it now
September 13th, 2012 3:56pm

You'd need to put that in a Try/Catch thingy, remember.  If Get-AdUser fails, it throws a terminating error.
September 13th, 2012 3:59pm

Get-ADuser <user>

 will throw a terminating error if it doesn't find anything.

Get-ADUser -filter {sAMAccountName -eq <user>}
Will simply return null if it doesn't find anything
Free Windows Admin Tool Kit Click here and download it now
September 13th, 2012 4:02pm

Get-ADuser <user>

 will throw a terminating error if it doesn't find anything.

Get-ADUser -filter {sAMAccountName -eq <user>}
Will simply return null if it doesn't find any
September 13th, 2012 4:07pm

I appreciate all the suggestions, but as I said above, I tried about 4 versions of checking for a null or an error when retrieving the user object.  None of them worked - at least none of them worked consistently.

mjolinor's suggestion worked:

if (dsquery user -samid $username)

Thanks

RF

Free Windows Admin Tool Kit Click here and download it now
September 13th, 2012 6:07pm

Mjolinor,

I owe you a beer.  Thanks for the answer on this one.

Mr Mister

October 2nd, 2012 5:57am

The dsquery method works perfectly fine, however I would like to point out that it will take about half a second per user to run this check.  If you have a small data set, this won't matter.  However, if you need to check 1,000+ users, it could get slow.

As an alternative, I would suggest using the System.Security.Principal namespace.  The code below should work much faster

Function VerifyAccount {
    Param ([Parameter(Mandatory=$true)][System.String]$userName, [System.String]$domain = $null)
        
    $idrefUser = $null
    $strUsername = $userName
    If ($domain) {
        $strUsername += [String]("@" + $domain)
    }
        
    Try {
        $idrefUser = ([System.Security.Principal.NTAccount]($strUsername)).Translate([System.Security.Principal.SecurityIdentifier])
    }
    catch [System.Security.Principal.IdentityNotMappedException] {
        $idrefUser = $null
    }
           
    If ($idrefUser) {
        return $true
    }
    Else {
        return $false
    }
}

One thing to note; if the domain parameter is omitted, this function will return true if the user exists in the current or any trusted domain.  If you want to limit the scope to just one domain, then make sure to specify that domain as the second parameter.

This code should work with Powershell v2 (and later) without any extensions.


  • Edited by Mike at WFU Friday, April 19, 2013 6:46 PM grammar
Free Windows Admin Tool Kit Click here and download it now
April 19th, 2013 9:40pm

The dsquery method works perfectly fine, however I would like to point out that it will take about half a second per user to run this check.  If you have a small data set, this won't matter.  However, if you need to check 1,000+ users, it could get slow.

As an alternative, I would suggest using the System.Security.Principal namespace.  The code below should work much faster

Function VerifyAccount {
    Param ([Parameter(Mandatory=$true)][System.String]$userName, [System.String]$domain = $null)
        
    $idrefUser = $null
    $strUsername = $userName
    If ($domain) {
        $strUsername += [String]("@" + $domain)
    }
        
    Try {
        $idrefUser = ([System.Security.Principal.NTAccount]($strUsername)).Translate([System.Security.Principal.SecurityIdentifier])
    }
    catch [System.Security.Principal.IdentityNotMappedException] {
        $idrefUser = $null
    }
           
    If ($idrefUser) {
        return $true
    }
    Else {
        return $false
    }
}

One thing to note; if the domain parameter is omitted, this function will return true if the user exists in the current or any trusted domain.  If you want to limit the scope to just one domain, then make sure to specify that domain as the second parameter.

This code should work with Powershell v2 (and later) without any extensions.



Nice, I like it because it doesn't require any AD tools to be installed.
September 4th, 2013 9:35pm

Use this below script , update GC://DC=my,DC=Domain,DC=COM"   with the top level domain name.

If want to check for specific domain then replace GC with LDAP and provide the domain name

Import-CSV "C:\temp\Userinput.txt" -header ("UserName") | % {
$UserN = $_.UserName
$ObjFilter = "(&(objectCategory=person)(objectCategory=User)(samaccountname=$UserN))"
$User = [ADSISearcher]"(sAMAccountName=$Name)"
$objSearch = New-Object System.DirectoryServices.DirectorySearcher
$objSearch.Filter = $ObjFilter
$objSearch.SearchRoot = "GC://DC=my,DC=Domain,DC=COM"
$AllObj = $objSearch.findOne()
$user = [ADSI] $AllObj.path
$ErrorActionPreference = "silentlycontinue"
If ($User -eq $Null)

{Write-host "$UserN not found in AD"

Write "$UserN not found in AD" | Out-File C:\temp\Outputfile.txt -Append}

Else
{Write-host "$UserN is found in AD"
Write "$UserN is found in AD" | Out-File C:\temp\Outputfile.txt -Append}
}

Free Windows Admin Tool Kit Click here and download it now
September 23rd, 2013 6:58pm

Hello..

I don't know if anybody is still interested.

I took Richard Mueller script and modify it a little

#####################################################################

#Create a txt file with the usernames inside in c:\userstatus\ named users.txt

$user = get-content C:\userstatus\users.txt
$user | foreach {
$Name = "$_"
 $Searcher = [ADSISearcher]"(sAMAccountName=$Name)"
 $Results = $Searcher.FindOne()
 If ($Results -eq $Null) {"$Name not in AD" >> C:\userstatus\userstatus.txt}
 Else {
 $status = (get-aduser $Name).enabled
 if ($status -eq "True"){
 
 "$Name is Enabled" >> C:\userstatus\userstatus.txt}
 else{
 "$Name is Disabled" >> C:\userstatus\userstatus.txt}
 }}

#If you want to check only enabled accounts delete the "#" below

 #get-content C:\userstatus\userstatus.txt | select-string "is Enabled" >> C:\userstatus\userstatus_enabled.txt

#If you want to check only disabled accounts delete the "#" below

get-content C:\userstatus\userstatus.txt | select-string "is Disabled" >> C:\userstatus\userstatus_disabled.txt

#If you want to check only accounts not in AD delete the "#" below

get-content C:\userstatus\userstatus.txt | select-string "not in AD" >> C:\userstatus\userstatus_notinAD.txt

######################################################################



  • Edited by Cornel.Ghisoiu Wednesday, November 20, 2013 12:04 PM small mistake in the script
November 19th, 2013 4:20pm

For bulk users.

Import-module activedirectory
$users = get-content c:\users.txt
foreach ($user in $users) {
$User = Get-ADUser -Filter {(samaccountname -eq $user)}
If ($user -eq $Null) {"User does not exist in AD ($user)" }
Else {"User found in AD ($user)"}
}

Here is the output

User found in AD (CN=bbiswajit,OU=win7,DC=Jaihanuman,DC=net)
User found in AD (CN=test1,OU=win7,DC=Jaihanuman,DC=net)
User found in AD (CN=test2,OU=win7,DC=Jaihanuman,DC=net)
User found in AD (CN=Administrator,CN=Users,DC=Jaihanuman,DC=net)
User does not exist in AD ()
User found in AD (CN=test3,OU=win7,DC=Jaihanuman,DC=net)
User found in AD (CN=Biswajit Biswas,OU=win7,DC=Jaihanuman,DC=net)
User found in AD (CN=tak alu,OU=win7,DC=Jaihanuman,DC=net)

Free Windows Admin Tool Kit Click here and download it now
December 5th, 2013 3:20pm

Cornel,

This is an excellent script and has help tremendously with samaccountname found in one domain and check the samaccountname status in another domain.

Here is my problem.

I have looked everywhere trying to locate a script that I can import the sam accountnames that were exported into enable and disable and have that script export the pwlastset, and lastlogontimestamp. Would it be possible to modify this script and deliver those attributes in the enabled and disabled csv file. Thank you for your time and contributions.

December 18th, 2013 11:04pm

Hello Collins.

I am not shure if I understand correct. I am not an fluent english speaker.

If you would like to export all the enabled users into one file and the disabled users in another, you can just modify the following

get-content C:\userstatus\userstatus.txt | select-string "is Enabled" >> C:\userstatus\enabled.csv

get-content C:\userstatus\userstatus.txt | select-string "is Disabled" >> C:\userstatus\disabled.csv

The lines are already in the script, you should just uncomment them if it is commented.

I hope this helps.

Have a nice day.

Free Windows Admin Tool Kit Click here and download it now
January 21st, 2014 12:57pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics