Noam's scripting blog

"Ready to use" scripts and scripting tips for system admins with detailed walkthroughs/explanations.

Sidebar

Recent Posts

  • Powershell – Split PFX certificates April 3, 2017
  • Remove a VMFS datastore using powershell August 13, 2014
  • Get windows time settings from remote servers July 31, 2014
  • Logoff RDP sessions on multiple servers July 22, 2014
  • Synchronize folder/directory contents June 10, 2014
Follow Noam's scripting blog on WordPress.com
  • Home
  • About Me

AD

Powershell – Get obsolete active directory users and export results to CSV

Standard

When maintaining and cleaning up your active directory it can be useful to know if any user accounts have become obsolete. Account of users who have left the company and old application accounts may still exist in your active directory causing a mess and/or potential gaps in your security. With this script you can scan the active directory for user accounts who haven’t authenticated or logged in for a given number of days. The results will be exported to a CSV file which will allow you to review the results and take any appropriate actions.
I have divided the script into two sections “variables” and “script main” which I will go over below.

Variables

#VARIABLES
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath #$dir is the path to the directory which the script is being run from
$outputFile =  "$dir\$(get-date -format "yyyy-MM-dd HH-mm-ss")_ObsoleteUsers.csv"
#parameters
$DaysBack = 30 #Gets users who haven't logged in for this number of days

$outputFile is the path of the CSV file which will be created each time you run the script. It includes a time stamp for future reference and to avoid overwriting.
Before running the script you need to set the $DaysBack parameter to the desired number of days.

Script Main

#SCRIPT MAIN
if (-not(Get-Module -name "activedirectory")) {    
Import-Module ActiveDirectory | out-null
}
$Date = (Get-Date).addDays(-$DaysBack)
$Users = @() #Create blank array to hold users who haven't logged in for $DaysBack days		 
	Get-ADUser -filter {(LastLogon -le $Date) -and (Name -like "*")} -Properties Lastlogon,whenCreated | % {			
	$LastLogon = $_.LastLogon
	$LastLogon_DT = [datetime]::FromFileTime("$LastLogon") #convert logon time to a datetime object
	$User = "" | select Name,LastLogon,FullName,WhenCreated #creating a custom object
	$User.Name = $_.SamAccountName 
	$User.LastLogon = $LastLogon_DT
	$User.FullName = $_.Name
	$User.WhenCreated = $_.WhenCreated
	$Users += @($User) #Add user to $Users array		
}
$ObsoleteUsers = $Users | sort-object Lastlogon #sorting results by last logon time
$ObsoleteUsers | Export-CSV $outputFile -force -NoTypeInformation #Export results to CSV in script directory

The first thing to happen is that the active directory module for powershell is imported (if not already imported). I then create the blank array $users to hold results of the coming AD search. The cmdlet Get-ADUser is then used to get the users who haven’t authenticated/logged on for $DaysBack days. For each user found, a custom object with the properties “name”, “lastlogon”, “fullname” and “whencreated” is created and added to the $users array. The results are then sorted by last logon time and then exported to a CSV file.
I have copied in the full script below. I hope you find this script useful!

##################################################################################################################
##Script:			Get-ObsoleteUsers.ps1
##Description: 		Gets users in the active directory who haven't logged in for a given number of days (specified
#+					in the parameter $DaysBack) and then exports the results to CSV.
##Created by: 		Noam Wajnman
##Creation Date: 	March 5, 2013
##Updated:			March 31, 2014
###################################################################################################################
#VARIABLES
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
$outputFile =  "$dir\$(get-date -format "yyyy-MM-dd HH-mm-ss")_ObsoleteUsers.csv"
#parameters
$DaysBack = 30 #Gets users who haven't logged in for this number of days
#SCRIPT MAIN
if (-not(Get-Module -name "activedirectory")) {    
Import-Module ActiveDirectory | out-null
}
$Date = (Get-Date).addDays(-$DaysBack)
$Users = @() #Create blank array to hold users who haven't logged in for $DaysBack days		 
	Get-ADUser -filter {(LastLogon -le $Date) -and (Name -like "*")} -Properties Lastlogon,whenCreated | % {			
	$LastLogon = $_.LastLogon
	$LastLogon_DT = [datetime]::FromFileTime("$LastLogon") #convert logon time to a datetime object
	$User = "" | select Name,LastLogon,FullName,WhenCreated #creating a custom object
	$User.Name = $_.SamAccountName 
	$User.LastLogon = $LastLogon_DT
	$User.FullName = $_.Name
	$User.WhenCreated = $_.WhenCreated
	$Users += @($User) #Add user to $Users array		
}
$ObsoleteUsers = $Users | sort-object Lastlogon #sorting results by last logon time
$ObsoleteUsers | Export-CSV $outputFile -force -NoTypeInformation #Export results to CSV in script directory
Advertisement

