Powershell to get accounts with passwords older than "$" - powershell

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

Related

PowerShell Comparing lastLogon to 90 days ago [duplicate]

So far I tried this**
Does not seem to work well, I get dates back from 2014.
And only a few from 2022
$90Days = (get-date).adddays(-90)
Get-ADUser -SearchBase "OU=Domain Users,DC=x,DC=state,DC=x,DC=x" -properties * -filter {(lastlogondate -notlike "*" -OR lastlogondate -le $90days) -AND (passwordlastset -le $90days)} | select-object name, SAMaccountname, lastlogondate | export-csv c:\Temp\90days.csv
It's a simple flip from less than to greater than. Dates are stored as numbers that increment every millisecond. Starting at a date 90 days ago and asking for "less than" means get everything from 90 days ago and earlier, not 90 days and greater to "today".
Simply flip your -le to -ge.
$90Days = (get-date).adddays(-90)
Get-ADUser -SearchBase "OU=Domain Users,DC=x,DC=state,DC=x,DC=x" -properties * -filter {(lastlogondate -notlike "*" -OR lastlogondate -ge $90days) -AND (passwordlastset -ge $90days)} | select-object name, SAMaccountname, lastlogondate | export-csv c:\Temp\90days.csv
Your filter is wrong. lastlogondate -notlike "*" -OR literally means if LastLogonDate not like anything OR ...
This means it would almost always pass the test.
Then, I don't see why you also include property PasswordLastset in the equation as your question is not about that.
I think this would work better for you:
$90Days = (Get-Date).AddDays(-90).Date # set the date to midnight
# to filter on enabled users only, you can also use the LDAPFilter parameter like:
# -LDAPFilter "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"
Get-ADUser -Filter "Enabled -eq $true" -SearchBase "OU=Domain Users,DC=x,DC=state,DC=x,DC=x" -Properties LastLogonDate |
Where-Object {$_.LastLogonDate -ge $90Days} |
Select-Object Name, SamAccountName, LastLogonDate |
Export-CSV -Path 'c:\Temp\90days.csv' -NoTypeInformation
P.S. Don't ask for ALL properties with -Properties * if you only want one extra property on top of the attributes returned by default like Name and SamAccountName.
Note: Please also bear in mind that the calculated property LastLogonDate (not really an AD attribute at all) is not replicated within the domain and to get the most accurate value, you need to iterate the domaincontrollers in your domain.

Powershell, find users that were disabled in the past 14 days only

I have a powershell script that his output is showing me everything that was disabled for the past 14 days.
What i'm looking is to change that this script will run from a specific OU and not the whole DC.
I want him to show me only the disabled users for the past 14 days from a specific OU.
The script:
$date = (Get-Date).AddDays(-14)
$disabledUsers = Get-ADObject -Filter 'ObjectClass -eq "User" -and whenChanged -ge $sixMonthsAgo -and UserAccountControl -band 2'
$server = Get-ADDomainController
foreach ($disabledUser in $disabledUsers)
{
Get-ADReplicationAttributeMetadata $disabledUser -Server $server -Properties UserAccountControl |
Where-Object { $_.AttributeName -eq 'UserAccountControl' } | Select Object, LastOriginatingChangeTime |
Where-Object { $_.LastOriginatingChangeTime -gt $date }
}
You should be aware that your current script actually works only if an object has not been modified since it was disabled.
But as far as I know, it is the only way without logging specificly userAccountControl attribute modification (and this cannot still log 100% of cases since once disabled, an object can see his userAccountControl modified without enabling it).
Based on "user is never modified after he was disabled" :
Search-ADAccount -SearchBase "OU=myOU,DC=mydom,DC=adds" -AccountDisabled -UsersOnly | Get-ADUser -Properties whenChanged | Where whenChanged -gt (Get-Date).AddDays(-14)
Using the Filter will make it run quickly
$date = (Get-Date).AddDays(-14)
get-aduser -filter {Enabled -eq $false -and Modified -ge $date } -Properties Modified | select samaccountname,Modified

