Active Directory Powershell - whole forest script search using .csv user list
I'm looking for a little help, hope no one will bash me for being clueless. Not so long ago I became something of an AD administrator, the organization is large, so the tasks are different. Most of the time I can easily accomplish what I need with Powershell or a snap. However, I have a task on my hands that surpasses my "creativity". I have a list of over 10,000 users in .csv that I need to look for in my local AD if they exist. My two problems: -I am very new to scripting and increasingly frustrated that I cannot figure this out and get my scripts to work the way I need them. -Delivery for this task and other responsibilities give me a little time to learn more about scripting basics and learn.Therefore, in most cases I am forced to search for script fragments on the Internet and modify them a little to suit my needs. This has worked so far as the script I have in my hands is too complex for me.
The biggest problem I've faced so far is finding the forest as a whole. My organization has one root domain and 4 child domains. When running a simple foreach loop like below:
ForEach ($User in (Import-Csv c:\users\public\users.csv))
{ If (Get-ADUser $User.mail -server GLOBALCATALOGADDRESS:xxxx)
{ Write-Host "User found: $($User.mail)"
}
Else
{ Write-Host "User not found: $($User.mail)"
}
}
It only looks for the domain my computer is connected to. So I was able to find and modify a forest-wide search script and came up with the following:
#Get Domain List
$objForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$DomainList = @($objForest.Domains | Select-Object Name)
$Domains = $DomainList | foreach {$_.Name}
$User = Import-CSV c:\users\public\users.csv
#Act on each domain
foreach($Domain in ($Domains))
{
Write-Host "Checking $Domain" -fore red
$ADsPath = [ADSI]"LDAP://$Domain"
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher($ADsPath)
#The filter
Foreach($mail in($User))
{
$objSearcher.Filter = "(&(objectCategory=user)(mail=$User.mail))"
$objSearcher.SearchScope = "Subtree"
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
{
$objArray = $objResult.GetDirectoryEntry()
write-host $objArray.mail
}
}
}
The script seems to be good in its original form (here: http://powershell.nicoh.me/powershell-1/active-directory/forest-wide-object-searches ) and works well with wildcards and one parameter as a filter. However, I have no idea what I am missing so that it searches every email address I have .csv and that it returns information about whether a user with such a mail was found. The script runs itself, but given the time it takes and the empty output, it looks like it is looking for just one user. I'm 100% sure that at least one user on the list exists in on-prem AD. Any suggestions are greatly appreciated. Thanks for your attention.
[EDIT] Final script:
#Get Domain List and load user e-mails from file
$objForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$DomainList = @($objForest.Domains | Select-Object Name)
$Domains = $DomainList | foreach {$_.Name}
$Users = Import-CSV c:\users\public\users.csv
#Act on each domain
foreach($Domain in ($Domains))
{
Write-Host "Checking $Domain" -fore red
Foreach($mail in ($Users.mail))
{
Get-ADUser -filter {mail -eq $mail} -Server $domain -properties mail | select mail
}
}
source to share
Do yourself a favor and download the AD Powershell module: http://blogs.msdn.com/b/rkramesh/archive/2012/01/17/how-to-add-active-directory-module-in-powershell-in-windows -7.aspx
Then you can simplify your code and run things like this, making the task clearer:
... foreach($Domain in ($Domains)) { Write-Host "Checking $Domain" -fore red Foreach($mail in ($User.mail)) { Get-ADUser -filter {mail -eq $mail} -Server $domain -Properties mail | select-object -ExpandProperty mail } } ...
More on AD PS cmdlets: http://technet.microsoft.com/en-us/library/ee617195.aspx
source to share