Определите имя учетной записи LocalSystem с помощью С#

У нас есть приложение, которое устанавливает SQL Server Express из командной строки и указывает учетную запись службы как учетную запись LocalSystem через параметр SQLACCOUNT = "NT AUTHORITY\SYSTEM".

Это не работает с разными языками, потому что имя учетной записи для LocalSystem отличается. Там таблица с перечислением различий здесь:

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

Это не кажется полным (шведская версия не указана). Поэтому я хотел бы иметь возможность определять имя программно, возможно, используя SID?

Я нашел несколько VB Script, чтобы сделать это:

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

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

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

Кто-нибудь знает эквивалентный код, который можно использовать в С#?

Ответ 1

С этой целью вы можете использовать .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-имен на локальном компьютере - например, даже если учетная запись пользователя, на которой вы работаете, находится только в Группа гостей, этот код должен работать. Все немного отличается, если SID разрешает учетную запись домена, но даже в большинстве случаев это должно работать корректно, если вы вошли в домен (и контроллер домена доступен во время поиска).

Ответ 2

Или вы можете использовать:

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

С помощью WellKnownSidType вы можете искать другие учетные записи, например NetworkService.

Ответ 3

Это должно сделать что-то похожее на то, что вы разместили. Я не уверен, как получить конкретные свойства объектов WMI, но это поможет вам начать с синтаксиса:

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

Ответ 4

Проблема с принятым ответом заключается в том, что имя учетной записи должно быть разрешено локальным компьютером, на котором запущен код.

Если вы читаете списки 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();
}