Usually when querying the logon history of a Windows system you might query the Security event log or a domain controller. But if you’re using SCCM, the SCCM client also logs user logon events and stores them in WMI. Here’s a quick PowerShell script to retrieve those events and translate them into meaningful values.
You can run it against the local or a remote computer and optionally specify the maximum number of events to retrieve.
Note that for remote computers the date/time values will be displayed in your local time zone, not necessarily the timezone of the remote system.
Get-CMUserLogonEvents | Sort LogonTime -Descending | Out-GridView

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Get-CMUserLogonEvents { | |
[CmdletBinding()] | |
Param | |
( | |
[Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] | |
$ComputerName, | |
[Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] | |
$MaximumEvents = 50 | |
) | |
If ($ComputerName) | |
{ | |
[array]$LastLogons = Get-WmiObject –ComputerName $ComputerName –Namespace ROOT\CCM –Class CCM_UserLogonEvents | Select –last $MaximumEvents | |
} | |
Else | |
{ | |
[array]$LastLogons = Get-WmiObject –Namespace ROOT\CCM –Class CCM_UserLogonEvents | Select –last $MaximumEvents | |
} | |
Foreach ($Logon in $LastLogons) | |
{ | |
If ($Logon.LogoffTime -ne $null) | |
{ | |
[pscustomobject]@{ | |
LogonTime = [System.TimeZoneInfo]::ConvertTimeFromUtc(([datetime]::new(1970,01,01,00,00,00,[System.DateTimeKind]::Utc)).AddSeconds($Logon.LogonTime),[System.TimeZoneInfo]::Local) | |
LogoffTime = [System.TimeZoneInfo]::ConvertTimeFromUtc(([datetime]::new(1970,01,01,00,00,00,[System.DateTimeKind]::Utc)).AddSeconds($Logon.LogoffTime),[System.TimeZoneInfo]::Local) | |
User = [System.Security.Principal.SecurityIdentifier]::new($Logon.UserSID).Translate([System.Security.Principal.NTAccount]).Value | |
DurationInHours = [math]::Round([System.TimeSpan]::FromSeconds(($Logon.LogoffTime – $Logon.LogonTime)).TotalHours,2) | |
} | |
} | |
Else | |
{ | |
[pscustomobject]@{ | |
LogonTime = [System.TimeZoneInfo]::ConvertTimeFromUtc(([datetime]::new(1970,01,01,00,00,00,[System.DateTimeKind]::Utc)).AddSeconds($Logon.LogonTime),[System.TimeZoneInfo]::Local) | |
LogoffTime = $null | |
User = [System.Security.Principal.SecurityIdentifier]::new($Logon.UserSID).Translate([System.Security.Principal.NTAccount]).Value | |
DurationInHours = [math]::Round(((Get-Date) – ([System.TimeZoneInfo]::ConvertTimeFromUtc(([datetime]::new(1970,01,01,00,00,00,[System.DateTimeKind]::Utc)).AddSeconds($Logon.LogonTime),[System.TimeZoneInfo]::Local))).TotalHours,2) | |
} | |
} | |
} | |
} |
This is exactly what I was looking for. Do you mind if I add this script to my device scanner project (https://github.com/MikePohatu/DevChecker)?
Glad it helped…be my guest 🙂
Where do you run this powershell script from to collect this data?
On any MEMCM client