issue with looking up "auxiliary data" from AD

i have a power shell script that got brute forced into existence and, while it works, its deadly slow.
here is the relevant portion:
Import-Module ActiveDirectory
Set-Location ""

$OutFilePath = "Export.csv"
$Server = 'proper name inserted'
$collectionWithItems = @()

$userList = Import-Csv "Import.csv"

ForEach ($rec in $userList) {    
   
        $user = Get-ADUser -Identity $rec.'Accessed by' -Properties "*"
        $temp = New-Object System.Object
        $temp | Add-Member -MemberType NoteProperty -Name "Time" -Value $rec.'Time Accessed'
        $temp | Add-Member -MemberType NoteProperty -Name "Name" -Value $user.Name
        $temp | Add-Member -MemberType NoteProperty -Name "Username" -Value $user.SamAccountName
        $temp | Add-Member -MemberType NoteProperty -Name "Title" -Value $user.Title
        $temp | Add-Member -membertype noteproperty -name "Manager" -Value $user.Manager
        $temp | Add-Member -MemberType NoteProperty -Name "Description" -Value $user.Description
        $temp | Add-Member -MemberType NoteProperty -Name "Department" -Value $user.Department
        $temp | Add-Member -MemberType NoteProperty -Name "Office" -Value $user.Office
        $temp | Add-Member -MemberType NoteProperty -Name "File" -Value $rec.'File / Folder Name'
        $temp | Add-Member -MemberType NoteProperty -Name "Path" -Value $rec.'UNC Name'      
        $collectionWithItems += $temp
        }
           
$collectionWithItems |
Select-Object Time, Name,Username, Title, @{Label = "Manager";Expression = {%{(Get-AdUser $_.Manager -server $Server -Properties DisplayName).DisplayName}}},@{Label = "Mgr Phone";Expression = {%{(Get-AdUser $_.Manager -server $Server -Properties telephoneNumber).telephoneNumber}}},@{Label = "Mgr Email";Expression = {%{(Get-AdUser $_.Manager -server $Server -Properties mail).mail}}},Description, Department, Office,file, path  | Export-CSV -Path $OutFilePath -NoTypeInformation

 the original add-member portion was "provided" by a team mate and i didnt mess too much with it other than clean up some of the labels and real names of the fields.
i think my major issue is the bolded section. i can't figure out how to look up those 3 elements at one time as opposed to 3 lookups.

anybody have a clue to spare? im sure its as obvious as the sun at noon but i cant wrap hands around it
Steven KiergaardAsked:
Who is Participating?
 
oBdACommented:
The difference is the sorting, because it minimizes the user lookups, and there are probably a lot of entries from the same users. Since you didn't provide any information about the input data, I treated it conservatively.
Check how this performs:
Import-Module ActiveDirectory
Set-Location ""
$InFilePath = "Import.csv"
$OutFilePath = "Export.csv"
$Server = 'proper name inserted'

$managers = @{}
$user = $null
Import-Csv -Path $InFilePath | Sort-Object -Property 'Accessed by' | ForEach-Object {
	If ($user.SamAccountName -ne $_.'Accessed by') {
		Write-Debug "Processing new user $($_.'Accessed by')"
		$user = Get-ADUser -Identity $_.'Accessed by' -Properties Name, Title, Manager, Description, Department, Office -Server $server
		If ($user.Manager) {
			If ($managers.ContainsKey($user.Manager)) {
				$manager = $managers[$user.Manager]
			} Else {
				$manager = Get-ADUser -Identity $user.Manager -Properties DisplayName, telephoneNumber, mail -Server $server
				$managers[$user.Manager] = $user.Manager
			}
		} Else {
			$manager = $null
		}
	}
	$_ | Select-Object -Property `
		@{n='Time';			e={$_.'Time Accessed'}},
		@{n='Name';			e={$user.Name}},
		@{n='Username';		e={$user.SamAccountName}},
		@{n='Title';		e={$user.Title}},
		@{n='Manager';		e={$manager.DisplayName}},
		@{n='Mgr Phone';	e={$manager.telephoneNumber}},
		@{n='Mgr Email';	e={$manager.mail}},
		@{n='Description';	e={$user.Description}},
		@{n='Department';	e={$user.Department}},
		@{n='Office';		e={$user.Office}},
		@{n='File';			e={$_.'File / Folder Name'}},
		@{n='Path';			e={$_.'UNC Name'}}
} | Sort-Object -Property Path, Name | Export-CSV -Path $OutFilePath -NoTypeInformation

Open in new window

0
 
oBdACommented:
It's not only the three separate Get-ADUser commands - Add-Member is very slow as well.
Then never tell Get-ADUser to retrieve all AD properties if you're throwing away most of them anyway.
And you specified a server to get the manager information, but not the user information.
This is utterly untested, but should work:
Import-Module ActiveDirectory
Set-Location ""
$InFilePath = "Import.csv"
$OutFilePath = "Export.csv"
$Server = 'proper name inserted'

Import-Csv -Path $InFilePath | ForEach-Object {
	$user = Get-ADUser -Identity $_.'Accessed by' -Properties Name, Title, Manager, Description, Department, Office -Server $server
	$manager = Get-ADUser -Identity $user.Manager -Properties DisplayName, telephoneNumber, mail -Server $server
	$_ | Select-Object -Property `
		@{n='Time';			e={$_.'Time Accessed'}},
		@{n='Name';			e={$user.Name}},
		@{n='Username';		e={$user.SamAccountName}},
		@{n='Title';		e={$user.Title}},
		@{n='Manager';		e={$manager.DisplayName}},
		@{n='Mgr Phone';	e={$manager.telephoneNumber}},
		@{n='Mgr Email';	e={$manager.mail}},
		@{n='Description';	e={$user.Description}},
		@{n='Department';	e={$user.Department}},
		@{n='Office';		e={$user.Office}},
		@{n='File';			e={$_.'File / Folder Name'}},
		@{n='Path';			e={$_.'UNC Name'}}
} | Export-CSV -Path $OutFilePath -NoTypeInformation

