I’ve set up this script to grab inactive accounts in our AD(s). And it works as intended but I’d like to refine it a bit.
#Requires -version 5.1
#Requires -Modules ActiveDirectory
[CmdLetBinding()]
Param (
[Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ValidateSet('AD01','AD02','AD03','AD04')]
[string]$AD = 'AD01',
[Parameter(Mandatory = $false, ValueFromPipeline = $false)]
[int]$InactiveDays = 365,
[Parameter(Mandatory = $false, ValueFromPipeline = $false)]
[string]$ExportPath = 'C:\Temp\'
)
$CsvName = "$(Get-Date -Format 'yyyyMMdd_HHmm')-$($AD.ToUpper())-$($InactiveDays)DaysInactive.csv"
$ExportPath = Join-Path -Path $ExportPath -ChildPath $CsvName
switch ($AD) {
'AD01' {
$Server = (Get-ADDomainController -DomainName 'AD01.local' -Discover).Hostname
Continue
}
'AD02' {
$Server = (Get-ADDomainController -DomainName 'AD02.local' -Discover).Hostname
Continue
}
'AD03' {
$Server = (Get-ADDomainController -DomainName 'AD03.local' -Discover).Hostname
Continue
}
'AD04' {
$Server = (Get-ADDomainController -DomainName 'AD04.local' -Discover).Hostname
Continue
}
Default {
Write-Warning -Message 'No valid domain chosen.'
exit
}
}
Write-Output "Contacting $Server in the $AD domain"
Write-Output "The timespan in days is $InactiveDays"
Try {
Search-ADAccount -Server $($Server) -AccountInactive -UsersOnly -TimeSpan "$($InactiveDays):00:00:00" -ResultPageSize 2000 -ResultSetSize $null |
Where-Object -FilterScript {$_.Enabled -eq $true} |
Get-ADUser -Properties WhenCreated, LastLogonDate, Description |
Select-Object Name, SamAccountName, DistinguishedName, WhenCreated, LastLogonDate, Description |
Where-Object -FilterScript {$_.WhenCreated -lt (Get-Date).AddDays(-$($InactiveDays))} |
Export-CSV -Path $ExportPath -Encoding utf8 -Delimiter ';' -NoTypeInformation
}
Catch {
Write-Host -BackgroundColor Red "Error: $($_.Exception)"
Break
}
So I’ve got two questions.
The primary is that I’d like to add a switch parameter to filter out accounts that have never logged in.
The Where-Object line is not a problem, but I’m not sure of the best way to implement it.
Would I have to duplicate the entire Search-AdAccount - Export-Csv block in an If-block like this:
If ($LoggedOn) {
Search-AdAccount...
Where-Object [LOGGED ON FILTER]
}
else {
Search-AdAccount...
}
Or is there a more elegant solution where I can just modify the first Where-Object line depending on whether or not the Switch-parameter was set?
The other question is about the two existing Where-Object lines in the block. The recommendation is to filter as far to the left as possible in PowerShell. However, the WhenCreated property is not available on Search-AdAccount, so I’ve had to filter twice in this block. Is there a better way of doing this or should I just accept that this is how it should be in this instance or is there a better way of doing this?