Find users with administrator rights on certain computers using PowerShell

With the PowerShell script I discuss in this post, you can find out who has administrator rights on specific computers.

One of my customers is a typical freewheeling creative media giant, with pool tables, ping-pong, free lattes, and a real lack of concern for network security—which is why they pay us to manage it for them.

Over the years, as I'm sure you appreciate, one or two more technically minded people in your organization may have asked to be local administrators on their computers. Or at least they wanted a separate local admin account created so they could continually update their equally awesome open-source development tool. Of course, no one has ever heard of this, and it doesn't have a management engine GPO can control.

Unfortunately for those free spirits, someone just bought out their company. And although the users can go along with the pool tables and the lattes, the new owner will not tolerate under any circumstances users with administrative permissions on their computers—quite rightly so.

So we face the easy option to enable restricted groups and wipe out any local admin permissions anyone may have had. Before doing this, I wanted to search those devices to see who actually did still have local admin permissions and whether we needed to inform any folks their party was over or if we could just silently roll out a restricted group.

PowerShell seemed like an easy option, but with no direct way to query local groups, we needed to search for a way to do it and additionally exclude our own local administrator accounts from the results.

Using this PowerShell script as a basis, I adapted it to exclude certain accounts from the results (for example, local administrator accounts authorized to be there), direct the query to a specific PC or to an entire organizational unit (OU), and also exclude PCs not active recently.

The base script uses WMI to query Win32_GroupUser and collect all users in all local groups. It then selects only those where the local group is administrators.

In the example, we have queried an OU for any local Aadministrator accounts not either Administrator, REDACTED, or part of the Domain Admins on a PC active on the network since September 1. The result is 139 computers to search, 31 offline computers, and 4 accounts that fail our test.

We can now speak to those four individuals and warn them they'll soon lose their admin permissions.

Local admin query

Local admin query

Of course the good thing about collating all of this information into $report is that we can then use the object to build a picture over time by exporting the result to a CSV or emailing the report to an auditor or anything you can think of!

Join the 4sysops PowerShell group!

Your question was not answered? Ask in the forum!

