I would like to get the actual date of accounts that have expired but still enabled in the active directory. I always get the date + 1 day. For example, if a user is expired today (15/11/2022), it will shows (16/11/2022)... Can you help me with this?
Get-ADUser -Filter * -properties AccountExpirationDate |
Where-Object{$_.AccountExpirationDate -lt (Get-Date) -and $_.AccountExpirationDate -ne $null -and $_.Enabled -eq $True} |
select-object Name, SamAccountName, AccountExpirationDate | Sort-Object -Property {$_.AccountExpirationDate} -Descending
I always like to include LDAP property accountExpires in there (PowerShell conveniently converts this to local time in Property AccountExpirationDate)
to first check if the attribute has never been set (value 0) or if the attribute for the user has been set to 'Never Expires' (value 9223372036854775807).
Try
$refDate = (Get-Date).Date # set to midnight
# or use -LDAPFilter "(!userAccountControl:1.2.840.113556.1.4.803:=2)"
Get-ADUser -Filter 'Enabled -eq $true' -Properties AccountExpirationDate, accountExpires |
Where-Object {($_.accountExpires -gt 0 -and $_.accountExpires -ne 9223372036854775807) -and
($_.AccountExpirationDate -le $refDate)} |
Select-Object Name, SamAccountName, AccountExpirationDate |
Sort-Object AccountExpirationDate -Descending
Thanks Theo, ive found what i was looking for
Get-ADUser -Filter 'Enabled -eq $true' -Properties AccountExpirationDate, accountExpires |
Where-Object {($_.accountExpires -gt 0 -and $_.accountExpires -ne 9223372036854775807) -and
($_.AccountExpirationDate -le $refDate)} |
Select-Object Name, SamAccountName, #{Name="AccountExpirationDate";Expression={(get-date $_.AccountExpirationDate).AddDays(-1)}} |
Sort-Object AccountExpirationDate -Descending
We are using a good script that we would like to extend to search for users everywhere except one OU. How can I do this?
Thanks in advance for your help!
PasswordChangeNotification
How to instert this code?
Get-ADOrganizationalUnit -filter * -SearchBase 'OU=test,DC=test,DC=com' | foreach {
if($_.distinguishedname -ne "OU=not,OU=that,OU=orgUnit,OU=test,DC=test,DC=com"){
$users=Get-ADUser -filter * -searchbase $_.distinguishedname -ResultPageSize 2000 -resultSetSize 500 -searchscope Onelevel | where-object enabled -eq true
$total=($users | measure-object).count
New-Object psobject -Property #{
OU=$_.Name;
A=$Total
}
}
}
On line 132 of the file you've linked to, you'll find the statement that actually queries Active Directory for the users:
$users = get-aduser -filter {(Enabled -eq $true) -and (PasswordNeverExpires -eq $false)} -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress | where { $_.passwordexpired -eq $false }
Add the following statement to the next line:
$users = $users |Where-Object distinguishedname -notlike "*,OU=not,OU=that,OU=orgUnit,OU=test,DC=test,DC=com"
... and leave the rest of the script as-is
This script below works, but every attempt I make to have it cycle through all my domain controllers fail. How do I add a array to go through all these OUs on all my domain controllers. Thanks in advance!
$OUs= “OU=Test1,OU=Test1,OU=Test1,OU=Test1,OU=All Users,DC=domain,DC=local",
"OU=Test2,OU=Test2,OU=Test2,OU=All Users,OU=Test2,DC=domain,DC=local",
"OU=Test3,OU=Test3,OU=Test3,OU=All Users,OU=Test3,DC=domain,DC=local",
"OU=test4,OU=test4,OU=test4,OU=All Users,OU=test4,DC=domain,DC=local",
"OU=Test5,OU=test5,OU=Test5,OU=All Users,OU=test5,DC=domain,DC=local”
$OUs | ForEach-Object
{
Get-ADUser -Filter {Enabled -eq $TRUE} -SearchBase $_ -Properties Name,SamAccountName,LastLogonDate |
Where-Object {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)}
} |
Sort LastLogonDate |
Format-Table -Property Name,SamAccountName,LastLogonDate, DistinguishedName |
Out-String
Below you have now an array of your OUs. Please try whether that works for you now.
$OUs= #(
“OU=Test1,OU=Test1,OU=Test1,OU=Test1,OU=All Users,DC=domain,DC=local",
"OU=Test2,OU=Test2,OU=Test2,OU=All Users,OU=Test2,DC=domain,DC=local",
"OU=Test3,OU=Test3,OU=Test3,OU=All Users,OU=Test3,DC=domain,DC=local",
"OU=test4,OU=test4,OU=test4,OU=All Users,OU=test4,DC=domain,DC=local",
"OU=Test5,OU=test5,OU=Test5,OU=All Users,OU=test5,DC=domain,DC=local”
)
I would also suggest to break your line after every pipe in order to cut the line. That makes it far easier to read for you, plus your colleagues.
$OUs | ForEach-Object
{
Get-ADUser -Filter {Enabled -eq $TRUE} -SearchBase $_ -Properties Name,SamAccountName,LastLogonDate |
Where-Object {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)}
} |
Sort LastLogonDate |
Format-Table -Property Name,SamAccountName,LastLogonDate, DistinguishedName |
Out-String
You mention cycling through your domain controllers, but then you go on to ask about OUs. I suspect you want DC's, because each DC might have a different Last Logon Time for the user.
You can omit the -SearchBase and search all OU's, if you're looking to get this data for all users.
$Domains = Get-ADDomainController -Filter * #Note, this shows all DCs- you may have some without ADWS Installed, which won't handle the WHERE.
foreach ($domain in $Domains) {
Get-ADUser -Filter {Enabled -eq $TRUE} -Server $domain -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)} |
Export-CSV -Path 'UsersNotRecentlyLoggedIn.CSV' -Append
}
If you only want one DC, but all OUs
$Domains = Get-ADDomainController -Discover -Service ADWS
foreach ($domain in $Domains) {
Get-ADUser -Filter {Enabled -eq $TRUE} -Server $domain -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)} |
Export-CSV -Path 'UsersNotRecentlyLoggedIn.CSV' -Append
}
I'm trying to query machines which were last logged on to 30 days ago
Clear-Host
$Threshold = (Get-Date).AddDays(-30)
$NotInUse = Get-ADComputer -Filter * -Properties LastLogonDate | Where {
$_.name -Like "*LN-T48*" -and $_.LastLogonDate -gt $Threshold
}
$NotInUse | select Name, LastLogonDate -Verbose
Use -lt
Using the filter is quicker:
$Threshold = (Get-Date).AddDays(-30)
$NotInUse = Get-ADComputer -Filter {LastLogonDate -lt $Threshold} -Properties LastLogonDate |
Where { $_.name -Like "*LN-T48*"}
$NotInUse | select Name, LastLogonDate -Verbose | sort LastLogonDate
I am trying to get a list of accounts with passwords that are older than lets say 90 days but something is not working right and I am not sure why.
Get-ADUser -Filter 'Enabled -eq $True' -Properties PasswordLastSet,samaccountname,passwordlastset | Where-Object {$_.PasswordLastSet -gt ($_.PasswordLastSet).adddays(1)} | select Name,samaccountname,passwordlastset
This is what i got so far but if I run it as is it returns 0 results. I know there are passwords that are older than one day, mine is one of them. Any help is appreciated.
Per your realization in the comments you should compare the PasswordLastSet field to today's date less 90 days as follows:
Get-ADUser -Filter 'Enabled -eq $True' -Properties PasswordLastSet | Where-Object {$_.PasswordLastSet -lt (Get-Date).adddays(-90)} | select Name,SamAccountName,PasswordLastSet
Use -lt for older passwords, or -gt for newer passwords.
You can try this,if you wana export remove #
$DaysAgo=(Get-Date).AddDays(-90)
$params = #{
"filter" = 'Enabled -eq $true -and passwordlastset -lt $DaysAgo'
"Properties" = "Displayname",
"passwordlastset",
"samaccountname"
}
Get-ADUser #params |select displayname,samaccountname,passwordlastset #| export-csv C:\result.csv -nti