Verify local administrators via PowerShell and Compliance Settings in ConfigMgr 2012

Everybody probably knows the inventory posts for local administrators by Sherry Kissinger, but what if you want to know the compliance of your devices. What if you “just” want to know if a device is compliant to company defaults for the local administrators. This blog post will provide an answer to that question. It will provide a script, including explanation, that can be used for compliance checks. This blog post won’t go into details about creating the Configuration Item and the additional Configuration Baseline.

Script

The script that will be the core of this Configuration Item consists of three key parts. Basically, it first finds the members of the local administrators group on the device, then verifies these members and in the end it returns the compliance of the device. Per key part this means the following:

  1. The first part is finding the members of the local administrators group. There are multiple methods to find the members of the local administrators group and those methods are described in detail, in this great post by the Scripting Guys. I prefer to go for using WMI, which means I have to look at two things.
    1. The first thing is finding the users that are a member of the local administrators group.
      $LocAdmGroupMembers = (Get-WmiObject -Query "ASSOCIATORS OF ` {Win32_Group.Domain='$($env:COMPUTERNAME)',Name='Administrators'} ` WHERE ResultClass = Win32_UserAccount").Caption

    2. The second thing is finding the groups that are a member of the local administrators group.
      $LocAdmGroupMembers += (Get-WmiObject -Query "ASSOCIATORS OF ` {Win32_Group.Domain='$($env:COMPUTERNAME)',Name='Administrators'} ` WHERE ResultClass = Win32_Group").Caption

  2. The second part is comparing the members of the local administrators group with a list of what the members of the local administrators group should be. This piece will count every corresponding member and will write every illegal member to a specific variable. Both local and domain users and groups can be added to the check-list.

    foreach($Member in $LocAdmGroupMembers) { switch ($Member) { "$($env:COMPUTERNAME)\<UserName>" ` {$MemberCount = $MemberCount + 1; break;} "$($env:COMPUTERNAME)\<GroupName>" ` {$MemberCount = $MemberCount + 1; break;} "<DomainName>\<UserName>" ` {$MemberCount = $MemberCount + 1; break;} "<DomainName>\svcServiceMgr-SVC" ` {$MemberCount = $MemberCount + 1; break;} default {$IllegalMember += "$Member`n"} } }

  3. The third and last part is to check for compliance. In case the corresponding members match the number of the member count. and there are no illegal members found. the script will return Compliant. In case there is mismatch the script will return the illegal members (if applicable).
    if (($MemberCount -eq 4) -and ($IllegalMember -eq "")) { $Compliance = "Compliant" } else { $Compliance = $IllegalMember } Return $Compliance

Putting the pieces together make the complete script to look like this:

$MemberCount = 0 $IllegalMember = "" $LocAdmGroupMembers = (Get-WmiObject -Query "ASSOCIATORS OF ` {Win32_Group.Domain='$($env:COMPUTERNAME)',Name='Administrators'} ` WHERE ResultClass = Win32_UserAccount").Caption $LocAdmGroupMembers += (Get-WmiObject -Query "ASSOCIATORS OF ` {Win32_Group.Domain='$($env:COMPUTERNAME)',Name='Administrators'} ` WHERE ResultClass = Win32_Group").Caption foreach($Member in $LocAdmGroupMembers) { switch ($Member) { "$($env:COMPUTERNAME)\<UserName>" ` {$MemberCount = $MemberCount + 1; break;} "$($env:COMPUTERNAME)\<GroupName>" ` {$MemberCount = $MemberCount + 1; break;} "<DomainName>\<UserName>" ` {$MemberCount = $MemberCount + 1; break;} "<DomainName>\svcServiceMgr-SVC" ` {$MemberCount = $MemberCount + 1; break;} default {$IllegalMember += "$Member`n"} } } if (($MemberCount -eq 4) -and ($IllegalMember -eq "")) { $Compliance = "Compliant" } else { $Compliance = $IllegalMember } Return $Compliance

Usage

This script can be used as a Discovery script in a Configuration Item. The Compliance Rule for this Configuration Item has to be configured to The value returned by the specified script: Equals Compliant.

Result