Select users from AD randomly

We've been tasked with creating a process to review random employee's web traffic on a quarterly basis. I have started a script in Powershell that selects 10 random users from a specific OU, but I'm still getting some unneeded data. I need help filtering down the list further. The output gives me users that have been disabled and left in the OU as well as PRN employees that haven't signed on in a long time. I would like to search AD accounts that has an email address & a logon, modified within the last 3 months. Here is an example of the code I have so far.
Get-ADUser -SearchBase "ou=ouname,ou=ouname,dc=domainname,dc=suffix" -Filter * | Select-Object -Property Name | Sort-Object{Get-Random} | select -First 10
[Edit: Question Answered]
Here is my final script, added $_.passwordlastset as a search attribute since this will pickup users that have changed their password in the last 90 days.
$DateFrom = (get-Date).AddDays(-90)
Get-ADUser -Properties * -Filter {enabled -eq $True} -SearchBase "ou=ouname,dc=domainname,dc=suffix" | where { $_.passwordlastset -gt $DateFrom -and $_.mail -ne $null } | Sort-Object {Get-Random} | select name, sAMAccountName -First 10
Get-ADUser -Properties name, mail, lastlogondate -Filter {enabled -eq $True} -SearchBase "ou=ouname,ou=ouname,dc=domainname,dc=suffix" | select name, mail, lastlogondate | where { $_.lastlogondate -gt (Get-Date).AddDays(-90) -and $_.mail -ne $null }
Here a start.
Try this:
$timeFrame = (get-Date).AddDays(-90)
get-aduser -SearchBase 'ou=ouname,ou=ouname,dc=domainname,dc=suffix' -Filter * -Properties * |
Where-Object {$_.whenChanged -gt $timeFrame -and $_.mail -ne $null} |
Select-Object -Property Name | Sort-Object{Get-Random} | select -First 10
Change the -Filter value:
# LastLogontimeStamp is not guaranteed to be updated on every login, so 30 days + 14 days margin
$threshold = (Get-Date).AddDays(-44).ToFileTime()
Get-ADUser -Filter {Enabled -eq $true -and LastLogontimeStamp -gt $threshold} -SearchBase "ou=ouname,ou=ouname,dc=domainname,dc=suffix" | Sort-Object {Get-Random} | Select Name -First 10
This filter will ensure that AD only returns Enabled users and that their lastLogontimeStamp value has been updated within the last month and a half
This will do everythign the OP stated:
$timeFrame = (get-Date).AddDays(-90)
get-aduser -SearchBase 'YourOU,DC=Domain,DC=com' -Filter * -Properties * |
Where-Object {$_.whenChanged -lt $timeFrame -and $_.mail -ne $null -and $_.Enabled -eq $true} |
Select-Object -Property Name | Sort-Object{Get-Random} | select -First 10
This should meet all the OPs checkpoints via the snippets:
"I would like to search AD accounts that has an email address"
$_.mail -ne $null
"& a logon"
$_.Enabled -eq $true
"modified within the last 3 months"
$_.whenChanged -lt $timeFrame

Get Password expiry date for one single user in AD