Share this:

  • Facebook
  • Twitter
  • Print
  • Email

Like this:

Like Loading...
  • Date March 31, 2014
  • Tags accounts, active directory, ActiveDirectory, AD, csv, CSV file, last login, last logon, lastlogon, logon date, obsolete users, powershell, script, user accounts, users
  • Comments 2 Comments

Powershell – Get locked out AD user accounts and export to CSV

Standard

Keeping track of locked out accounts is important. Furthermore it can be important to know where and when an account was locked out. For instance the source of the lockout can be important to know if one of your users is complaining that his account is being locked but he doesn’t know why.
This script scans the event log of your DC and gets all lockout events and then exports them to a CSV. If you run this script regularly with the task scheduler you can document all locked out accounts along with the time and source of the lockouts.
I have split the script into three sections variables, functions and script main.

Variables

#VARIABLES
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath #path to the directory from which the script is run.
$after = (get-date).addHours(-1) #time back to search the event log
$lockoutEventID = 4740 #event id of lockout
#parameters
$DC = "SomeDC" #Name of domain controller to scan event logs on 

It is important to remember to enter the name of your DC in $DC in the parameters section. The rest can be left as is.

Functions

1. Function Get-LockoutEvents

function Get-LockoutEvents {
	param(
		$after,
		$lockoutEventID,
		$computerName = $env:COMPUTERNAME
	)
	$lockoutEvents = @(Get-EventLog -LogName "Security" -After $after -ComputerName $computerName | Where-Object {$_.EventID -eq $lockoutEventID})
	return $lockoutEvents
}

Get-LockoutEvents uses the powershell cmd-let Get-EventLog to scan the event log on the specified computer $computerName (should be a domain controller). It then returns an array containing the events found.
2. Function Parse-LockoutEvent

function Parse-LockoutEvent {
	param(
		$lockoutEvent
	)
	$EventTxt = $lockoutEvent.Message
	$bool = $EventTxt -match "(.*?)(Account That Was Locked Out:)[\S\s]+Account Name:[\s]+?(\w+)"
	$lockoutUser = $Matches[3]
	$lockoutTime = $lockoutEvent.TimeGenerated
	$lockoutSource = $lockoutEvent.Source
    $lockoutMessage = $lockoutEvent.Message -creplace "`n|`r",""    
	$lockoutMessage = $lockoutMessage -creplace "`t"," "
    
	$lockout = "" | select "User","Time","Source","Message"
	$lockout.User = $lockoutUser
	$lockout.Time = $lockoutTime
	$lockout.Source = $lockoutSource
    $lockout.Message = $lockoutMessage
	Return $lockout
}

This function takes a lockout event as a parameter and parses the most relevant parts to readable information. It returns a custom object with four properties user, time, source and message. User is the locked out user account. Time is the time of the lockout. Source is the entity which locked out the account. Message is the message text of the event which also normally includes the name/IP of where the account was locked out (in other words where the bad passwords were entered).
3. ExportToFile-LockoutEvents

function ExportToFile-LockoutEvents {
	param(
		$lockouts
	)
	$datestr = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
	$fileName = "$dir\Lockouts--$datestr.csv"
	$lockouts | Export-Csv $fileName -NoTypeInformation
}

