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

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

Это не работает с разными языками, потому что имя учетной записи для 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#?

4 ответа

Решение

Для этой цели вы можете использовать встроенный в.NET класс http://msdn.microsoft.com/en-us/library/system.security.principal.securityidentifier.aspx: преобразовав его в экземпляр 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 разрешается с учетной записью домена, но даже это должно работать правильно в большинстве случаев, если вы вошли в домен (и контроллер домена доступен во время поиска),

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

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

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

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

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

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

ManagementObject m = new ManagementObject("winmgmts:root\cimv2");
m.Get();
MessageBox.Show(m["Win32_SID.SID='S-1-5-18'"].ToString());
Другие вопросы по тегам