Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Need help with logic for AD Powershell Audit <30 / 30-60 / >90 days inactive users

Posted on 2013-12-03
6
Medium Priority
?
3,305 Views
Last Modified: 2013-12-05
So I have this script I've been playing with... the goal is to do some basic AD auditing.  I'm using both Microsoft AD cmd-lets and the Quest cmd-lets (I find both have their place).

What I really need to make sure of is my logic for finding users that are inactive for 30 days, then inactive form 30-60 days, then inactive over 90 days.

The script will output:

- New accounts created in last seven days
- Groups modified in last seven days
- 30/30-60/90 and over inactive users
- Report user accounts that have never logged on to their account
- Send an email

Yeah, I know the attach as a text file is somewhat kludgy, but it works for these purposes.

Can someone take a look at the <30 / 30-60 / >90 logic strings and tell me what would work better, I'm not sure my results are accurate or my logic is correct.

# Prepare loading required modules

import-module activedirectory
Add-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue

# Prepare and output file for mailing

$OutputfilePath = "C:\ADUserAudit-"+([datetime]::Now).tostring("yyyyMMdd")+".txt"


# Accounts created this week

$When = ((Get-Date).AddDays(-7)).Date
 
$UsersCreatedLastWeek = (Get-ADUser -Filter {whenCreated -ge $When} -Properties whenCreated) | select samaccountname,name,distinguishedname
$UsersCreatedLastWeekTable = ($UsersCreatedLastWeek | format-table) 

# Groups Modified this week

$When = ((Get-Date).AddDays(-7)).Date
 
$GroupsModifiedLastWeek = (Get-ADGroup -Filter {whenChanged -ge $When} -Properties whenChanged) | select samaccountname,name,distinguishedname 
$GroupsModifiedLastWeekTable =  ($GroupsModifiedLastWeek | format-table)


# List all users in that have not logged on within 
# XXX days in "Active Directory" 
#  
# Get the Current Date 
#  
$CURRENTDATE=GET-DATE 
# 
# Number of Days to check back.   
#  
$NumberDays=30 
# 
# Organizational Units to search 
# 

$OUList = "OU=Users,OU=company,DC=com","OU=Users2,OU=company,DC=com"

# Prepare arrays for totals

$30Days = @()
$60Days = @()
$90Days = @()

ForEach ($OU in $OUList) 
    {

    #LastLogon.AddDays() adds x number of days making the users lastlogon x number of days into the future (e.g. Sep 28th somes October 27th...)

    $30Days += (GET-QADUSER -SearchRoot $OU | where { $_.LastLogon.AddDays(30) -lt $CURRENTDATE}) | select samaccountname,Name,DN

    $60Days += (GET-QADUSER -SearchRoot $OU | where { ($_.LastLogon.AddDays(60) -lt $CURRENTDATE -and $_.LastLogon.AddDays(60) -lt ($CURRENTDATE.AddDays(-30))) }) | select samaccountname,Name,DN

    $90Days += (GET-QADUSER -SearchRoot $OU | where { ($_.LastLogon.AddDays(90) -lt $CURRENTDATE -and $_.LastLogon.AddDays(90) -lt ($CURRENTDATE.AddDays(-30))) }) | select samaccountname,Name,DN
    
 
    }

$30DaysTable = ($30Days | format-table)
$60DaysTable = ($60Days | format-table)
$90DaysTable = ($90Days | format-table)

# Get users that have never logged in, but use Windows AD Powershell cmdlets as it should look at all domain controllers. Not restricted to OU:

$NeverBeenKissed = get-aduser -f {-not ( lastlogontimestamp -like "*") -and (enabled -eq $true)} | select samaccountname,name,distinguishedname

$NeverBeenKissedTable = $NeverBeenKissed | format-table
 
# Write to a file

Out-File $OutputfilePath

Add-Content -Path $OutputfilePath "Users Created in the Last Week:"
Add-Content -Path $OutputfilePath " "
$UsersCreatedLastWeekTable | Out-File $OutputfilePath -append
Add-Content -Path $OutputfilePath "Groups Modified in the Last Week:"
Add-Content -Path $OutputfilePath " "
$GroupsModifiedLastWeekTable | Out-File $OutputfilePath -append
Add-Content -Path $OutputfilePath "Users not logged in for 30 days:"
Add-Content -Path $OutputfilePath " "
$30DaysTable | Out-File $OutputfilePath -append
Add-Content -Path $OutputfilePath "Users not logged in for 60-90 days:"
Add-Content -Path $OutputfilePath " "
$60DaysTable | Out-File $OutputfilePath -append
Add-Content -Path $OutputfilePath "Users not logged in for over 90 days:"
Add-Content -Path $OutputfilePath " "
$90DaysTable | Out-File $OutputfilePath -append
Add-Content -Path $OutputfilePath "Users who have NEVER logged in!:"
Add-Content -Path $OutputfilePath " "
$NeverBeenKissedTable | Out-File $OutputfilePath -append

# Send it in email as an attachment, since it's not as simple to port it into an email yet.

$smtpServer = “hub.company.com”

