Skip to main content

How to determine if a client on your network is locked or not.

To be able to do this in your domain will require some setup work.  First off, you need to configure a Group Policy to ensure that the proper events are being audited on your clients.  As with all Group Policy, you must make sure that the policy is scoped to reach your clients, and that you have allowed ample time for the policy to be replicated in your domain, downloaded to the clients, and applied.

Note: This will only work for client that are Windows Vista or later.

The audit policy to set is: Logon/Logoff Events with the sub category of Other Logon/Logoff Events set to capture Successful events. In your Group Policy, follow these instructions.

  • Expand Computer Configuration \ Policies \ Windows Settings \ Security Settings \ Advanced Audit Policy Configuration \ Audit Policies \ Logon/Logoff
  • Double click Audit Other Logon/Logoff Events
  • Check Configure the following audit events.
  • Check Success

image

Once this policy is applied to your clients, you will now be able to look for the following events in the security log of your clients:

 

ID Event
4649 A replay attack was detected.
4778 A session was reconnected to a Window Station.
4779 A session was disconnected from a Window Station.
4800 The workstation was locked.
4801 The workstation was unlocked.
4802

The screen saver was invoked.

4803 The screen saver was dismissed.
5378 The requested credentials delegation was disallowed by policy.
5632 A request was made to authenticate to a wireless network.
5633 A request was made to authenticate to a wired network.

We also need to enable auditing for interactive logons on your clients.

  • Expand Computer Configuration \ Policies \ Windows Settings \ Security Settings \ Advanced Audit Policy Configuration \ Audit Policies \ Logon/Logoff
  • Double click Audit Logon.
  • Check Configure the following audit events.
  • Check Success

Finally, we need to determine if the user has logged off.

  • Expand Computer Configuration \ Policies \ Windows Settings \ Security Settings \ Advanced Audit Policy Configuration \ Audit Policies \ Logon/Logoff
  • Double click Audit Logoff.
  • Check Configure the following audit events.
  • Check Success

We are interested in 3 events.  If Event 4800 is the first of the three that we come across, then the client is locked.  If event 4801 is the first, then the client has been unlocked, but the code below will detect event 4648 which will be logged right after event 4801.  Event 4801 will not be generated if the client is powered off without first unlocking and then doing a proper shutdown.  In other words there was a loss of power or the user just held the power button in until the machine forced itself to power down. For this reason, we also need to look for event 4648 which is an interactive logon.  If the client is on, but the user logged off, we need to look for event 4647.

 

A list of these audit event can be obtained at: http://support.microsoft.com/default.aspx?scid=kb;EN-US;947226

The code below is designed to me dot sourced into your current PowerShell session. Look for the Status property to see if the machine is locked, logged on, or logged off.

<#
.SYNOPSIS
Determines if a client is locked.

.DESCRIPTION
Examines a client to determine if it is locked, logged on, of logged off.

.PARAMETER ComputerName
The Name or IP address of the client to test.

.PARAMETER DaysToSearch
The number of days in history you want to examin in the clients log files. The default is 14 days.

.EXAMPLE
PS C:\Users\Administrator> Test-LockedClient lon-cli1


Status : Unlocked
TimeCreated : 8/17/2012 10:48:31 AM
TimeDiff : 00:16:58.7258484
UserName : administrator
Domain : CONTOSO

Checks the status of a client.

.EXAMPLE
PS C:\Users\Administrator> Test-LockedClient lon-cli1 -DaysToSearch 10


Status : Unlocked
TimeCreated : 8/17/2012 10:48:31 AM
TimeDiff : 00:18:02.8665857
UserName : administrator
Domain : CONTOSO

Checks the status of a client, Examining the log files back 10 days instead of the default of 14.

#>
Function Test-LockedClient
{
Param (
[cmdletbinding()]
[Parameter(Mandatory
=$True)]$ComputerName,
[
int]$DaysToSearch = 14
)


$StartTime = (Get-Date).AddDays(-($DaysToSearch))
$LogHash = @{LogName = 'Security';StartTime = $StartTime; ID=4647,4648,4800,4801}

Try
{
$Event = Get-WinEvent -FilterHashtable $LogHash -ComputerName $ComputerName -ea Stop |
Sort-Object -Property TimeCreated -Descending |
Select -First 1


}
Catch
{
Write-Host "Host offline" -ForegroundColor Red -BackgroundColor DarkRed

}

Switch ($Event.ID)
{
# User logged off'
'4647'
{
$Status = "Logged_Off"
$TimeWritten = $Event.TimeCreated
$TimeDiff = (Get-Date) - $Event.TimeCreated
$UserName = ($Event.Properties)[1].value
$Domain = ($Event.Properties)[2].value
}

# Workstation is unlocked.
'4648'
{
$Status = "Unlocked"
$TimeWritten = $Event.TimeCreated
$TimeDiff = (Get-Date) - $Event.TimeCreated
$UserName = ($Event.Properties)[5].value
$Domain = ($Event.Properties)[6].value
}

# Workstation is locked.
'4800'
{
$Status = "Locked"
$TimeWritten = $Event.TimeCreated
$TimeDiff = (Get-Date) - $Event.TimeCreated
$UserName = ($Event.Properties)[1].value
$Domain = ($Event.Properties)[2].value
}

# If no Event Returned
Default
{
$Status = "No_Data__Client my be offline."
$TimeWritten = $Null
$TimeDiff = $NULL
}
}

# Create Object to hold the output.
$Obj = New-Object PSObject

# Add member data to the object.
$Obj | Add-Member -MemberType NoteProperty -Name "Status" -Value $Status
$Obj | Add-Member -MemberType NoteProperty -Name "TimeCreated"
-Value
$TimeWritten
$Obj | Add-Member -MemberType NoteProperty -Name "TimeDiff" -Value $TimeDiff
$Obj | Add-Member -MemberType NoteProperty -Name "UserName" -Value $UserName
$Obj | Add-Member -MemberType NoteProperty -Name "Domain" -Value $Domain

# Write the object to the pipeline.
Write-Output $Obj

}

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.