Determine the LocalSystem account name using C#

那年仲夏 提交于 2020-01-02 09:43:09

问题


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#?


回答1:


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).




回答2:


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.




回答3:


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());



回答4:


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();
}


来源:https://stackoverflow.com/questions/204942/determine-the-localsystem-account-name-using-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!