none
Retriewing list of local admins from remote system RRS feed

  • General discussion

  • I am trying to retrieve a list of members of the local administrators group on a given system and have the output of the function be an object such that and I can use it for later consumption and decision making in the script.

    I have spent a significant amount of time researching my options and have come up with the following code.  The problem that I am having with the code is that if I run it locally on a system I get the list of the members of the local administrator group.  However, if I run it against a remote system I only get SystemName\Administrator back.

    I have used this article as a guide:http://blogs.technet.com/b/heyscriptingguy/archive/2013/12/08/weekend-scripter-who-are-the-administrators.aspx

    I must be missing something somewhere.  Can anybody tell me what I need to change in order to get my result set from a remote system to be like I am getting from the local system?

    I should add that I am using Windows Server 2012 R2 across the board.

    function Get-LocalAdministrators
    {
        [CmdletBinding()]
        param
        (
            [parameter(Mandatory=$true)]
            [String] $computerName
        )
        begin
        {
            $wmiEnumOpts = New-Object System.Management.EnumerationOptions
            $wmiEnumOpts.BlockSize = 20
            $wmiObject = Get-WmiObject -Class Win32_Group -Filter "LocalAccount=True and SID='S-1-5-32-544'" -ComputerName $computerName
            $groupName = $wmiObject.Name
        }
        process
        {
            #$wmiObject
            $wmiObject.GetRelated("Win32_Account","Win32_GroupUser","","","PartComponent","GroupComponent",$false,$wmiEnumOpts) | `
                Select-Object @{Name="ComputerName"; Expression={$_.__SERVER}}, @{Name="Name"; Expression={$groupName}}, @{Name="Member"; Expression={$_.Caption}}
        }
        end
        {
        }
    }


    Monday, April 27, 2015 3:13 PM

All replies

  • If it works when you use Get-LocalAdminGroupMember.ps1 but not when you run your script, then you've made an error in your script somewhere.

    Any reason you're not just running Get-LocalAdminGroupMember.ps1 instead of trying to rewrite it?


    -- Bill Stewart [Bill_Stewart]

    Monday, April 27, 2015 3:26 PM
    Moderator
  • Yes because of the second hop restriction.  Use ADSI to get the list. Look in script gallery for numerous examples of doing thei with ADSI.


    \_(ツ)_/

    Monday, April 27, 2015 3:46 PM
  • I would add that you need to explain precisely what you mean by "if I run it against a remote system."

    If you try to use PowerShell remoting, it will fail because of the second-hop restriction of which jrv speaks.

    If you simply connect using WMI, like the original script does, then there's no second hop and it should return results as expected (presuming the account under which you run it has sufficient permission).


    -- Bill Stewart [Bill_Stewart]

    Monday, April 27, 2015 4:17 PM
    Moderator
  • Well lets start by throwin out all of the fancy stuff and kust getting the basics.

    To get the remote admin group this will work:

    $group=Get-WmiObject -Class Win32_Group -Filter "LocalAccount=True and SID='S-1-5-32-544'" -ComputerName $computerName

    To get the accounts this will work:

    $group.GetRelated('Win32_UserAccount')

    On a Windows 2008R2 domin wit Wi7 clients the dmaion admins group never shows up nor do any explicit domain group members.

    Use ADSI to get the membership of local groups.

    The issue is, in part, that the SID of the user or group must be resolved to display.  If I run the WMI at the console or in an RDP session it will show all members but it cannot when run remotely.  If anyone knows a way to circumvent this I am listening.


    \_(ツ)_/

    Monday, April 27, 2015 4:32 PM
  • Running an unqualified GetRelated("Win32_UserAccount") might not complete in a reasonable amount of time, depending on your environment (in my case, more than at least 30 minutes; I didn't wait for it to actually finish before I terminated the script). There are simply far too many relationships. This is why I fully specify the relationship, as noted in the blog post.


    -- Bill Stewart [Bill_Stewart]

    Monday, April 27, 2015 4:39 PM
    Moderator
  • Bill,  I don't understand.  $group.GetRelated('Win32_UserAccouont') is not unqualified but will scan all objects.  Either waty we still will not get domain members of the group whereas ADSI gets just the members of the group directly.


    \_(ツ)_/

    Monday, April 27, 2015 4:55 PM
  • This does the job very quickly and efficiently:

    Get-LocalGroupMembership -Computername ws701 -Group administrators -Depth 1

    https://gallery.technet.microsoft.com/scriptcenter/Get-LocalGroupMembership-c6168cfd


    \_(ツ)_/

    Monday, April 27, 2015 5:03 PM
  • That's great, as long as the group you want to query is named consistently across all computers you intend to query. (It would not be useful on my work domain, where there are thousands of different computers with different managers and different standards for naming the Administrators group.)


    -- Bill Stewart [Bill_Stewart]

    Monday, April 27, 2015 5:14 PM
    Moderator
  • That's great, as long as the group you want to query is named consistently across all computers you intend to query. (It would not be useful on my work domain, where there are thousands of different computers with different managers and different standards for naming the Administrators group.)


    -- Bill Stewart [Bill_Stewart]

    Then just adjust the code to translate the SID for the group. I think the fast way is to use WMI to get the group name by the SID and use that in the ADSI.  I think one of the scripts in the Gallery does it like that.


    \_(ツ)_/


    • Edited by jrv Monday, April 27, 2015 6:09 PM
    Monday, April 27, 2015 6:08 PM
  • Just for a sanity check I tried with the original, unmodified script and received the same behaviour. I'm not so much trying to re-write it as leverage the pieces I need for my script. Another part of it is just understanding how things work.
    Monday, April 27, 2015 6:21 PM
  • No PowerShell remoting. Just calling WMI directly using the PowerShell cmdlets as shown in the script.
    Monday, April 27, 2015 6:23 PM
  • I see what you are saying. I haven't been able to find anything that speaks to this name resolution issue and I feel like this isn't the first time I have run into this. I started with ADSI and thought maybe I could find a way to do this that didn't leverage ADSI but it seems I'm going to have to go back to my original design given this limitation. I'm very curious to see if someone has a solution to this.
    Monday, April 27, 2015 6:28 PM
  • Yup, you are right, there is a script out there that functions like that as well. Still doesn't over come the issue of not resolving the names if run against a remote system. I'll have to do it with ADSI by the looks of things.
    Monday, April 27, 2015 6:30 PM
  • I can't reproduce the problem with the original script; sorry.


    -- Bill Stewart [Bill_Stewart]

    Monday, April 27, 2015 7:00 PM
    Moderator
  • I appreciate you trying. I will probably setup a test domain that is void of GPO's and such and see if the problem follows me or the domain.  Right now I'll just focus on getting something working and out the door.
    Monday, April 27, 2015 10:45 PM
  • There is nothing really hard or tricky about this.  Here is how to do it if you have renamed the administrators groups which is actually a very rare occurrence.

    Get-AdComputer .... |
         ForEach-Object{
                $groupname=(gwmi win32_group -filter 'SID="S-1-5-32-544"' -Computer $_.Name).Name
                 Get-LocalGroupMembership -Group $groupname -Computer $_.Name
         }

    Using Boe's function this is all you need to do.  It is very fast and very efficient.

    You could also adapt it to a parallel workflow to improve performance even more.


    \_(ツ)_/


    • Edited by jrv Monday, April 27, 2015 10:57 PM
    Monday, April 27, 2015 10:57 PM