Send-MailMessage -To "person@company.com” -Subject “AD User Audit 30/60/90” -From “PowerShellAudit@company.com” -Body “Current AD User Audit is attached.” -Priority High -SmtpServer $smtpServer -Attachments $OutputfilePath

Open in new window

0
Comment
Question by:gerhardub
[X]
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
  • 3
  • 2
6 Comments
 
LVL 40

Expert Comment

by:Subsun
ID: 39694056
You can try with Search-ADAccount to search the inactive accounts.. for example..

$30  = Search-ADAccount -UsersOnly -AccountInactive -TimeSpan 30
$3060 = Search-ADAccount -UsersOnly -AccountInactive -TimeSpan 60 | ?{($30 | Select -ExpandProperty Samaccountname) -notcontains $_.Samaccountname}
$90 = Search-ADAccount -UsersOnly -AccountInactive -TimeSpan 90

Open in new window

0
 
LVL 41

Accepted Solution

by:
footech earned 2000 total points
ID: 39694175
What I really need to make sure of is my logic for finding users that are inactive for 30 days, then inactive form 30-60 days, then inactive over 90 days
This says to me - find the users;
 - who haven't logged in in the last 30 days, so last logon date must be greater than 30
 - whose last logon was between 30 and 60 days ago
 - whose last logon was greater than 90 days ago

The first two are pretty much the same, the second just has an additional limit placed on it.  And what about last logon between 60 and 90 days ago?

Your script logic is pretty convoluted (and a little different than my understanding of what you want).  The first will get users whose last logon was greater then 30 days ago.  The second will get users whose last logon was between 30 and 60 days ago.  The third will get users whose last logon was between 30 (I think you meant 60 here) and 90 days ago.

In addition to Search-ADAccount you could also do something like the following:
$lt30 = @()
$30Days = @()
$60Days = @()
$90Days = @()

$now = Get-Date
ForEach ($OU in $OUList) 
{
        Get-ADUser -filter * -Properties LastLogonDate -SearchBase $OU | ForEach `
    {
        If ( $_.LastLogonDate -gt $now.AddDays(-30) )
        { $lt30 += $_ | Select samaccountname,Name,DistinguishedName }
        ElseIf ( $_.LastLogonDate -lt $now.AddDays(-30) -and $_.LastLogonDate -gt $now.AddDays(-60) )
        { #another way to do the same thing
          $30Days += New-Object PsObject -Property @{ samaccountname = $_.samaccountname; Name = $_.name; DN = $_.DistinguishedName }
        }
        ElseIf ( $_.LastLogonDate -lt $now.AddDays(-60) -and $_.LastLogonDate -gt $now.AddDays(-90) )
        { $60Days += $_ | Select samaccountname,Name,DistinguishedName }
        ElseIf ( $_.LastLogonDate -lt $now.AddDays(-90) )
        { $90Days += $_ | Select samaccountname,Name,DistinguishedName }
    }
}

Open in new window

0
 
LVL 1

Author Comment

by:gerhardub
ID: 39694411
Folks ,

You rock.... Let me plug these in and play in the AM... I'll get back to you tomorrow!
0
Looking for the Wi-Fi vendor that's right for you?

We know how difficult it can be to evaluate Wi-Fi vendors, so we created this helpful Wi-Fi Buyer's Guide to help you find the Wi-Fi vendor that's right for your business! Download the guide and get started on our checklist today!

 
LVL 1

Author Comment

by:gerhardub
ID: 39695312
Interestingly, the Search-ADAccount cmdlet gave me false results.  It was odd... $30 and $90 were exactly the same, $60 had zero results.... which makes sense in hindsight.


FooTech: Your understanding of what I really needed worked great.  The arrays literally break out the users from time as I needed, and then allowed me to break it out in a text based report that ended with 7/7/30/60/90 and "never been kissed." -grin-

Thanks for that... you've just saved me a ton of time, and I learned something from both of you.  I need to brush up on my Powershell logic... and revisit the cmdlets.

I'll open another ticket if either of your want 500 points toward figuring out how to format it in HTML and send that in an email! Let me know!

GB
0
 
LVL 1

Author Closing Comment

by:gerhardub
ID: 39695317
Fantastic level of help... I can't thank you enough... and I'm a hardass.
0
 
LVL 41

Expert Comment

by:footech
ID: 39699387
Glad I could help.

One thing to keep in mind if you want to explore the use of Search-ADAccount, when specifying a timespan to indicate days you should enclose the number in quotes.  So
Search-ADAccount -UsersOnly -AccountInactive -TimeSpan 30
would have a timespan of 30 ticks, and
Search-ADAccount -UsersOnly -AccountInactive -TimeSpan "30"
would have a timespan of 30 days.  You could also write it like
Search-ADAccount -UsersOnly -AccountInactive -TimeSpan 30.0:0
When written like this the quotes are optional.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

This process allows computer passwords to be managed and secured without using LAPS. This is an improvement on an existing process, enhanced to store password encrypted, instead of clear-text files within SQL
Active Directory can easily get cluttered with unused service, user and computer accounts. In this article, I will show you the way I like to implement ADCleanup..
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

718 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