Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Scaling the Active Directory Log Search with PowerShell

Posted on February 16, 2021February 16, 2021

Recently, I posted a demonstration of how to find changes to your Active Directory using PowerShell. This process requires that you search through the Security event log on all your domain controllers. As a few people pointed out, myself included, this has the potential to not scale very well in large environments. I still believe that if you have a large Active Directory infrastructure, that you should look for professional and enterprise-grade management tools. PowerShell is good for filling in the gaps or ad-hoc work.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

However, there is a way to scale my search function and that is to use PowerShell 7.x and take advantage of parallel processing with ForEach-Object. I think this is a great use case for this feature. There is overhead involved in spinning up runspaces, so you need to make sure that the task justifies the expense. In this case, I think it does. While you may not be querying a lot of domain controllers, the log files could be large. My admittedly limited testing bears this out.

The Traditional Approach

I'm going to use my Get-ADuserAudit function as it is. I am not making any changes to it. Here's how I might query multiple domain controllers. First, I'll define a list.

$dcs = "dom1","dom2","dom1","offline","dom2","dom1"

My test domain only has two domain controllers so I'll query them a few times. I also threw in a name that I know will fail. I need to dot source the script.

. C:\scripts\get-adlog.ps1

And now run it. I'm splatting a hashtable of parameter values to the function.

$get = @{
    DomainController = $dcs
    Since = "2/1/2021"
    Events = "Created","Deleted","Disabled"
}
$r = Get-ADUserAudit @get

The command found 15 results in about 24 seconds.

The PowerShell 7 Way

Now for PowerShell 7. I will use the same list of domain controllers with code like this:

$r = $dcs | foreach-object -Parallel {
  . C:\scripts\get-adlog.ps1
  $get = @{
    DomainController = $_
    Since = "2/1/2021"
    Events = "Created","Deleted","Disabled"
}
Get-ADUserAudit @get
}

The scriptblock is run in a separate runspace for each piped in object, which in this case is the name of a domain controller. In each runspace I'm dot sourcing the function since it is not part of a module and defining my parameter hashtable which is in turn splatted to Get-ADUserAudit.

This expression returned the same results but now in about 12 seconds. 12 vs 24 seconds on one hand isn't that big a deal. But I would expect this scale with more domain controllers and larger logs. Then 50% might really mean something. And with a large number of servers, you can also take advantage of throttling. I'm using the default of 5. You will have to test to see if there is any benefit to adjusting the throttle limit.

If you try out the Get-ADUserAudit function, especially with this technique, I'd love to hear about your experiences.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d