MarcGel
MarcGel

Reputation: 301

Trying to find a way to speed up this powershell script

I have this script that works fine (output looks good), but it is taking longer than 12 hours now. There are 34220 records in the csv and it's only now on 2110. Maybe I need to load up all the user data first, then compare to the csv file? Thx for help...

import-module ActiveDirectory

$CCure = Import-csv C:\Scripts\CCure\CCure-Personnel-enabled.csv 

ForEach ($Row in $CCure) {
    [string]$ID = $Row.ObjectID
    [string]$Name = $Row.Name
    [string]$EmpID = $Row.Int5

    If ($EmpID.Trim() -ne "0") {
    $User = Get-ADUser -LDAPFilter "(&(&(&(objectclass=user)(objectcategory=person)(!userAccountControl:1.2.840.113556.1.4.803:=2))))((employeeId=*$EmpID))" -SearchBase 'DC=Enterprise,DC=mycompany,DC=org' -Properties SamAccountName,DisplayName,EmployeeId,enabled  | 
    Select @{Name="CCure ObjectID";Expression={$ID}},SamAccountName,DisplayName,@{Name="CCure Name";Expression={$Name}},EmployeeId,@{Name="CCure Int5 Row";Expression={$EmpID}},enabled | Export-csv c:\scripts\ccure\EmployeeIds4-10-2016.csv -NoTypeInformation -append

    }
    }

Upvotes: 1

Views: 111

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174990

Maybe I need to load up all the user data first, then compare to the csv file?

That's exactly what you need to do!

Since you want to correlate the users in the CSV by the EmployeeId attribute, I'd recommend pulling out all the (enabled) users that have the EmployeeId populated, and then store them in a hashtable where the EmployeeId is used as the key:

$ADUserTable = @{}
Get-ADUser -LDAPFilter "(&(!userAccountControl:1.2.840.113556.1.4.803:=2)(employeeId=*))' -SearchBase 'DC=Enterprise,DC=mycompany,DC=org' -Properties SamAccountName,DisplayName,EmployeeId |ForEach-Object {
    $ADUserTable[$_.EmployeeId] = $_
}

Then, as you iterate over the rows in the CSV, lookup the user in the hashtable instead of searching AD again:

$ExistingUsers = ForEach ($Row in $CCure) {
    # Import-Csv always creates string properties anyways
    $ID = $Row.ObjectID
    $Name = $Row.Name
    $EmpID = $Row.Int5.Trim()

    if ($EmpID -ne "0" -and $ADUserTable.ContainsKeys($EmpID)) 
    {
        $ADUserTable[$EmpID] |Select @{Name="CCure ObjectID";Expression={$ID}},SamAccountName,DisplayName,@{Name="CCure Name";Expression={$Name}},EmployeeId,@{Name="CCure Int5 Row";Expression={$EmpID}}
    }
}

Do NOT export them to Csv until AFTER you've collected all the information - otherwise you're opening, writing to and closing the same file 35000 times!

So, at the very end:

$ExistingUsers |Export-csv c:\scripts\ccure\EmployeeIds4-10-2016.csv -NoTypeInformation

This will undoubtedly speed up execution of your script


Note: I've removed the Enabled property from Get-ADUser and Select-Object. Your LDAP Filter already guarantees that only Enabled users are returned, so I don't really see any value in adding it to the CSV

Upvotes: 2

Related Questions