Us a script cache to speed up repetitive directory lookups

In an Active Directory environment there will be many instances where you’ll be doing report scripting that will involve repetitive resolution of identity references. To demonstrate, I’ll bring back the unused vacation notification script from a previous post on splatting parameters:

Param (
$ImportFile     =  './user_vacation_list.csv',
$EmailFrom      =  'HR@mycompany.com',
$EmailSubject   =  'Unused vacation reminder',
$SMTPServer     =  'mail.mycompany.com'
)

$AllEmailParams =
        @{
          From       = $EmailFrom
          Subject    = $EmailSubject
          SMTPServer = $SMTPServer
          }

Foreach ($User in inport-csv $ImportFile)
 {
   $ADUser = Get-ADUser $User.Name -Propertes Mail,Manager
   $Manager = Get-ADUser $User.Manager -Properties Mail

   $ThisEmailParams = 
        @{
          To   = $ADUser.Mail
          Cc   = $Manager.Mail
          Body = "You have $($User.VacationDays) unused vacation days."
         }

 Send-MailMessage @AllEmailParams @ThisEmailParams
 }

Now, in most any organization this script can easily result in having to look up the email address for the same manager many times, since there will be relatively few managers compared to the number of employees, and multiple employees having the same manager. We can speed up our script and reduce the load on our DC's by creating an in-script cache of manager email addresses we've already looked up, so we don't have to keep doing it over and over again.


Param (
$ImportFile     =  './user_vacation_list.csv',
$EmailFrom      =  'HR@mycompany.com',
$EmailSubject   =  'Unused vacation reminder',
$SMTPServer     =  'mail.mycompany.com'
)
 
$AllEmailParams =
        @{
          From       = $EmailFrom
          Subject    = $EmailSubject
          SMTPServer = $SMTPServer
          }

#Create an empty hash table for the cache
$Manager = @{} 
 
Foreach ($User in inport-csv $ImportFile)
 {
   $ADUser = Get-ADUser $User.Name -Propertes Mail,Manager

   #Check to see if the entry we want is already in cache, if not add it.
   if ($Manager[$ADUser.Manager] -eq $null)
     {
       $Manager[$ADUser.Manager] = 
        (Get-ADUser $User.Manager -Properties Mail).Mail
     }
   
   #Use the identity reference to get the entry from cache.
   $ThisEmailParams = 
        @{
          To   = $ADUser.Mail
          Cc   = $Manager[$ADUser.Manager]
          Body = "You have $($User.VacationDays) unused vacation days."
         }
 
 Send-MailMessage @AllEmailParams @ThisEmailParams
 }

By using the hash table created ahead of entering the processing loop:


#Create an empty hash table for the cache
$Manager = @{} 

We can test that to see if we already have an entry cached for this manager. If we don’t have it yet, we’ll go ahead and do that lookup and add it to our cache:

if ($Manager[$ADUser.Manager] -eq $null)
     {
       $Manager[$ADUser.Manager] = 
        (Get-ADUser $User.Manager -Properties Mail).Mail
     }

Then use the cache reference to get our manager’s email address

$ThisEmailParams = 
        @{
          To   = $ADUser.Mail
          Cc   = $Manager[$ADUser.Manager]
          Body = "You have $($User.VacationDays) unused vacation days."
         }

Now we only go to our DC once for each manager the first time we encounter a user with that manager in our input data, and for every subsequent user with that same manager we just retrieve it from our hash table.

Reporting scripts will frequently be focused on a particular group or type of objects in the directory and associations between them are linked by an identity reference in AD (DN, SID, guid) you’ll find many instances where you will end up having to resolve the same identity references and retrieve the same information for that object over and over again, and using a cache of already resolved indentities and data can both speed up your script and reduce the impact on your critical infrastructure servers.

Advertisements

2 responses to “Us a script cache to speed up repetitive directory lookups

  1. Your Blog Sir is a treat to read.

    Regards

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s