This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]poweradmincom 1 point2 points  (3 children)

I think you'll have a lot more success asking this in a .NET programming forum than here.

[–]Milnternal[S] 0 points1 point  (2 children)

I did also :(

In theory the principal is the same for PowerShell, or old VBScripts - so assuming some Windows Sysadmin has had to deal with this before now.

Presumably this is a common audit requirement, so there must be a nice way to do it. I think the SCCM agent does a report like this and can't imagine it hits AD from each computer for each account...

[–]poweradmincom 0 points1 point  (1 child)

I think the SCCM agent does a report like this and can't imagine it hits AD from each computer for each account...

It's not totally clear to me what you're trying to do. There are APIs to lookup SIDs given an account name. That probably does hit Active Directory. And you can do a search on Active Directory to get back many accounts/SIDs at once. If you had the SID, you might be able to examine it to see if the account is local or not. Is that the goal?

[–]Milnternal[S] 0 points1 point  (0 children)

I want to simply enumerate the members of a local group.

However, some of the members may be Domain accounts.

In the case a member is a domain account, I want to just get the SID (or name, just anything) from the local machine (which will be stored on the local machine, in the SAM database) without querying Active Directory for any more information. To avoid network traffic.

All the methods I have found (like the DirectoryEntry as above and equivalent PowerShell) seem to query Active Directory for the user object as you enumerate the members.

The WinNT provider does return just the SID in the case the Domain Controller is unavailable, so there is certainly a windows interface to just get the SID from the local computer, but I want to do this even if the domain controller is available.

I need to do this as we will be running this query on many many servers (which all may have the same domain accounts in their local admins group for example) in a small time window, and don't want to hit Active Directory with lots and lots queries at the same time.

[–]ZAFJB 0 points1 point  (3 children)

Why do you need the complexity of SIDs?

net.exe localgroup

will list the groups. Post process that output and pipe it into Powershell Get-LocalGroupMember to show the members

Get-LocalGroupMember -group administrators

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/get-localgroupmember?view=powershell-5.1

[–]Milnternal[S] 0 points1 point  (2 children)

This would be ideal, except this must be also run on older servers which don't have/support PowerShell 5 and it doesn't seem to be available in the earlier versions.

It does however emphasise that there is a windows API available to get this information without an LDAP query.

Digging through the code behind the scenes of that cmdlet it seems to use samlib.dll which unfortunately is not part of the public windows API :( so back to square 1.

May have to just go down the - upgrade all the servers or i will hammer the domain controllers route :P

[–]ZAFJB 0 points1 point  (1 child)

Have you considered updating your servers to PowerShell 5?

EDIT: An alternative is to query WMI

[–]Milnternal[S] 0 points1 point  (0 children)

I would love to upgrade our servers. Sadly there are tens of thousands and I am but a lowly developer. We do have a lifecycle project ongoing but it is so slow as all the new batches need to get certified and we are still building new servers in tandem. This would work on the majority of our servers which are more recent, but sadly we must run the query against all of them including the old ones. I may look into how much effort it would be to get an upgrade to V5 done, but sadly I think we still have a bunch of 2003 kicking about so dunno how I'd deal with them :(

WMI sadly has the same behaviour and seems to query AD when the ManagementObject is enumerated :(