我希望能够像PSGetSID一样检索本地计算机的SID 来自Sysinternals但使用C#的实用程序。 这可能吗?
编辑: 我正在寻找适用于可能是或可能不是域成员的计算机的解决方案。
答案 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)
本地用户帐户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();
}