PS script to query last logon dates of accounts in an OU.

I need some help with a PS command to check an OU in my domain and return list of active accounts (samid, last name, first name) and also return list of active accounts with last logon date more than six months.  

Thanks.
nav2567Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Will SzymkowskiSenior Solution ArchitectCommented:
Use the following script below...
Import-module activedirectory
$OU = "ou=myou,dc=domain,dc=com"
$Date = get-date
Get-ADUser -Filter { LastLogonDate -gt $Date.AddDays(-180) } -SearchBase $OU -Properties samaccountname, givenname, surname |
Select samaccountname, givenname, surname |
Export-csv "c:\UserExport.csv" -nti

Open in new window


Change the $OU on line 2 to the OU where you want to search on.

Will.
0
Christopher KibbleCommented:
Hi Will - you won't want to use LastLogonDate since that attribute isn't replicated between Domain Controllers.  Only the DC that authenticates a user updates the value.  If you query a different DC, it will not have the update.  In a multi-DC environment, your output won't be right

References:

http://social.technet.microsoft.com/wiki/contents/articles/22461.understanding-the-ad-account-attributes-lastlogon-lastlogontimestamp-and-lastlogondate.aspx,

http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx)
0
Christopher KibbleCommented:
Nav -

This should be what you're looking for
https://gallery.technet.microsoft.com/scriptcenter/Get-Inactive-User-in-78b8db79

You'll want to change the days inactive and add a search scope, so it'll look like this:

# Gets time stamps for all User in the domain that have NOT logged in since after specified date 
# Mod by Tilo 2014-04-01 

import-module activedirectory  
$DaysInactive = (30*6)  # About 6 Months

$time = (Get-Date).Adddays(-($DaysInactive)) 
  
