Reputation: 2149
As part of my job i'm constantly auditing active directory for given properties of cross domain accounts.
I've constructed a powershell script to output information to a CSV based on properties given to the script. This is fine, the script works beautifully for a small list of people however i'm noticing that the script slows down considerably when i provide a big list of users to audit.
This is the script:
$inputfile = "C:\Powershell\input.txt"
$users = Get-Content $inputfile
$audit = Read-Host "Audit Name"
$csv = ".\output\Audit\$audit.csv"
$failed = @()
$serv = @("server1", "server2", "server3")
if((Test-Path $csv) -eq $true){Remove-Item $csv}
foreach($domain in $serv)
{
$count = $users.Count
for( $i=0; $i -le $count - 1; $i++ )
{
if (($users.Get($i)) -ne "")
{
try
{
Write-Host "Checking for $($users.get($i)) on" -NoNewline
switch($domain)
{ # with fancier text for which domain we're searching
"server1" {write-host "...Server1" -ForegroundColor Cyan -NoNewline; $domainCsv = "Server1"}
"server2" {Write-Host "...Server2" -ForegroundColor White -NoNewline; $domainCsv = "Server2"}
"server3" {Write-Host "...Server3" -ForegroundColor Magenta -NoNewline; $domainCsv = "Server3"}
}
$usr = Get-ADUser -Identity $users.get($i) -Properties $properties -Server $domain | ? { ($_.distinguishedname -notlike '*Suspended*')}
if ($usr -ne $null)
{
$usr = Get-ADUser -Identity $users.get($i) -Properties $properties -Server $domain | ? { ($_.distinguishedname -notlike '*Deletion*')}
if ($usr -ne $null)
{
Write-Host "...Found" -ForegroundColor Green
$userobj = New-Object PSObject
Add-Member -InputObject $userobj -MemberType NoteProperty -Name "User" -Value $($users.Get($i))
Add-Member -InputObject $userobj -MemberType NoteProperty -Name "Domain" -Value $domainCsv
foreach($prop in $properties) {$userobj | Add-Member -MemberType NoteProperty -Name $prop -Value "$($usr.$prop)"}
$userobj | Export-Csv $csv -Append -NoTypeInformation
}
else
{
Write-Host "...Pending Delete" -ForegroundColor Red
$failed += "$($users.Get($i)),Pending deletion on $domainCsv"
}
}
else
{
Write-Host "...Suspended" -ForegroundColor Red
$failed += "$($users.Get($i)),Suspended on $domainCsv"
}
}
catch [System.Exception]
{
Write-Host "...Not found" -ForegroundColor Red
$failed += "$($users.Get($i)),Could not find on $domainCsv"
} # </Try
} # </If user ""
} # </For users
} # </For Domains
Add-Content $csv ""
Add-Content $csv "Those who failed, (Not found or Suspended or Pending deletion)"
Add-Content $csv ""
Add-Content $csv "User,Domain"
foreach($fail in $failed) {Add-Content $csv $fail}
Write-Host " "
Write-Host " Audit saved to $csv" -ForegroundColor Green
What the script does
Gets input file full of users (one name per line) (mostly 20 or so lines but sometimes the input file has been over 200)
user1
user2
user3
user4
user5
goes through each domain
checks if they're in an OU for suspended accounts
checks if they're in an OU for accounts pending deletion
if not in either OU grabs the information and puts it into a PSObject for insertion into a CSV
after its done it lists the accounts it couldnt find or were in an OU that i dont need to worry about.
As i'm quite new to powershell i have no idea if theres a way i can condense parts of the code to be quicker, i have read a few pages on optimizing powershell but the only change i could see was to change
for( $i=0; $i -le $users.count - 1; $i++ )
to
$count = $users.count
for( $i=0; $i -le $count - 1; $i++ )
My question is: How can i improve my script to loop faster when given more users?
Upvotes: 2
Views: 933
Reputation: 72630
As far as I understand your script spent most of the time in Get-ADUser
. You call it twice with the same parameters, using $usr you should call it just one time, your script execution time should bedevided by two.
Another thing, I can't find the defenition of $properties
in your script, reducing this list can also reduce the network payload.
Test something like this.
$usr = Get-ADUser -Identity $users.get($i) -Properties $properties -Server $domain | ? { ($_.distinguishedname -notlike '*Suspended*')}
if ($usr.distinguishedname -notlike '*Suspended*')
{
if ($usr.distinguishedname -notlike '*Deletion*')
{
Upvotes: 1