How to get LogonID without accessing the network (cached logon) using WMI

Summary

This article describes a method to get UserName and LogonID without accessing the network i.e. for LogonType=11 

Here is the link to find different Logon types (Win32_LogonSession Class ):

 

msdn.microsoft.com/en-us/library/aa394189.aspx

Symptoms

1. Logon to PC without network connection. (cached logon)

2. Run the following query in wbemtest or in a script :

 

      ASSOCIATORS OF {Win32_Account.Domain='DomainName',Name='DomainUser'} WHERE AssocClass=Win32_LoggedOnUser ResultRole=Dependent

 

3. It throws an error 0x8004103A (The specified object path was invalid)

4. The query works perfectly with other Logon Types.

Cause

WMI uses several underlying Windows APIs to build the Win32_account instance. Some of these APIs require network access to accurately retrieve information about the current login token.

Without full network access, the class can not accurately retrieve user account information

Resolution

The Win32_LoggedOnUser association WMI class relates a session and a user account.

It contains two properties :

Win32_Account ref Antecedent;
Win32_LogonSession ref Dependent;

We can get the logon ID from the Win32_LogonSession and then based on that logon ID we can find the user name in the Win32_Account ref Antecedent string.

The more information sections contains a VBS example of how to use the Win32_Account Antecedent and the Win32_LogonSession dependent properties.

More Information

The Win32_LoggedOnUser association WMI class relates a session and a user account.

It contains two properties :

Win32_Account ref Antecedent;
Win32_LogonSession ref Dependent;

We can get the logon ID from the Win32_LogonSession and then based on that logon ID we can find the user name in the Win32_Account ref Antecedent string.

 

Here is a sample script to get the LogonID and UserName with Logon Type = 11 .

SAMPLE SCRIPT
==============

Set objSvc = GetObject("winmgmts:\\.\root\cimv2")

Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare

Set objLogonSession = objSvc.ExecQuery("SELECT * FROM Win32_LogonSession where logonType=11")

for each objS in objLogonSession
objList.Add objS.LogonID, objS.LogonType
Next

Set objCol = objSvc.ExecQuery("SELECT * FROM Win32_LoggedOnUser")

for each obj in objCol
Set objSession = objSvc.Get(obj.dependent)
strLogonID = objSession.LogonID
If (objList.Exists(strLogonID) = True) Then
strObjPathAccount = obj.Antecedent
strArr = Split(UCase(strobjPathAccount),"NAME=")
strMessage = "User: " & strArr(1) & vbCrLf & "Logon ID: " & strLogonID & vbCrLf & "Logon Type: " & objList(strLogonID) & vbCrLf & vbCrLf
wscript.echo strMessage
End If
strLogonID = ""
strArr = ""
strMessage = ""
next

wscript.echo "done"