# Get all AD User with lastLogonTimestamp less than our time and set to enable 
$users = Get-ADUser -Filter {LastLogonTimeStamp -lt $time -and enabled -eq $true} -Properties LastLogonTimeStamp -SearchBase "OU=MyOU,OU=SomethingElse,DC=Domain,DC=Stuff,DC=COM" -SearchScope Subtree
$users | select-object Name,@{Name="Stamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp).ToString('yyyy-MM-dd_hh:mm:ss')}} | export-csv OLD_User.csv -notypeinformation

Open in new window

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Will SzymkowskiSenior Solution ArchitectCommented:
LastLogonDate is equivalent to LastLogonTimeStamp. LastLogonDate is a human representation of LastLogonTimeStamp. The values could be up to approx 14 days out but atleast the user will have a good starting point and a rough calculation overall.

Will.
0
nav2567Author Commented:
Thanks, everyone.

Will, I am trying your script and get this error:

Get-ADUser : Property: 'AddDays' not found in object of type: 'System.DateTime'
.
At line:1 char:11
+ Get-ADUser <<<<  -Filter { LastLogonDate -gt $Date.AddDays(-180) } -SearchBas
e $OU -Properties samaccountname, givenname, surname |Select samaccountname, gi
venname, surname |Export-csv "C:\actacctlt180.csv" -nti
    + CategoryInfo          : InvalidArgument: (:) [Get-ADUser], ArgumentExcep
   tion
    + FullyQualifiedErrorId : Property: 'AddDays' not found in object of type:
    'System.DateTime'.,Microsoft.ActiveDirectory.Management.Commands.GetADUse
  r
0
Will SzymkowskiSenior Solution ArchitectCommented:
I have modified the script slightly. Try the following script below...
Import-module activedirectory
$OU = "ou=myou,dc=domain,dc=com"
$Date = get-date
Get-ADUser -Filter * -SearchBase $OU -Properties samaccountname, givenname, surname, LastLogonDate |
? { $_.LastLogonDate -gt $Date.AddDays(-180) } |
Select samaccountname, givenname, surname, LastLogonDate |
Export-csv "c:\UserExport.csv" -nti

Open in new window


I missed the LastLogonDate which needs to be added to the Properties parameter. This should now work for you. Let me know if you have any other error messages.

Will.
0
nav2567Author Commented:
Almost perfect!!!

Right now, I am seeing listed accounts with lastlogondate from January 2015 to today.  

Can you tweak your script to list "Active" accounts which have not been login for three months or the "lastlogondate" is greater than three months?  

Thanks.
0
Will SzymkowskiSenior Solution ArchitectCommented:
Change
Import-module activedirectory
$OU = "ou=myou,dc=domain,dc=com"
$Date = get-date
Get-ADUser -Filter * -SearchBase $OU -Properties samaccountname, givenname, surname, LastLogonDate |
? { $_.LastLogonDate -lt $Date.AddDays(-90) } |
Select samaccountname, givenname, surname, LastLogonDate |
Export-csv "c:\UserExport.csv" -nti

Open in new window


There you go.

Will.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Christopher KibbleCommented:
Hi Will,

LastLogonDate is equivalent to LastLogonTimeStamp. LastLogonDate is a human representation of LastLogonTimeStamp. The values could be up to approx 14 days out but atleast the user will have a good starting point and a rough calculation overall.

I think you might be mistaken.  LastLogonDate is not replicated between Domain Controllers.  What this means for the person asking the question is that if there is more than one Domain Controller, the one that they are querying with Get-ADUser will not have the updated LastLogonDate of some number of users in the environment.  

This is noted in the remarks on this MSDN page:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms676823(v=vs.85).aspx
This attribute is not replicated and is maintained separately on each domain controller in the domain. To get an accurate value for the user's last logon in the domain, the Last-Logon attribute for the user must be retrieved from every domain controller in the domain. The largest value that is retrieved is the true last logon time for that user.

As well as on a number of blogs online:

http://kpytko.pl/active-directory-domain-services/lastlogon-vs-lastlogontimestamp/
the most simple difference between them is that lastLogon attribute stores information about last successful user logon only on that particular Domain Controller and it is NOT replicated to other Domain Controllers.

http://serverfault.com/questions/487822/active-directory-last-logon-replication-across-ad-servers
This attribute is not replicated and is maintained separately on each domain controller in the domain. To get an accurate value for the user's last logon in the domain, the Last-Logon attribute for the user must be retrieved from every domain controller in the domain. The largest value that is retrieved is the true last logon time for that user.

http://www.coretekservices.com/2013/02/28/ad-attributes-lastlogon-vs-lastlogontimestamp
I did a few minutes of research on the "lastLogon" attribute and then I discovered I was searching the wrong attribute, per Microsoft's MSDN Attribute Library which states: "This attribute is not replicated and is maintained separately on each domain controller in the domain. To get an accurate value for the user's last logon in the domain, the Last-Logon attribute for the user must be retrieved from every domain controller in the domain. The largest value that is retrieved is the true last logon time for that user."  But since the enterprise I was working with had more domain controllers than I could count on one hand so I chose to find a simple alternative.

After a few more minutes of research I then found the attribute that is replicated across all domain controllers, the "lastLogonTimeStamp" attribute.  I updated my script to:

Get-ADUser $UserNameToSearch | Get-ADObject -Properties lastLogonTimeStamp

If you have any sources that say that this has changed, please let us know.

Thanks -
Chris
0
nav2567Author Commented:
Thanks, Will and everyone.
0
Will SzymkowskiSenior Solution ArchitectCommented:
"Powershell was nice enough to give us a third option to query by.  LastLogonDate is a converted version of LastLogontimestamp.  He was technically right.  It’s not a replicated attribute.  Instead, it’s a locally calculated value of the replicated value.  Most importantly, it gives us the ability to query using human friendly date formats!!"

Please reference your first link as I have pulled the above statment from it. LastLogonDate is a locally calculated value of the LastLogonTimeStamp which makes it readable to humans.

Try it for yourself. In my current production environment I have 10 DC's I have run the following command on ALL of my DC's and I get the same results from everyone.

Get-ADUser -identity user1 -properties LastLogondate | fl lastlogondate

Open in new window


I logged into each DC separately and ran the above command and got the same results everytime.

Will.
0
Christopher KibbleCommented:
Hey Will - happy to be corrected in this instance, the lack of replication of the attribute has always been a thorn in my side!  Thanks for the heads up.  :)
0
nav2567Author Commented:
Will,

I applied your last script against an OU and it returns only the ACTIVE accounts with lastlogondate more than 3 months which is what I want.  However, when I change the $OU to "DC=MYDOMAIN,DC=COM", the "disabled" accounts are listed as well.  

Please advise again.

Let me know if I need to post a new question regarding this.

Thanks.
0
Will SzymkowskiSenior Solution ArchitectCommented:
As you have closed this question already please post another one and I will answer it accordingly. Just let me know what the link is.

Thanks

Will.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.