As part of investigations, you may need to query which privilege is held by a local principal, such as a local user or group. There is of course ‘whoami’ which tells you everything you need to know when logged in on a given system. And there is the ProcessExplorer utility which is incredibly powerful, and can tell you all that and more about a logged in user.
However you may need to do a scan across multiple systems to verify that a given group has a specific privilege. This is the action I will write about here. I try to do as much as possible with Powershell, because it is ubiquitous, very powerful, and lends itself well to programming systems administration tasks.
There is a convenient PowerShell module which facilitates access to the Local Security Authority via .NET marshaling. It used to be available on technet but is now only found on GitHub.
For the sake of testing, I created a group named ‘TestGroup’ on my local machine, and on a remote machine. In the real-world use case I had, the group is one that exists on all computers. That doesn’t need to be the case, but in this case I added it locally to explain a problem a bit later.
On the remote computer, I used the Local Security mmc to grant the Impersonation privilege to that local group:
The account can be supplied either as an actual SID, or as a name which is then translated to a SID. The problem here is that if we supply the name of a local principal for looking up the privileges on a remote computer, we mean the local group on ‘that’ system, not the local group on this system. Logically, the remote group will have a different SID. This can be demonstrated easily enough:
So with that in mind, the solution is trivial. We implement our own SID translation, and pass that SID to the module function so that it immediately contacts the remote LSA with that SID and skips the translation step: