New to powershell, learning it on the fly. I run a report weekly that requires me to get a list of names from my employer, specifically the first half of the userprincipalname attribute, check each associated account in AD, get account details, and save those details to a CSV that I later input into Excel.
My list is usually 5000 names long, and all the users are scattered in different OU's at different levels. What I originally used was the code below, but by narrowing my OU's down to my local office (OU=Level_1), I noticed it was fast, but only found users that are in Level 1 (about 80%) of the users, and omitted everyone else. I stopped specifying Level 1 and started at Level 2, and it ran much slower but found a few more. Starting at Level 3 found everyone, but takes now 4-5 seconds per $user in $users... several hours overall.
I ::think:: there is a way to make this faster by specifying if/else statements:
For every $user in $users, look in the Level_1 OU
if User is found, append Employee_Details.CSV, move to next $user
else look in the Level_2 OU
if User is found, append Employee_Details.CSV, move to next $user
else look in the Level_3 OU
if User is found, append Employee_Details.CSV, move to next $user
else look in the Level_4 OU
if User is not found, write-out "User Not Found"
EDIT: Josh below had a different way to do the same thing:
For every $user in $users, look in the Level_1 OU
if User is found, append Employee_Details.CSV
else send the user to a new array $Level_2.
For every $user in $Level_2, look in the Level_2 OU
if User is found, append Employee_Details.CSV,
else send the user to a new array $Level_3.
For every $user in $Level_3, look in the Level_2 OU
if User is found, append Employee_Details.CSV,
else send the user to a new array $Level_4.
Seem's to be a great way to do it so far, but not all the way there yet.
$users = (Import-csv C:\Users\mickey.mouse\Desktop\userprincipalname_List.txt).userprincipalname
$count = 0
$start = Get-Date
foreach ($user in $users) {
$count++
# calculate percent complete
$percentComplete = ($count / $users.Count) * 100
# Define parameters for Write-Progress
$progressParameters = @{
Activity = "Searching AD for userprincipalnames on list [$($count)/$($users.Count)] $($secondsElapsed.ToString('hh\:mm\:ss'))"
Status = 'Processing'
CurrentOperation = "Writing AD data for: $user to file"
PercentComplete = $percentComplete
}
# if we have an estimate for the time remaining, add it to the Write-Progress parameters
if ($secondsRemaining) {
$progressParameters.SecondsRemaining = $secondsRemaining
}
# Write the progress bar
Write-Progress @progressParameters
# Insert code to be performed in each iteration of the array here
Get-ADUser -searchbase "OU=Level_1,OU=Level_2,OU=Level_3,OU=Level_4,DC=Alpha,DC=Bravo,DC=Charlie" -Filter "userprincipalname -like '*$user*'" -properties * | select-object employeeid, name, title, mail, description, lastlogondate, userprincipalname |
Export-CSV C:\Users\mickey.mouse\Desktop\Employee_Details.csv -NoTypeInformation -append
# estimate the time remaining
$secondsElapsed = (Get-Date) – $start
$secondsRemaining = ($secondsElapsed.TotalSeconds / $count) * ($users.Count – $count)
}