Scheduled Task: LastLogon PowerShell Script with Email

Posted on 2016-10-25
Last Modified: 2016-10-31
Good Morning, Experts!

Firstly, I will be the first to admit: I am a PowerShell amateur.

What we are wanting to do is setup a script that will:

- Audit all Active Directory Users, to see when their last logon was (lastlogon)
- Export this information to a .csv file labeled lastlogon-audit-<yyyymmdd>
- Include the following LDAP fields, each in its own column: Login Name, Display Name, Email Address, Description, Account Disabled, Last Logon
- If possible, highlight users who have not logged in for more than 7 days
- Email that report to a specific email address

We have a similar setup for Password Expiration, though that script is more sophisticated, in that it emails the users whose passwords will expire in 14 days, and outlines password rules. That script predates my time here.
Question by:Woodrax
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
ID: 41859528
Try this.
Gets the info you need (except account disabled, need to find that attribute name), and exports to a csv.

Get-ADUser -Filter * -Properties * | Select-Object Name, @{Name=”Last Successful Logon”;Expression={[datetime]::FromFileTime($_.’lastLogonTimeStamp’)}},mail,displayname,description | Sort-Object “Last Successful Logon”| Export-Csv C:\Powershell\output.csv

This will send you and email of the CSV attachment that was exported to the path of your choice.

Send-MailMessage -From "THEUSERNAME <>" -TO "USERNAME <>" -Subject "SUBJECT DESCRIPTION" -Body "A MESSAGE IN THE BODY." -Attachments "C:\APATHYOUCHOOSE\output.csv" -SmtpServer "YOUR SMTP SERVER"
ID: 41859534
login name is "samaccountname"  I forgot that so add in this the selection so to make it easier it is this.

Get-ADUser -Filter * -Properties * | Select-Object Name, @{Name=”Last Successful Logon”;Expression={[datetime]::FromFileTime($_.’lastLogonTimeStamp’)}},samaccountname,mail,displayname,description | Sort-Object “Last Successful Logon”| Export-Csv C:\Powershell\output.csv

Assisted Solution

by:get-ADuser -F ($_.Name -eq "Todd")
get-ADuser -F ($_.Name -eq "Todd") earned 500 total points
ID: 41859584
Here's the whole thing.  Your date format was tough because you have to manipulate it a bit to put in the format you want.

# Get date values
$Date = Get-Date
[String]$Year = $Date.Year
[String]$Month = $Date.Month
[String]$Day = $Date.Day

# Pad the date parts with leading 0's
If ( $Month.ToString().Length -lt 2 ) { $Month = '0' + $Month }
If ( $Day.ToString().Length -lt 2 ) { $Day = '0' + $Day }

Get-ADUser -Filter * -Properties * | Select-Object Name, @{Name=”Last Successful Logon”;Expression={[datetime]::FromFileTime($_.’lastLogonTimeStamp’)}},samaccountname,useraccountcontrol,mail,displayname,description | Sort-Object “Last Successful Logon”| Export-Csv C:\YOURPATH\lastlogon-audit_$Year$Month$Day.csv

Send-MailMessage -From "ANYNAME <>" -TO "NAMEOFVALIDEMAILADDRESS <>" -Subject "YOUR SUBJECT" -Body "YOUR BODY OF EMAIL." -Attachments "C:\YOURPATH\lastlogon-audit_$Year$Month$Day.csv" -SmtpServer "YOURMAILSERVER"

The only thing I had trouble with was the disabled accounts.  The only way I could get those is by this:    

Search-ADAccount -AccountDisabled |select name |ft -wrap

This gives you a list by name of the disabled accounts.  But the rest was tested and works here. Just fill in what is needed that fits your environment.  I put them all in caps.
Free Webinar: AWS Backup & DR

Join our upcoming webinar with experts from AWS, CloudBerry Lab, and the Town of Edgartown IT to discuss best practices for simplifying online backup management and cutting costs.


Author Comment

ID: 41862071
You are truly a Gentleman and a Scholar, Mr. netcepter! This is more than I expected!

I apologize in advance, but wanted to see if it is possible to add a little functionality to the script. The purpose of this script is to try and ax the bad habit of supervisors "ignoring" users, and allowing their accounts to remain active, even when they are no longer in use. Is it possible to output accounts that have not been used for X amount of days into the body of the email? I think just having the Display Name, and LastSuccessfulAudit attributes will be plenty of information. What I am really envisioning is outputting any accounts that have not logged in for X or more days, so that we can contact supervisors regarding their users. Would there be a way, in both the Script and the Email Output to sort by date?

I also dorked around a bit, and added the manager attribute. It outputs the information, but is the full AD Attribute output, as opposed to just the Manager's name. Not sure how to parse this down to just the name, as it would appear in the Display Name attribute.

