Reputation: 243
I am having issues filtering out accounts in a Search-ADAccount
query. The query always returns the 40 days inactive AD accounts that are enabled and have logged in at least once. However a number of accounts being returned are flagged as long-term sickness, maternity leavers or are Helpdesk accounts. In the users' objects the keyword will appear at least once, hence my use of -notlike
to have the wildcard function. But it still does not work, any ideas are much appreciated!
$excludelist = "Sickness", "Maternity", "Helpdesk"
$users = Search-ADAccount -AccountInactive -TimeSpan (New-TimeSpan -Days 40) -Searchbase "OU=Users,OU=State,DC=Company,DC=Biz" |
where {($_.enabled -eq $true) -and
($_.Description -notlike $excludelist) -and
($_.LastLogonDate -notlike $null) } |
Get-ADUser -Properties mail, manager, LastLogonTimeStamp
UPDATE: Based off the help in the comments, I have updated the code however the filtering does not apply. Here is the full code;
Import-Module ActiveDirectory
#Set our non-changing variables for the email
$SMTPServer = "[email protected]"
$From = "Helpdesk <[email protected]>"
#Set Testing if needed
$testing = "Enabled" #Set to disabled to go live
$testRecipient = "[email protected]"
#Set Description Modifiers:
$excludelist = 'Sickness|Maternity|Helpdesk'
#Query AD for all the NCE accounts with no activity for 40 days and are enabled
$users = Search-ADAccount -AccountInactive -TimeSpan (New-TimeSpan -Days 40) -Searchbase "OU=Users,OU=Company,DC=Company,DC=de" |
Where-Object {
$_.Enabled -and
$_.Description -notmatch $excludelist -and
$_.LastLogonDate
} | Get-ADUser -Properties mail, manager, LastLogonTimeStamp, description
#Loop through the query results
foreach ($User in $Users) {
#Convert LastLogonDate to days since last use
$lastLogon = [DateTime]::FromFileTime($User.lastLogonTimeStamp)
$Daysinactive = ((Get-Date) - $lastLogon).Days
#Get manager email with passthrough
$Manager = Get-ADUser $User.Manager -Properties EmailAddress
#Set dynamic variables and body of email
$To = $Manager.EmailAddress
$Subject = "Your employee $($User.Givenname) $($User.Surname) has not been active since $Daysinactive days."
$Body =
"Hello $($Manager.GivenName),<br>
<p>The account of $($User.Givenname) $($User.Surname) has not been active for $Daysinactive days. Please explain in return email.
<table border='1'>
<tr>
<td>Name</td>
<td>eIPN</td>
<td>email</td>
<td>Inactive Days</td>
<td>Description</td>
<td>Test</td>
</tr>
<tr>
<td>$($User.Givenname) $($User.Surname)</td>
<td>$($User.SamAccountName)</td>
<td>$($User.mail)</td>
<td>$Daysinactive</td>
<td>$($User.Description)</td>
<td>$excludelist</td>
</tr>
</table>
<p>Thanks you.<br>
<p>IT Helpdesk"
#Testing check before email is sent
if (($testing) -eq "Enabled") {
$To = $testRecipient
} # End Testing
#Send email
Send-MailMessage -To $To -From $From -Subject $Subject -SmtpServer $SMTPServer -Body $Body -BodyAsHtml -Priority High
}
To test, I have added in the $($User.Description)
and $excludelist
into the email table to ensure that the values are being read.
A user that should be filtered is returning a table such as thus:
So I can see that user.description
is being read with the excluded word "Helpdesk" in it, but it does not filter.
I have also tried to set the $exludelist
to simply "Helpdesk" but that does not filter either.
Any help is appreciated. I have tried every method of writing the filtering method I can find online but still no luck!
Upvotes: 1
Views: 180
Reputation: 200233
A condition <value> -notlike <list>
won't work. The -notlike
operator (as well as the -like
operator) can only compare a value to another value with a wildcard pattern. Also, you only want items that have neither of the given strings in the description, so you'd have to define the filter like this:
Where-Object {
$descr = $_.Description
-not ($excludelist | Where-Object {$descr -like "*$_*"})
}
If you want to check whether an attribute doesn't contain any of a given list of strings it's simpler to use a regular expression and the -notmatch
operator. Also, the properties of the objects returned by Search-ADAccount
don't include the attribute description
, so you can't filter on that property before running Get-ADUser
(which you must instruct to fetch that attribute). Another thing you may want to do is add the parameter -UsersOnly
to Search-ADAccount
to prevent it from fetching computer accounts and the like.
Change your code to this:
$excludelist = 'Sickness|Maternity|Helpdesk'
$users = Search-ADAccount ... -UsersOnly |
Where-Object { $_.Enabled -and $_.LastLogonDate } |
Get-ADUser -Properties mail, manager, LastLogonTimeStamp, Description |
Where-Object { $_.Description -notmatch $excludelist }
Upvotes: 1
Reputation: 174485
The -like
operator(s) doesn't work well with an array as its right hand argument:
PS C:\> "a" -notlike "a","b"
True
Since -like
(or any variation, including -notlike
) expects a string on the right hand, it converts the array to a single string and so your filter effectively becomes:
$_.Description -notlike "Sickness Maternity Helpdesk"
I doubt this will ever exclude anyone :)
You can use the -contains
operator instead:
$excludelist -notcontains $_.Description
Or the -in
operator (PowerShell 3.0 or newer):
$_.Description -notin $excludelist
Upvotes: 0