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

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

Related

Issue with powershell output ad-computer foreach

$computers = Get-ADComputer -Filter * -Properties * | Where-Object {$_.Name -like "LT*" -or $_.Name -like "PC*" -or $_.Name -like "MC*"} | Select name,lastlogondate
"You have [{0}] computers in domain [{1}]" -f $computers.count, (get-addomain).dnsroot
$today = Get-Date
$monthago = $today.AddDays(-30)
"Looking for systems that have not logged in since $monthago"
foreach ($computer in $computers)
{
if ($computer.lastlogondate -lt $monthago)
{"Computer [$computer] suspect"
"last logon $($computer.lastlogondate)"
""}
}
returns the following result:
Computer [#{name=lt020367; lastlogondate=10/23/2019 11:45:38}] suspect
last logon 10/23/2019 11:45:38
Can someone possibly tell me why my output is resulting in [#{ and how to resolve?
by get-adcomputer [...] | Select name,lastlogondate you are creating an object. To output properties of those objects, simply use:
"Computer [$($computer.name)] suspect"
"last logon $($computer.lastlogondate)"
By the way:
Getting all * properties is not ideal. Always filter as early as you can: -properties lastlogondate (name is always returned). Same goes for -filter "name -like 'LT*' -or name -like 'PC*' -or name -like 'MC*'".
Also be careful as lastlogondate of computer objects in AD is not synced between domain controllers.

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

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.

Powershell to get accounts with passwords older than "$"

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

PowerShell script to list users that are enabled, have never logged on or have not logged on in 60 days

I need to use PowerShell to list users that are enabled, have never logged on or have not logged on in 60 days.
The below is what I've come up with having never used PowerShell previously, however clearly there is something wrong in my understanding as it just spouts out a bunch of different error messages.
Get-ADUser -Filter { Enabled -eq $true } -Properties LastLogonDate | where { ($_.LastLogonDate.AddDays(60) -lt $(Get-Date)) -or ( -not $_.LastLogonDate-like "*")) } | Select-Object SamAccountName | Format-Table
try this
Get-ADUser -Filter { Enabled -eq $true } -Properties LastLogonDate | where{ (($_.LastLogonDate.AddDays(60) -lt $(Get-Date)) -or ( -not $_.LastLogonDate-like "*")) } | Select-Object SamAccountName | Format-Table
your brackets werent correct, more specifically this bracket is extra
( -not $_.LastLogonDate-like "*")) // extra closing bracket
Taking my comment and making it an answer:
Get-ADUser -Filter { Enabled -eq $True } -Properties LastLogonDate |
#Tests whether LastLogonDate is older than 60 days or if it's $Null
Where-Object { $_.LastLogonDate -lt (Get-Date).AddDays(-60) -or
-not $_.LastLogonDate } |
Select-Object -Property SamAccountName |
Format-Table