使用 C# 确定 LocalSystem 帐户名

发布于 2024-07-08 09:38:13 字数 680 浏览 8 评论 0原文

我们有一个从命令行安装 SQL Server Express 的应用程序,并通过参数 SQLACCOUNT="NT AUTHORITY\SYSTEM" 将服务帐户指定为 LocalSystem 帐户。

这不适用于不同的语言,因为 LocalSystem 的帐户名不同。 这里有一个表格列出了差异:

http://forums。 microsoft.com/MSR/ShowPost.aspx?PostID=685354&SiteID=37

这似乎并不完整(未列出瑞典语版本)。 所以我希望能够以编程方式确定名称,也许使用 SID?

我找到了一些 VB 脚本来执行此操作:

Set objWMI = GetObject("winmgmts:root\cimv2") 

Set objSid = objWMI.Get("Win32_SID.SID='S-1-5-18'") 

MsgBox objSid.ReferencedDomainName & "\" & objSid.AccountName 

有谁知道可以在 C# 中使用的等效代码吗?

We have an application that installs SQL Server Express from the command line and specifies the service account as the LocalSystem account via the parameter SQLACCOUNT="NT AUTHORITY\SYSTEM".

This doesn't work with different languages because the account name for LocalSystem is different. There's a table listing the differences here:

http://forums.microsoft.com/MSR/ShowPost.aspx?PostID=685354&SiteID=37

This doesn't seem to be complete (the Swedish version isn't listed). So I'd like to be able to determine the name programmatically, perhaps using the SID?

I've found some VB Script to do this:

Set objWMI = GetObject("winmgmts:root\cimv2") 

Set objSid = objWMI.Get("Win32_SID.SID='S-1-5-18'") 

MsgBox objSid.ReferencedDomainName & "\" & objSid.AccountName 

Does anyone know the equivalent code that can be used in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

呆萌少年 2024-07-15 09:38:13

您可以使用.NET的内置 System.Security.Principal .SecurityIdentifier 类用于此目的:将其转换为 NtAccount 您可以获得帐户名称:

using System.Security.Principal;


SecurityIdentifier sid = new SecurityIdentifier("S-1-5-18");
NTAccount acct = (NTAccount)sid.Translate(typeof(NTAccount));
Console.WriteLine(acct.Value);

稍后编辑,回应评论中的问题:您不需要任何特殊权限即可在本地计算机上进行 SID 到名称查找 - 例如,即使您运行的用户帐户仅位于Guests组中,此代码也应该可以工作。 如果 SID 解析为域帐户,情况会有所不同,但即使这样,只要您登录到域(并且在查找时域控制器可用),大多数情况下也应该可以正常工作。 。

You can use .NET's built-in System.Security.Principal.SecurityIdentifier class for this purpose: by translating it into an instance of NtAccount you can obtain the account name:

using System.Security.Principal;


SecurityIdentifier sid = new SecurityIdentifier("S-1-5-18");
NTAccount acct = (NTAccount)sid.Translate(typeof(NTAccount));
Console.WriteLine(acct.Value);

Later edit, in response to question in comments: you do not need any special privileges to do SID-to-name lookups on the local machine -- for example, even if the user account you're running under is only in the Guests group, this code should work. Things are a little bit different if the SID resolves to a domain account, but even that should work correctly in most cases, as long as you're logged on to the domain (and a domain controller is available at the time of the lookup).

记忆消瘦 2024-07-15 09:38:13

或者您可以使用:

string localSystem = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Translate(typeof(NTAccount)).Value;

通过 WellKnownSidType,您可以查找其他帐户,例如 NetworkService

Or you can use:

string localSystem = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Translate(typeof(NTAccount)).Value;

With WellKnownSidType you can look for other accounts, as NetworkService for example.

怪我闹别瞎闹 2024-07-15 09:38:13

这应该执行与您发布的内容类似的操作。 我不确定如何立即获取 WMI 对象的特定属性,但这将使您开始使用语法:

ManagementObject m = new ManagementObject("winmgmts:root\cimv2");
m.Get();
MessageBox.Show(m["Win32_SID.SID='S-1-5-18'"].ToString());

This should do something similar to what you posted. I'm not sure how to get specific properties of WMI objects offhand, but this will get you started with the syntax:

ManagementObject m = new ManagementObject("winmgmts:root\cimv2");
m.Get();
MessageBox.Show(m["Win32_SID.SID='S-1-5-18'"].ToString());
墨小沫ゞ 2024-07-15 09:38:13

已接受答案的问题是帐户名必须可由运行代码的本地计算机解析。

如果您正在读取远程计算机上的 ACL,您很可能无法解析远程机器上的域 SID/本地 SID。 以下使用 WMI 并获取远程计算机的参数和您希望远程计算机解析的 SID。

/// <summary>
/// Returns the Account name for the specified SID 
// using WMI against the specified remote machine
/// </summary>
private string RemoteSID2AccountName(String MachineName, String SIDString)
{
    ManagementScope oScope = new ManagementScope(@"\\" + MachineName +     
       @"\root\cimv2");
    ManagementPath oPath = new ManagementPath("Win32_SID.SID='" + SIDString + "'");
    ManagementObject oObject = new ManagementObject(oScope, oPath, null);
    return oObject["AccountName"].ToString();
}

The problem with the accepted answer is that the account name must be resolvable by the local machine running the code.

If you are reading the ACLs on a remote machine you may well not be able to resolve Domain SIDs / local SIDs on the remote box. The following uses WMI and takes the parameter of the remote machine and the SID you want the remote machine to resolve.

/// <summary>
/// Returns the Account name for the specified SID 
// using WMI against the specified remote machine
/// </summary>
private string RemoteSID2AccountName(String MachineName, String SIDString)
{
    ManagementScope oScope = new ManagementScope(@"\\" + MachineName +     
       @"\root\cimv2");
    ManagementPath oPath = new ManagementPath("Win32_SID.SID='" + SIDString + "'");
    ManagementObject oObject = new ManagementObject(oScope, oPath, null);
    return oObject["AccountName"].ToString();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文