获取用户SID从登录ID(Windows XP和上) [英] Get User SID From Logon ID (Windows XP and Up)

查看:588
本文介绍了获取用户SID从登录ID(Windows XP和上)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要访问在HKEY_USERS注册表配置单元当用户登录时,在本地或通过终端服务器的Windows服务。我使用WMI查询win32_logonsession接收事件当用户登录时,我从该查询得到的属性之一是LogonID的。为了找出我需要访问的注册表配置单元,现在,我需要的用户的SID,这是用来作为下HKEY_USERS注册表项的名称。

I have a Windows service that needs to access registry hives under HKEY_USERS when users log on, either locally or via Terminal Server. I'm using a WMI query on win32_logonsession to receive events when users log on, and one of the properties I get from that query is a LogonId. To figure out which registry hive I need to access, now, I need the users's SID, which is used as a registry key name beneath HKEY_USERS.

在大多数情况下,我可以做这样所以RelatedObjectQuery(在C#)得到这样的:

In most cases, I can get this by doing a RelatedObjectQuery like so (in C#):

RelatedObjectQuery relatedQuery = new RelatedObjectQuery( "associators of {Win32_LogonSession.LogonId='" + logonID + "'} WHERE AssocClass=Win32_LoggedOnUser Role=Dependent" );

其中LogonID的是从会话查询的登录会话ID。运行RelatedObjectQuery包含正是我需要的一般给我一个SID属性。

where "logonID" is the logon session ID from the session query. Running the RelatedObjectQuery will generally give me a SID property that contains exactly what I need.

有两个问题我都与此有关。首先,也是最重要的是,RelatedObjectQuery不会返回任何结果,记录在缓存凭据,从域断开的域用户。其次,我不喜欢这种RelatedObjectQuery的性能 - 它最多可能需要几秒钟来执行。

There are two issues I have with this. First and most importantly, the RelatedObjectQuery will not return any results for a domain user that logs in with cached credentials, disconnected from the domain. Second, I'm not pleased with the performance of this RelatedObjectQuery --- it can take up to several seconds to execute.

下面是一个快速和肮脏的命令行程序,我扔在一起,尝试查询。而不是设置为接收事件,这只是列举了用户在本地计算机上:

Here's a quick and dirty command line program I threw together to experiment with the queries. Rather than setting up to receive events, this just enumerates the users on the local machine:

using System;
using System.Collections.Generic;
using System.Text;
using System.Management;

namespace EnumUsersTest
{
    class Program
    {
        static void Main( string[] args )
        {
            ManagementScope scope = new ManagementScope( "\\\\.\\root\\cimv2" );

            string queryString = "select * from win32_logonsession";                          // for all sessions
            //string queryString = "select * from win32_logonsession where logontype = 2";     // for local interactive sessions only

            ManagementObjectSearcher sessionQuery = new ManagementObjectSearcher( scope, new SelectQuery( queryString ) );
            ManagementObjectCollection logonSessions = sessionQuery.Get();
            foreach ( ManagementObject logonSession in logonSessions )
            {
                string logonID = logonSession["LogonId"].ToString();
                Console.WriteLine( "=== {0}, type {1} ===", logonID, logonSession["LogonType"].ToString() );
                RelatedObjectQuery relatedQuery = new RelatedObjectQuery( "associators of {Win32_LogonSession.LogonId='" + logonID + "'} WHERE AssocClass=Win32_LoggedOnUser Role=Dependent" );
                ManagementObjectSearcher userQuery = new ManagementObjectSearcher( scope, relatedQuery );
                ManagementObjectCollection users = userQuery.Get();
                foreach ( ManagementObject user in users )
                {
                    PrintProperties( user.Properties );
                }
            }

            Console.WriteLine( "\nDone! Press a key to exit..." );
            Console.ReadKey( true );
        }


        private static void PrintProperty( PropertyData pd )
        {
            string value = "null";
            string valueType = "n/a";
            if ( pd.Value != null )
            {
                value = pd.Value.ToString();
                valueType = pd.Value.GetType().ToString();
            }

            Console.WriteLine( "  \"{0}\" = ({1}) \"{2}\"", pd.Name, valueType, value );
        }


        private static void PrintProperties( PropertyDataCollection properties )
        {
            foreach ( PropertyData pd in properties )
            {
                PrintProperty( pd );
            }
        }
    }
}

所以...有没有办法快速,可靠地获取给定的,我从WMI检索信息的用户的SID,或者我应该考虑使用类似SENS呢?

So... is there way to quickly and reliably obtain the user SID given the information I retrieve from WMI, or should I be looking at using something like SENS instead?

推荐答案

我问<一个href="http://stackoverflow.com/questions/2365367/how-to-access-hkcu-registry-of-currently-logged-on-users-from-a-service">a非常类似的问题的一段时间回来,得到这样的回答:的如何从一个Windows用户名一个SID。

I asked a very similar question a while back and got this answer: how to get a SID from a windows username.

我正打算使用SystemEvents当用户登录到Windows检测,然后通过登录的用户列表循环,在这一点上,以检测所有登录的用户。 (<一href="http://stackoverflow.com/questions/2077958/how-to-determine-the-current-windows-user-from-a-windows-service">Here's我的问题,这一切,包括用于检测登录和当前用户参考。)

I was planning on using SystemEvents to detect when a user logs on to windows, then looping through the logged on users list at that point to detect all the logged on users. (Here's my question, about all this including references for detecting logons and current users.)

如果您决定的方法,请发布更新 - 我很想听听你发现效果很好

If you decide on an approach please post an update - I'd be interested to hear what you find works well.

这篇关于获取用户SID从登录ID(Windows XP和上)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