사용자가 로컬로 또는 터미널 서버를 통해 로그온 할 때 HKEY_USERS 아래에서 레지스트리 하이브에 액세스해야하는 Windows 서비스가 있습니다. win32_logonsession에서 WMI 쿼리를 사용하여 사용자가 로그온 할 때 이벤트를 수신하고 그 쿼리에서 얻은 속성 중 하나가 LogonId입니다. 액세스해야하는 레지스트리 하이브를 파악하려면 HKEY_USERS 아래에 레지스트리 키 이름으로 사용되는 사용자의 SID가 필요합니다.로그온 ID에서 사용자 SID 가져 오기 (Windows XP 이상)
대부분의 경우에, 나는 같은 (C#에서)를 RelatedObjectQuery를 수행하여이를 얻을 수 있습니다 : "logonID는"세션 쿼리의 로그온 세션 ID입니다
RelatedObjectQuery relatedQuery = new RelatedObjectQuery("associators of {Win32_LogonSession.LogonId='" + logonID + "'} WHERE AssocClass=Win32_LoggedOnUser Role=Dependent");
. RelatedObjectQuery를 실행하면 일반적으로 내가 필요한 것을 정확하게 포함하는 SID 속성을 얻을 수 있습니다.
두 가지 문제점이 있습니다. 가장 중요한 점은, RelatedObjectQuery는 도메인에서 연결이 끊긴 캐시 된 자격 증명으로 로그인하는 도메인 사용자의 결과를 반환하지 않습니다. 둘째,이 RelatedObjectQuery의 성능에 만족하지 않습니다. 실행하는 데 최대 몇 초가 걸릴 수 있습니다.
다음은 쿼리를 실험하기 위해 함께 던진 빠르고 지저분한 명령 줄 프로그램입니다. 오히려 이벤트를 수신하도록 설정하는 것보다, 이것은 단지 로컬 시스템에 대한 사용자 열거 :
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와 같은 것을 사용하려고합니다.
중복 가능성 [C#에서 SID 열을 자명 변환 /. NET (http://stackoverflow.com/questions/1040623/convert-a-username-to-a-sid-string- in-c-net) – Richard