I have found this script that filters me the passwprdexpirydate of enabled accounts on AD.
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –Properties “DisplayName”, “msDS-UserPasswordExpiryTimeComputed” |
Select-Object -Property “Displayname”,#{Name=“ExpiryDate”;Expression{[datetime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”)}}
It works fine but I would like to have it search just one specific AD account that I will type in. How do I accomplish that?
I would
This is one of those times where reading the documentation would answer your question, as the examples cover this question...
You can either replace the Filter for the Identity param:
Get-ADUser -Identity USERNAME
Or, update the filter:
Get-ADUser -Filter {Name -eq "USERNAME"}
Try something like this:
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –
Properties "DisplayName", "msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "Displayname",#{Name="ExpiryDate";Expression=
{[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} |
Where-Object {$_.DisplayName -like "Username"}

Compare LastLoginDate of user from multiple DC's

I got 2 DCs and need to get a list of all my users that haven't logged in for X days. I got a PS script that looks at the user his last logon date on the domain and then filters and export the users that haven't logged on for the X days.
PowerShell script:
$AmountDays = 30
Get-ADUser -Filter * -Properties Enabled, LastLogonDate |
? {
$_.LastLogonDate -ne $null -and
$_.LastLogonDate -lt (Get-Date).AddDays(-$AmountDays)
} |
sort LastLogonDate |
Select Name,LastLogonDate |
Export-Csv C:\temp\LastLogonUser.csv -NoTypeInformation
The problem is my DC's have different LastLogonDates of that same user.
So if I run my script on DC1 for example he thinks the user haven't logged in for over 20 days, but when i run it on DC2 he logged in yesterday.
Is there a way to check the LastLogonDate of the same user from both DC's and take the most recent one, so I can check the result of the compare if the user haven't logged in for X days?
I have edited my code so it uses a foreach loop to go through my DCs and find my users. But I think it stops after he went through the first one. Because if I run a simple code to check if he can find both DCs he views them both. But when I run my code and export the result, it only shows each member ones and not all the LastLogonDates are correct.
New Script:
Import-Module ActiveDirectory
$dcs = Get-ADDomainController -Filter {Name -like "*"}
$AmountDays = 0
foreach($dc in $dcs)
{
Get-ADUser -Filter * -Properties Enabled, LastLogonDate | ? { `
($_.LastLogonDate -NE $NULL -AND $_.LastLogonDate -LT (Get-
Date).AddDays(-$AmountDays)) } |
sort LastLogonDate | Select Name,LastLogonDate |
Export-Csv C:\temp\LastLogonUser.csv -NoTypeInformation
}
I could actually use some help with the question asked as well because I need to modify a report that I make to do a comparison against 16 DC's and 1200 Computer accounts to find the last logon and passwordlastset
This is logic that I have used for a smaller set of data but I don't think it will be efficient with ~20,000 rows of data to find accurate info. It would be slow.
$Users = #(
"User1"
"User2"
)
$DomainControllers = #(
"DC1"
"DC2"
)
Foreach ($User in $Users){
Foreach ($Controller in $DomainControllers){
$Data = Get-ADUser $User -Properties "LastLogonDate" -Server $Controller | Select LastLogonData
}
$Data = $null
}
The LastLogonDate is a DateTime object, try to convert it first to your local time using the ToLocalTime() Method
So try:
Get-ADUser [...] -Properties LastLogonDate |
? { $_.LastLogonDate -and $_.LastLogonDate.ToLocalTime() -lt [datetime]::Now.AddDays(-30)}
Also, Make sure to sync the DC's Clock, To validate it use the Net Time \\YouDcName command
That is what LastLogonTimestamp was invented for, given that a value from 1 or 2 weeks ago is sufficient for your needs. If not you'll have to query all domain controllers and pick the most recent value.
Get-ADDomainController | ForEach-Object {
Get-ADUser -Filter * -Server $_ -Properties Enabled, LastLogonDate | Where-Object {
# ...
} | Select-Object Name, LastLogonDate
} | Group-Object Name | Select-Object Name, #{n='LastLogon';e={
$_.Group |
Sort-Object LastLogonDate |
Select-Object -Last 1 -Expand LastLogonDate
}
I feel your pain.
The lastLogonTimeStamp attribute is replicated to all DC's, but is only updated during logon if the existing value is 14 or more days old.
The lastLogon attribute is updated at every logon, but is not replicated. You'll need to query all DC's to get an accurate lastLogon value for each user.
I (for better or worse) tend to do this...
$stuff = $(net user $env:username /domain | select-string 'Last logon*').ToString()
$label, $login_date = [regex]::split($stuff, '\s{5,}')
$login_date
It's quick and dirty.