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"}
-----
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
January 30th, 2012 7:15pm
if (dsquery user -samid $user){"Found user"}
else {"Did not find user"}
January 30th, 2012 7:24pm
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.
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
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.
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"
}
}
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
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
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
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}
}
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)
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.
January 21st, 2014 12:57pm