Whatever your answer (even if it is "go pound sand"), thanks a million for all of your help!

Accepted Solution

get-ADuser -F ($_.Name -eq "Todd") earned 500 total points
ID: 41864336
Thanks.  I have got a lot out of Powershell and this site.  So I try to give back.  I know enough to be dangerous and have a lot of .ps1 saves that can mix and match.  LOL.  Not only that, I am addicted to Powershell so that is my Geek statement of the day.  

So here is what I think you are looking for.  I have notes within the script to help you.  But I think you have a good grasp.  I had to put "DisplayName" and "Name" because we have generic accounts. So for testing I needed to add both.  You can just have "DisplayName" if that works for you. Kind of big, I am sure there is better syntax, but I only know what I know.  :)

# Get date values
 $Date = Get-Date
 [String]$Year = $Date.Year
 [String]$Month = $Date.Month
 [String]$Day = $Date.Day
 # Pad the date parts with leading 0's
 If ( $Month.ToString().Length -lt 2 ) { $Month = '0' + $Month }
 If ( $Day.ToString().Length -lt 2 ) { $Day = '0' + $Day }

# This is information you need about your SMTP server

$messageSubject = "All Domain Users"
$smtpfrom = ""
$smtpto = ""
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true

    Convert to HTML  You can go to this site to find more color names.
    I use what I can see well.

$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 2px;padding: 1px;border-style: solid;border-color: black;background-color:lightgray: text-align;right}"
$a = $a + "TD{border-width: 2px;padding: 1px;border-style: solid;border-color: black;background-color:whitesmoke}"
$a = $a + "</style>"

    Here is the amount of days.  I picked 10.  You can change the -gt to whatever you want.
    Keep in mind I get a lot of dates of the year 1600.  I think thats because they never logged in.
    Also, because of Exchange I get all the Exchange HealthMailboxes, etc.  But my Domain is
    in theprocess of cleaning up bad accounts.
    You can limit it by OU and use -searchbase for a specific OU
    Or what I did, and only

$AllUsers = get-aduser -filter *  -properties DisplayName,lastlogontimestamp,Manager `
            | ? {(((Get-date) - ([datetime]::FromFileTime($_.lastlogontimestamp))).TotalDays -gt 10)} |sort-object lastlogontimestamp `
            |select name,DisplayName,@{Exp={([datetime]::FromFileTime($_.lastlogontimestamp))};label="Last logon time stamp"},@{n="Manager Name";e={(Get-ADUser -Identity $_.Manager -properties DisplayName).DisplayName}}

    If you need to export to CSV by the date of the file place what I have below to the $allUsers variable
    Then put -attacments at the end of H1> and the path you exported it too
    |export-csv "C:\powershell\Scripts\lastlogon-audit_$Year$Month$Day.csv" -NoTypeInformation -Delimiter ";"

$message.Body = $AllUsers | ConvertTo-HTML -head $a -body "<H1>Users Not Logged On For Over 10 Days</H1>"

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)

Author Comment

ID: 41864361
HOLY CRAP! This is an amazing script! Honestly, seeing the awesome output that you have been able to generate through your scripts makes me want to learn more PowerShell. I know it will take time for me to be as talented as you, but this certainly shows the kind of muscle that PowerShell has!

I think you have done way more than enough for me, considering my initial and second requests. I will be posting a separate request for another script, but definitely think you have earned the points here.  :)

Thanks a billion!


Author Closing Comment

ID: 41864364
Amazing scripts, with so much more than I even thought possible. Wish I could double the points.  :)
ID: 41864451
Thanks much. Glad I could help.     Happy Powershelling....
ID: 41864478
Lastly,  I have always got confused with LastLogonTimeStamp, and LastLogon.  

Replace LastLogonTimeStamp with  LastLogon in your script and you may like the output better.  I think LastLogon is better.  I gave you the stamp. You can research if you want, but both work.

Author Comment

ID: 41866814
Yeah, the lastlogon replacement makes for a cleaner output. Thanks!

Featured Post

Backup Solution for AWS

Read about how CloudBerry Backup fully integrates your backups with Amazon S3 and Amazon Glacier to provide military-grade encryption and dramatically cut storage costs on any platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Previously, on our Nano Server Deployment series, we've created a new nano server image and deployed it on a physical server in part 2. Now we will go through configuration.
A company’s centralized system that manages user data, security, and distributed resources is often a focus of criminal attention. Active Directory (AD) is no exception. In truth, it’s even more likely to be targeted due to the number of companies …
In this Micro Tutorial viewers will learn how to use Boot Corrector from Paragon Rescue Kit Free to identify and fix the boot problems of Windows 7/8/2012R2 etc. As an example is used Windows 2012R2 which lost its active partition flag (often happen…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

761 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question