Now lets take a look at the compliancy results of a device. Of course it’s not really exiting to look at a compliant device, so I picked/ created a non-compliant device. This will also show the results of the illegal members of the local administrators group. Also, I picked the client-side report instead of the server-side report. The only reason for that is its size, this report is more compact.

CheckLocalAdministrators

19 thoughts on “Verify local administrators via PowerShell and Compliance Settings in ConfigMgr 2012”

  1. I had a need for a very simple version of this, Just needed to know if a single service account was applied to each PC so I used this script.

    if (invoke-command {net localgroup administrators} | Select-String username) {Echo True} else {echo False}

    And just created CI with Boolean

    If I need to check the status of several users then I will make use of yours

    Thanks.

    Nat

    Reply
  2. Peter,

    I’m getting an error “The script execution has timed out”, also where do I enter the check-list username and group name?

    I assumed its #3 script that I modify to add the users and groups I’m running the compliance against.

    Can you advise?

    Reply
  3. Hello Peter.

    Thank you so much for this awesome script.
    For some reason some devices in our domain are not retrieving the users that belong to the remote access group and as a consequence we cannot start a remote access.
    If we do a repair to the SCCM client the users are automatically added to the group so I would like to get a list of the “non-compliant” devices and then do a remote repair of the SCCM client.
    I used your script like this:

    $LocAdmGroupMembers = (Get-WmiObject -Query “ASSOCIATORS OF `
    {Win32_Group.Domain=’$($env:COMPUTERNAME)’,Name=’ConfigMgr Remote Control Users’} `
    WHERE ResultClass = Win32_UserAccount”).Caption
    $LocAdmGroupMembers += (Get-WmiObject -Query “ASSOCIATORS OF `
    {Win32_Group.Domain=’$($env:COMPUTERNAME)’,Name=’ConfigMgr Remote Control Users’} `
    WHERE ResultClass = Win32_Group”).Caption

    if ($LocAdmGroupMembers) {$Compliance = 1}
    else {$Compliance = 0 }
    Return $Compliance

    The script is working fine but it takes +- 10 min to run… Already tried it locally on 3 different Windows 10 machines and same behavior…

    Any ideas?

    Cheers,
    pedro

    Reply
  4. Hi Peter.

    Thank YOU for taking the time to answer our questions and Congrats once again for the MVP award!
    We don’t have a lot of groups, just the ‘default’ ones and the majority of them don’t have any members:
    Access Control Assistance Operators
    Administrators
    Backup Operators
    Cryptographic Operators
    Distributed COM Users
    Event Log Readers
    Guests
    Hyper-V Administrators
    IIS_IUSRS
    Network Configuration Operators
    Performance Log Users
    Performance Monitor Users
    Power Users
    Remote Desktop Users
    Remote Management Users
    Replicator
    System Managed Accounts Group
    Users
    ConfigMgr Remote Control Users (this one has another group in it with 20 members)

    Cheers,
    pedro

    Reply
  5. For those having timeout issues use this instead of wmiObject. Requires POSH v3+

    $LocAdmGroupMembers = Get-LocalGroupMember Administrators

    Reply
  6. I independently came up with the same thing as paul, was set to add my findings, and saw his comment… 🙂

    $localadmins = Get-LocalGroupMember -Group Administrators
    $LocAdmGroupMembers = $localadmins.name

    The rest of the script was a great time saver!

    Reply
  7. I had to make the a $LocAdmGroupMembers an array (see code below).
    All in all nice work.

    $MemberCount = 0
    $IllegalMember = “”
    $LocAdmGroupMembers = @()
    $LocAdmGroupMembers += (Get-WmiObject -Query “ASSOCIATORS OF `
    {Win32_Group.Domain=’$($env:COMPUTERNAME)’,Name=’Administrators’} `
    WHERE ResultClass = Win32_UserAccount”).Caption
    $LocAdmGroupMembers += (Get-WmiObject -Query “ASSOCIATORS OF `
    {Win32_Group.Domain=’$($env:COMPUTERNAME)’,Name=’Administrators’} `
    WHERE ResultClass = Win32_Group”).Caption

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.