Open in new window

0
 
Steven KiergaardAuthor Commented:
thanks for the input. I'll give it a try as soon as I can.
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

 
Steven KiergaardAuthor Commented:
your technique and script work better than my original but still takes 53 minutes to process 44000 lines of input.
in the interim, a teammate of mine helped me cobble this togather which processes the file in 5 minutes!
i really appreciate the feedback! here is my "improved" script in the event it helps others:
Clear-Host

Import-Module ActiveDirectory
Set-Location ""

$OutFilePath = "Export.csv"
$Server = 'domain name'
$collectionWithItems = @()

$userList = Import-Csv "Import.csv" | Sort-Object "Accessed by"
$manager = $null

ForEach ($rec in $userList) {    
        if ($user.SamAccountName -ne $rec.'Accessed by'){
            $user = Get-ADUser -Identity $rec.'Accessed by' -Properties "*"
            Write-Debug "Get new AD Object $($user.samAccountName)"
        }
        $temp = New-Object System.Object
        $temp | Add-Member -MemberType NoteProperty -Name "Time" -Value $rec.'Time Accessed'
        $temp | Add-Member -MemberType NoteProperty -Name "Name" -Value $user.Name
        $temp | Add-Member -MemberType NoteProperty -Name "Username" -Value $user.SamAccountName
        $temp | Add-Member -MemberType NoteProperty -Name "Title" -Value $user.Title
        if ($user.Manager -ne $null){
            if ($user.Manager -ne $manager.DistinguishedName){
                $manager = Get-ADUser -Identity $user.Manager -Properties DisplayName, telephoneNumber, mail
                Write-Debug "Getting New Manager $($manager.SamAccountName) AD Object"
            }
           
            $temp | Add-Member -membertype noteproperty -name "Manager" -Value $manager.DisplayName
            $temp | Add-Member -membertype noteproperty -name "Mgr Phone" -Value $manager.telephoneNumber
            $temp | Add-Member -membertype noteproperty -name "Mgr Email" -Value $manager.mail
        }
       
        $temp | Add-Member -MemberType NoteProperty -Name "Description" -Value $user.Description
        $temp | Add-Member -MemberType NoteProperty -Name "Department" -Value $user.Department
        $temp | Add-Member -MemberType NoteProperty -Name "Office" -Value $user.Office
        $temp | Add-Member -MemberType NoteProperty -Name "File" -Value $rec.'File / Folder Name'
        $temp | Add-Member -MemberType NoteProperty -Name "Path" -Value $rec.'UNC Name'      
        $collectionWithItems += $temp
        Write-Debug "Current Record: $($user.name)"
        }
           
$collectionWithItems |
Select-Object Time, Name, Username, Title, Manager, "Mgr Phone", "Mgr Email", Description, Department, Office, file, path | Sort-Object path, Name  | Export-CSV -Path $OutFilePath -NoTypeInformation

if anyone can explain the extreme difference in performance, im all ears.
0
 
Steven KiergaardAuthor Commented:
your update ran 57000 lines in 4 minutes! thank you very very much!
0
 
Steven KiergaardAuthor Commented:
Your update ran 57000 lines in 4 minutes! Thank you very very much! I learned quite a bit. now lets see if I can retain it. (is there a script for that?  ;->  )
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.