2+
avatar
Share
37 Comments
  1. Melvin Backus 2 years ago

    Sweet script. Is it possible there's a way I could modify it to include a default set of excluded names?  I never want to see Administrator or Domain Admins, and probably a few others in some groups of machines.

    0

    • Author

      Yes you can do that.

      At line 33, create a new array to include your default exclusions, then add that new array to the $excludeNames array.

      $defaultExclude = @(

      "Administrator",

      "Domain Admins"

      )

      $excludeNames += $defaultExclude

      Save and run to test.

      1+

  2. Melvin Backus 2 years ago

    PERFECT! Works great.

    Thank you

    0

  3. John Wagner 2 years ago

    How about having this save to a file?

    1+

    • Author

      Yes, can do that.

      Up around line 32, add in a new array.

      $report = @()

      Then line 93 add,

      $report += $comGroupObj

      Then at the end around line 111, you can do something like,

      $report | export-csv <my file path>

      Should work fine.

      1+

      • John Wagner 2 years ago

        So I added this in and it ends up generating the following error. I am running powershell with elevated rights so I should have full rights to the path I'm using.

        export-csv : Access to the path 'C:\logs' is denied.
        At C:\temp\LocalAdminGroupAudit.ps1:107 char:11
        + $report | export-csv C:\logs
        + ~~~~~~~~~~~~~~~~~~
        + CategoryInfo : OpenError: (:) [Export-Csv], UnauthorizedAccessException
        + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ExportCsvCommand

        0

        • Author

          You should use a full file path, like c:\logs\mylog.csv

           

          1+

          • john wagner 2 years ago

            doh! thanks my bad!! 🙂
            works perfectly now.

            0

          • john wagner 2 years ago

            OOps i spoke to soon.

            So the report file is generated but its empty. lol

            0

          • john 2 years ago

            So i just added a redirect at the end of the cli call to send it to a text file and that works okay.

            0

  4. John Wagner 2 years ago

    One issue I ran into in my environment.

    I have a  parent OU with several sub OUs and all have computer objects under them.  When I kick off the script it only scans the parent and doesn't scan the subs.  How would I set it to scan parent and subs?

    0

  5. That's easy.. you just need to change this line (59):

     
    Add the parameter -SearchScope Subtree, and that will pick up all the computers you need..

    David F.

    1+

  6. Sorry.. that didn't quote correctly..

    Original:
    $computers = Get-AdComputer -filter {LastLogonDate -ge $searchDays } -searchbase $ou -properties LastLogonDate | sort Name -Descending
     

    Updated:

    $computers = Get-AdComputer -filter {LastLogonDate -ge $searchDays } -searchbase $ou -properties LastLogonDate -SearchScope Subtree| sort Name -Descending

     
    David F.

    2+
    avatar
  7. John Wagner 2 years ago

    Awesome thanks very much!!!!

    0

  8. Eddiberto Silvaz 1 year ago

    Can you make it run for multiple PC that you have a file with the PC like "pc.txt"

     

    0

  9. moulouya 1 year ago

    Hello ,

    I receive this kind of error when i execute the script:

    Parameter set cannot be resolved using the specified named parameters.
    + CategoryInfo : InvalidArgument: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : AmbiguousParameterSet

    1+

  10. moulouya 1 year ago

    I copy paste the script with changing  :

    ParameterSetName="domain = i set my domain)

    ParameterSetName="computer = i set the path of the OU")

    Regards,

    0

    • Author

      OK that sounds like a bad idea.

      Copy the script 'as is', make no changes.

      When you run it, do the following..

      .\myscript.ps1 -pcname pc01

      This will query one pc, named PC01

      .\myscript.ps1 -ou "ou=myou,dc=domain,dc=com"

      This will query the whole OU.

      1+

  11. Eddiberto Silvaz 1 year ago

    Robert,

    I left the script as is and ran it against my domain that has 4500+ pc it runs great but the buffer gets full and before it can copy the $report | export-csv c:\logs\logs.csv it ran for days and I got no data.  if I break it down to groups of 100 it works.

    I had modified another script in VBS that I had set the files and created a log that passed the data results from each scan, so there were no buffering issues

    Option Explicit

    Const LogFile = "LocalAdmins.log"
    Const resultFile = "LocalAdministratorsMembership.csv"
    Const inputFile = "workstations.txt"

    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")

    Dim shl
    Set shl = WScript.CreateObject("WScript.Shell")

    Dim fil
    Set fil = fso.OpenTextFile(inputFile)

    Dim results
    Set results = fso.CreateTextFile(resultFile, True)

    WriteToLog "Beginning Pass of " & inputFile & " at " & Now()
    WScript.Echo "Beginning Pass of " & inputFile & " at " & Now()
    'On Error Resume Next

    Dim grp
    Dim line
    Dim exec
    Dim pingResults
    Dim member

    What would you recomend I do to with your script to scan 4000+ systems and keep the data?

    0

  12. Author

    Are they all in one single OU?

    Im not particularly experience with large environments like that. How many objects does it process before it crashes? 1000?

    0

  13. Eddiberto Silvaz 1 year ago

    Are they all in one single OU? YES computer is in one or broken into areas

    How many objects does it process before it crashes? 1000?  it doesn't crash it continues and displays about 100 lines on the screen, but nothing gets passed over to the CSV file.  The script runs for days, I'm thinking to increase the buffer size and the number of buffers to see if it can keep all the data.

    I'm not very good using Powershell but I'm thinking if I add a line to move output to a temp log.txt and then push the log.txt to my log.csv when the script is completed?

    0

  14. I can't see the entire modified script.. but the basic idea isn't too tough to do what you need Eddiberto..

    Change the array to an arraylist and use a .add() for each object, then use your $pCounter to export every 100 lines and then .Clear() it and continue on.  Here's a quick example of what I'm talking about..

    So, this should export every 100 numbers which will keep your memory from running out.  Base on the $pCounter you would use if ($pCounter % 100 -eq 0) { $var | export-csv -path <path> -append -notypeinformation }.

    Coralon

    0

    • Eddiberto Silvaz 1 year ago

      David,

      the code is the original on top with the following added

      create a new array to include your default exclusions, then add that new array to the $excludeNames array

      $defaultExclude = @("Administrator","Domain Admins")

      $excludeNames += $defaultExclud

      ----------------------------------------------------------------------

      Up around line 32, add in a new array.

      $report = @()

      Then line 93 add,

      $report += $comGroupObj

      Then at the end around line 111, you can do something like,

      $report | export-csv <my file path>

      where would you add your code?

      0

  15. moulouya 1 year ago

    Cooooool, thx a lot , it works

    0

  16. Jim 1 year ago

    I know this thread is a bit old, but I can run the script when I use -PCName. However when I use -ou it runs but returns nothing (No computers found). I've tried it on several different OUs. 

    0

    • Hi Jim, The script is running fine for me. Could you please provide the exact command you are running and the result.

      0

      • Jim 1 year ago

        I figured it out actually, I was not adding in the rest of the variables after the ou section (-excludeNames, active days, etc)

        But thanks for replying!

        1+
        avatar
  17. Steve 1 year ago

    For some reason when I run it I get no results.  It shows:

     

    Local Admin Group membership audit tool. Searches computers for membership of Local Administrators group.
    Accounts not listed in -excludeNames will be displayed.
    Searching Computers in : <redacted> (it shows the proper OU)
    Computers Active Since : 04/14/2019 16:22:25
    Admin Users            : Administrators Domain Admins
    Computers Found        : 0

    Total invalid Accounts : 0
    Online Computers       : 0
    Offline Computers      : 0

     

    I even made sure to run it as an admin, and tried the Import-Module ActiveDirectory to see if that helped, but still get the same results.

     

    0

  18. Steve 1 year ago

    Disregard, I didn't notice but I was searching the "Users" OU instead of computers.  It works now.

    0

  19. Michael 1 year ago

    Hi Robert 

    This is excellent and does exactly what I need.

    However one thing is our hostname are pretty long so the left column does not show the full hostname like the below.

    Can you please advise where do I modify to make the left column to fit more character.

     

    thanks

    DT-4RFS... test                                      Administrators
    DT-5CG6... test                                      Administrators

    1+
    avatar
  20. michael 1 year ago

    Thanks so much Swaphnil and Robert, worked perfectly.

    0

  21. Redi 5 months ago

    I have the same problem as Steve and i am searching a Computer OU.Can anyone please advise.

    thanks,

    0

  22. Tilak 3 months ago

    Hi Friends,

    Need your help to get powershell script on the below criteria.

    Thanks in advance for helping me.

    Create a script that creates a list with percentage  of computers running with users as local admin.

    % for Windows 10 STD and a list of PC'c
    % for Windows 10 VC and a list of PC'c
    % for Windows 7 STD (Both x86 and x64) and a list of PC'c
    % for Windows 7 VC and a list of PC'c
    % for Windows XP (all) and a list of PC'c

    Thanks,

    Tilak.

    0

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2020

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account