为什么我无法从 WMI 查询中获取登录会话?

为什么我无法从 WMI 查询中获取登录会话?

我正在编写一个程序,其功能之一是获取 Windows 计算机上的当前登录会话。它查询 WMI 以获取登录类型 2(交互式)、登录类型 10(远程交互式)和登录类型 11(缓存交互式)的当前会话。我拥有的代码运行正常,除了我刚刚注意到的一件事。当我在工作域环境中测试它时,一切都很好,但现在我在家里并在工作网络之外登录时,我根本没有获得任何会话——我以为我会将我的登录会话作为缓存交互式会话获得。

所以我用这个 PS 代码测试了它本网站

$computername = "mycomputername"
Get-WmiObject -Class Win32_LogonSession -ComputerName $computername |            
foreach {            
 $data = $_            

 $id = $data.__RELPATH -replace """", "'"            
 $q = "ASSOCIATORS OF {$id} WHERE ResultClass = Win32_Account"            
 Get-WmiObject -ComputerName $computername -Query $q |            
 select @{N="User";E={$($_.Caption)}},             
 @{N="LogonTime";E={$data.ConvertToDateTime($data.StartTime)}}            
}         

只需全部登录会话。同样,我好像根本没有登录过:

用户登录时间
---- ---------
我的计算机名称\IUSR 2016 年 1 月 22 日 上午 12:07:50
我的计算机名称\SYSTEM 2016 年 1 月 22 日 上午 12:07:09
我的计算机名称\LOCAL SERVICE 2016 年 1 月 22 日 上午 12:07:11
我的计算机名称\NETWORK SERVICE 2016 年 1 月 22 日 上午 12:07:10
我的计算机名称\ANONYMOUS LOGON 2016 年 1 月 22 日 上午 12:08:03

我的实际用户名没有显示...为什么会这样?我该怎么做才能看到我的登录会话?

答案1

为什么它不工作?

根据这篇微软博客文章,当域无法访问时,您的查询无法检索有关域用户帐户的信息。这是因为Win32_Account具有需要域控制器信息来填充的属性。因此,实例的构建Win32_Account失败,相关条目不会出现在您的结果中。

我们能做什么?

这确实是一件令人沮丧的事,但当你无法与某个域通信时,你需要解析类Antecedent的字符串才能可靠地获取该帐户的名称。帐户名称位于和之间,如 的输出所示。我相信你可以用正则表达式做得更好,但这是我快速而粗略地打印所有登录会话的用户名的方法:Win32_LoggedOnUserName=""gwmi -class Win32_LoggedOnUser

gwmi -Query "select * from win32_loggedonuser" | ForEach-Object { (($_.Antecedent -Split "Name=`"")[1] -Split "`"")[0] }

(由于我在这里与实际的控制台会话没有关联,因此会有几个像这样的松散的虚假用户DWM-1。)

答案2

也可以使用终端服务器命令询问

查询实用程序用于显示系统的当前信息,例如当前的资源分配和系统状态。查询命令可以调用任何一个查询实用程序。命令行格式为:

query [appservers | object | process | session | user] [/?]

此命令将获取所有登录用户的列表:

query user

对于本地登录,结果可能看起来像这样,但我还针对远程登录进行了验证:

图像

相关内容