views:

2578

answers:

3

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  A: 

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());
DannySmurf
Thanks also to you Danny. I always appreciate a response.
Carl
+6  A: 

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

mdb
Thanks mdb. Would there be any issues running this code under a limited privileges account?
Carl
Thanks again mdb. Just tested the code in a sample app running under a reduced privileges account and various OS languages. Works a treat!
Carl
+1  A: 

[link text][1]Hello,

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

Used by XIA Configuration on http://centrel-solutions.com/xiaconfiguration