This little function simply takes an array of parsed lockoutevents and exports it to a CSV file with a time stamp.

Script Main

#SCRIPT MAIN
$lockouts = @()
$lockoutEvents = Get-LockoutEvents -after $after -lockoutEventID $lockoutEventID
if ($lockoutEvents) {
	$lockoutEvents | % {	
	    $lockout = Parse-lockoutEvent -lockoutEvent $_
		$lockouts += @($lockout)
	}
	$lockouts #print the lockout events to the console
	ExportToFile-LockoutEvents -lockouts $lockouts #export the lockout events to CSV
}

In the script main I start by creating the blank array $lockouts. I then use the function Get-LockoutEvents to get the information and store it in another object called $lockoutEvents. If any lockout events were found they are parsed and then added to the array $lockouts which is then exported to a CSV file (and printed to the console window).
I have copied in the full script below. Enjoy!

##################################################################################################################
##Script:			Get-LockedOutAccounts.ps1
##Description: 		Script gets lockout events from the event log and parses them before exporting to CSV.
##Usage:			
##Created by:		Noam Wajnman
##Creation Date:	March 5, 2014
###################################################################################################################
#VARIABLES
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath #path to the directory from which the script is run.
$after = (get-date).addHours(-1) #time back to search the event log
$lockoutEventID = 4740 #event id of lockout
#parameters
$DC = "SomeDC" #Name of domain controller to scan event logs on
#FUNCTIONS
function Get-LockoutEvents {
	param(
		$after,
		$lockoutEventID,
		$computerName = $env:COMPUTERNAME
	)
	$lockoutEvents = @(Get-EventLog -LogName "Security" -After $after -ComputerName $computerName | Where-Object {$_.EventID -eq $lockoutEventID})
	return $lockoutEvents
}
function Parse-LockoutEvent {
	param(
		$lockoutEvent
	)
	$EventTxt = $lockoutEvent.Message
	$bool = $EventTxt -match "(.*?)(Account That Was Locked Out:)[\S\s]+Account Name:[\s]+?(\w+)"
	$lockoutUser = $Matches[3]
	$lockoutTime = $lockoutEvent.TimeGenerated
	$lockoutSource = $lockoutEvent.Source
    $lockoutMessage = $lockoutEvent.Message -creplace "`n|`r",""    
	$lockoutMessage = $lockoutMessage -creplace "`t"," "
    
	$lockout = "" | select "User","Time","Source","Message"
	$lockout.User = $lockoutUser
	$lockout.Time = $lockoutTime
	$lockout.Source = $lockoutSource
    $lockout.Message = $lockoutMessage
	Return $lockout
}
function ExportToFile-LockoutEvents {
	param(
		$lockouts
	)
	$datestr = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
	$fileName = "$dir\Lockouts--$datestr.csv"
	$lockouts | Export-Csv $fileName -NoTypeInformation
}
#SCRIPT MAIN
$lockouts = @()
$lockoutEvents = Get-LockoutEvents -after $after -lockoutEventID $lockoutEventID
if ($lockoutEvents) {
	$lockoutEvents | % {	
	    $lockout = Parse-lockoutEvent -lockoutEvent $_
		$lockouts += @($lockout)
	}
	$lockouts #print the lockout events to the console
	ExportToFile-LockoutEvents -lockouts $lockouts #export the lockout events to CSV
}

Share this:

  • Facebook
  • Twitter
  • Print
  • Email

Like this:

Like Loading...
  • Date March 30, 2014
  • Tags account, active directory, AD, domain controller, event log, locked, lockout source, lockout time, powershell, script, user, users, windows
  • Comments 1 Comment
Create a free website or blog at WordPress.com.
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy
  • Follow Following
    • Noam's scripting blog
    • Join 39 other followers
    • Already have a WordPress.com account? Log in now.
    • Noam's scripting blog
    • Customize
    • Follow Following
    • Sign up
    • Log in
    • Report this content
    • View site in Reader
    • Manage subscriptions
    • Collapse this bar
%d bloggers like this: