如何使用C#检索本地机器SID?

时间:2010-09-29 14:21:41

标签: c#

我希望能够像PSGetSID一样检索本地计算机的SID 来自Sysinternals但使用C#的实用程序。 这可能吗?

编辑: 我正在寻找适用于可能是或可能不是域成员的计算机的解决方案。

4 个答案:

答案 0 :(得分:3)

这有一个很好的帮助类来使用lookupaccountname win32 api调用。

get machine SID (including primary domain controller)

我没有找到使用原生C#

的方法

答案 1 :(得分:0)

你可以通过pinvoke来实现它,只需从Win32 API中获取它。

http://www.pinvoke.net/default.aspx/advapi32.lookupaccountname

也许有一种方法可以在“纯粹的”.NET中获得它。

答案 2 :(得分:0)

来自用户ewall的另一篇SO帖子有一个纯.NET解决方案,其中包含C#和PowerShell中的示例。它使用DirectoryEntry和SecurityDescriptor对象。看到: How can I retrieve a Windows Computer's SID using WMI?

答案 3 :(得分:0)

SIDs文件:
https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/security-identifiers

本地用户帐户SID表格: S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxxx-yyyy
系统特定部分: xxx ... xxx
用户帐户特定部分: yyyy
因此,您只需要从用户帐户SID中删除最后一组数字即可获得系统SID。

如果您的代码是 Windows应用程序,则可以通过这种方式获取系统SID:

using System.Security.Principal;  

string systemSid;  
using (WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent())  
{  
    systemSid = windowsIdentity.User.Value.Substring(0, windowsIdentity.User.Value.LastIndexOf('-'));  
}  

如果您的代码是 Web应用程序,它通常在应用程序池标识的上下文中运行,如果您的代码是 Windows服务,它通常在上下文中运行系统帐户(系统,本地服务,网络服务)。这些身份都不是用户帐户。所以你不能使用上面的代码。您需要知道用户帐户名称或列出用户帐户。

如果您知道用户帐户名,则可以通过以下方式获取系统SID:

using System.Security.Principal;  

NTAccount ntAccount = new NTAccount("MACHINE_NAME\\UserAccountName");  
SecurityIdentifier sid = (SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier));  
string systemSid = sid.Value.Substring(0, sid.Value.LastIndexOf('-'));  

但你不能假设标准用户的名字,比如" guest"因为标准本地用户帐户名已本地化,因为此标准用户帐户可能已被删除,并且因为在将来的Windows版本中可能会禁止使用标准用户帐户。
因此,大多数情况下,从Web应用程序或Windows服务,您需要通过WMI列出用户帐户:

//  your project must reference System.Management.dll  
using System.Management;  

SelectQuery selectQuery = new SelectQuery("SELECT * FROM Win32_UserAccount");  
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(selectQuery);  
string systemSid;  
foreach (ManagementObject managementObject in managementObjectSearcher.Get())  
{  
    if (1 == (byte)managementObject["SIDType"])  
    {  
        systemSid = managementObject["SID"] as string;  
        break;  
    }  
}  
systemSid = systemSid.Substring(0, systemSid.Value.LastIndexOf('-'));  

Win32_UserAccount类文档:
https://msdn.microsoft.com/en-us/library/aa394507(v=vs.85).aspx

更新

快约100倍:

using Microsoft.Win32;  

RegistryKey key = null;  
string sid = null;  

try  
{  
    foreach (string subKeyName in Registry.Users.GetSubKeyNames())  
    {  
        if(subKeyName.StartsWith("S-1-5-21-"))  
        {  
            sid = subKeyName.Substring(0, subKeyName.LastIndexOf('-'));  
            break;  
        }  
    }  
}  
catch (Exception ex)  
{  
    //  ...  
}  
finally  
{  
    if (key != null)  
        key.Close();  
}