2

Using ADSI I can query the members of the local Administrator group on a given computer by doing (for example in PowerShell) :

([ADSI]"WinNT://computer-name/Administrators,Group").Invoke("members")

To do this, as far as I can tell, the user running the PowerShell script requires Administrator privileges on the target machine - that is, the user needs to be directly on indirectly in the local administrator group of computer-name (eg. by being a member of "Domain Admins").

This surprised me because a non-administrator account who can login to computer-name (eg. a user that's part of "Domain Users" and nothing else) can open the local users & groups application, and view the members of the local administrator group. No specific rights are required when doing it manually, yet ADSI seems to require it.

So my questions are:

  • Is it correct that using ADSI you need Administrator rights to access this information, or am I doing something wrong?
  • Is there a different approach to programmatically obtain this information, which requires less privileges than an Administrator account ? (If there are solutions that are not available in PowerShell that's fine, my targets are C#/.NET Core )

Please note I want to run this remotely on other workstations - not just on the local workstation.

Alice Heaton
  • 1,140
  • 11
  • 16

2 Answers2

1

ADSI is built on top of WMI. By default, only the local Administrators group is allowed to make remote WMI calls and read a computers local directory data.

You can change the permissions on the OS by going into Computer Management (local) -> Services and Applications -> WMI Control. Right click on WMI Control and choose Properties.

I've only experimented with allowing all reads, which you can set on the root folder. I did some research and you may be able to restrict this to just LDAP. On the Security tab drill down to Root -> directory -> LDAP. You'll want to adjust permissions on the LDAP entry (or maybe more?). The key permission is Remote Enable.

Update

To query WMI directly from PowerShell.

Remote WMI over PowerShell: https://learn.microsoft.com/en-us/windows/win32/wmisdk/connecting-to-wmi-on-a-remote-computer.

Custom PowerShell method for listing remote group membership through WMI: https://gallery.technet.microsoft.com/scriptcenter/List-local-group-members-c25dbcc4

Peter
  • 9,643
  • 6
  • 61
  • 108
  • @AliceHeaton Have you had a chance to check this out? – Peter Jun 25 '20 at 16:10
  • Yes, so far I haven't managed to get this to work. I have User U1 who is in Desktop D1's local "Remote Desktop Users" and "Remote Management Users" group. And I have given User U1 all permissions on "WMI Control > Root", checking "Applies to this namespace and subnamespaces". If I now go to Desktop D2 and logon with User U1, running `[ADSI]"WinNT://D1/Administrators,Group"` returns "exception occured while retrieving PSComputerName: Access is Denied". Stll tinkering in case I missed something. – Alice Heaton Jun 25 '20 at 16:50
  • Sorry to hear that. Maybe try querying directly with WMI through Powershell? Remote WMI over PowerShell: https://learn.microsoft.com/en-us/windows/win32/wmisdk/connecting-to-wmi-on-a-remote-computer. Listing group membership through WMI: https://gallery.technet.microsoft.com/scriptcenter/List-local-group-members-c25dbcc4 – Peter Jun 26 '20 at 16:05
  • 1
    Yes! I can confirm querying directly using WMI works with the custom permissions on WMI (so does not require membership of local Administrator group). Thanks :) – Alice Heaton Jun 29 '20 at 10:01
  • After some testing, the smallest permission I found that allowed me to read the members of the Amdinistrators group via WMI was to set (for the domain user making the query) "Remote Enable" for `Root > CIMV2`. No other permission or group membership (other than Authenticated Users) was necessary. – Alice Heaton Jun 29 '20 at 10:36
  • And a useful related resource to set WMI permissions via GPO (and a powershell script): https://learn.microsoft.com/en-gb/archive/blogs/spatdsg/set-wmi-namespace-security-via-gpo-script – Alice Heaton Jun 29 '20 at 10:59
0

I think your ADSI approach should work, at least when executed locally.

I used a c# snippet I grabbed from this SO answer: https://stackoverflow.com/a/8192062/3374994.

To test whether it could run from regular user permissions, I used Runas /user:regularuser GetLocalUsers.exe.

I believe this shows that an ADSI approach would not necessarily require elevated privileges.

However, was your intention to run the code remotely?

var path = string.Format("WinNT://{0},computer", Environment.MachineName);

        using (var computerEntry = new DirectoryEntry(path))
        {
            var userNames = from DirectoryEntry childEntry in computerEntry.Children
                where childEntry.SchemaClassName == "User"
                select childEntry.Name;

            foreach (var name in userNames)
                Console.WriteLine(name);
        }
Nahum Timerman
  • 151
  • 1
  • 9
  • Yes, my intention is to run this remotely. I know it works with unprivileged user on the local computer. It also works with unprivileged user when I run the code against my Domain Controller. But to run it against another workstation (in my tests Windows 10 Pro) then I need a privileged user :( – Alice Heaton Jun 21 '20 at 14:26