Skip to main content

Enumerate all Users that are assigned User Rights with PowerShell

One of the security questions that came up in my last PowerShell class was who has the User Rights to shut down a server. I went with this and created a script that searches all the User Rights that have a user or group assigned to them.  It performs a recursive search through all groups and provides you with a list of users who have that certain right.  Below is a screen shot part of the output.

image

Here is the PowerShell script.

<#
===========================================================
Script Name:EnumerateUserRights.ps1
Author: Jason A. Yoder, MCT

Website: www.MCTExpert.com
Blog site: www.MCTExpert.Blogspot.com
-----------------------------------------------------------
Script Purpose:
Enumerates all the user accounts that are listed as having
a user right.  This script will do a recursive search
through all nested groups and will also report on user
accounts that have been directly assigned a User Right
outside of an Active Directory Group.

-----------------------------------------------------------
Requirements:
This script has been tested on a Domain Controller only.
The User rights were programed using the Default Domain
Controller Policy.

-----------------------------------------------------------
Revision History:
Version 2.0:
Now searches through all user rights.


Version 1.0:
Search only for Users who could shut down the
Server.

-----------------------------------------------------------
Known Issues:
None.

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

Variables:

$PolicyData : Holds the object of the user right for
               ShutDown server.

$UserList : Holds the names of all of the users found
            that have the User Right.
           
$UserObject : Holds the first name of the user. It is used
              to determine if a user account was directly
              assigned to the user right, as opposed to
              being assigned by a group.

$RightsAry : Holds the raw list of user rights extracted
           : from the server.


===========================================================
#>

# =========================================================
# Functions:

# =========================================================
# Function: Get_Rights_Name:
# ---------------------------------------------------------
# This function will create a User friendly version of
# the User Right name that was extracted with WMI.
Function Get_Rights_Names ($Name)
{

    # Only process the data if it is of string
    # data type.
    If($Name -is [String])
    {
        # Remove the surrounding double quotes and
        # the leading "Se".
        $Name = $Name.replace("`"Se","")
        $Name = $Name.replace("`"","")

        # Save an upper case version of the name in
        # $Data.
        $Data = $Name.ToUpper()

        # Make sure the variable $Final is empty.
        $Final = ""

        # Loop through the User Right name.
        # Identify the letters that are upper case
        # my using a case sensitive comparison
        # against both the original name, and
        # the upper case version.
        $i=0
        $i = While ($i -lt $Data.Length)
        {

            # When an upper case letter is found,
            # Place a space in front of it.
            If ($Data[$i] -ceq $Name[$i])
                {
                $Final += " "
                $Final += $Data[$i]

                }
           
            # Write all lower case letters without
            # making any changes.
            Else
                {
                    $Final += $Name[$i]
   
                }
   

            $i++
        }
    }
    # Trim any leading or trailing spaces from the
    # data.  Allow any errors here to pass without.
    # displaying error data.
    $ErrorActionPreference = 'SilentlyContinue'
    $Final = $Final.Trim()
    $ErrorActionPreference = 'Continue'

    # Write the header for the User Rights name.
    Write-Host "-- $Final ----------" `
        -ForegroundColor Yellow -BackgroundColor DarkGray

}



# =========================================================
# == Function: Enumerate_User_Rights                     ==
# ---------------------------------------------------------
# The below function will enumerate the User Rights that
# currently contain values.  It will return the values
# back to the script.

Function Enumerate_User_Rights
{
    # Get a string of all the __RELPATH properties that
    # contain the string "UserRight=".
    $RightsList = Get-WmiObject `
        -NameSpace Root\RSOP\Computer `
        -Class RSOP_PolicySetting | `
        Where {$_.PATH -match 'UserRight='}
   
    # Ensure this array has been cleared.
    $RightsArray = $NULL
   
    # Look through each object and select the string of
    # between the double quotes.  Add this data to
    # $RightsArray.  This process uses Regular
    # Expressions.  Type "Help About_Regular_Expressions"
    # for more information.
    foreach ($Rights in $RightsList)
    {
        $MatchString = "`"\w*`""
        $Rights.__RELPATH -match $MatchString
        $RightsArray += $Matches.Values
    }

    Return $RightsArray # Return the processed data.
}


# =========================================================
# Function: Enumerate_Users
# ---------------------------------------------------------
# Uses a WMI Query to list all the users and groups
# assigned to the User Right "Shutdown Server."
Function Enumerate_Users($RightsList)
{

# Feed the list of user rights.
ForEach ($RL in $RightsList)
{
    $UserList = $NULL
    If($RL -is [String])
    {
      Get_Rights_Names $RL
       
   
        # Use WMI to extract the object for the user right
        # of Shutdown Server.
        $PolicyData = Get-WmiObject `
            -NameSpace Root\RSOP\Computer `
            -Class RSOP_PolicySetting |
            Where-Object {$_.__RELPATH -like "*$RL*"}

   
        # Loop through each object in the "AccountList"
        # property and recursively get the members of that
        # group.
        For ($i = 0 
             $i -le $PolicyData.AccountList.count-1
             $i++)
             {

                # This first error handling will extract
                # the names of each User in each group
                # and nested group that have the right
                # to shutdown the server.
                Try {
                    $UserList += Get-ADGroupMember `
                        $PolicyData.AccountList[$i] `
                        -Recursive -ErrorAction Stop
       
                    }
                Catch{
                    # In the event that a user account is
                    # assigned directed to the user
                    # right as oppose through a group, this
                    # 'Catch' will allow the script to
                    # continue to the next 'Try'.
                    }



                # This error catch will extract a username
                # that was assigned directly to the User
                # Right.
                Try{
                    # $UserObject will use Regular
                    # Expressions to remove the Domain name
                    # and backslash and return the given 
                    # name of the user.
                    $UserObject = $PolicyData.AccountList[$i] `
                        -replace "\w*\W"
      
      
                    # Get the full user name and add it to
                    # the $userList array.
                    $UserList += Get-ADUser -filter `
                        'GivenName -like $UserObject'
                    }
                Catch{
                        # This will let the error handling
                        # continue if a group is passed to
                        # it instead of a user.
                }
            }
    }

    # Write the names of the users who have the User
    # Right that is being processed.
    $UserList | Sort-Object -Unique | format-Table Name
    }
}




# == End of Functions : ===================================

# =========================================================
# Main Code:

# Announce the start of the script.
Write-Host "Script EnumerateUserRights.ps1 has started" `
    -ForegroundColor Green -BackgroundColor DarkBlue

# Import the Active Director cmdlets needed
#  for this script.
Import-Module ActiveDirectory -Cmdlet Get-ADGroupMember,
Get-ADUser

Clear-Host  # Clear the display

# Enumerate the User Rights that have assigned users
# and groups.
$RightsAry = Enumerate_User_rights

# Get the list of users who are assigned User Rights.
Enumerate_Users $RightsAry


Try{
    # Clears the data from memory.
    Clear-Variable -name UserList -ErrorAction Stop  
   }
   
Catch{<# Do nothing, this is a none critical error.#>}
   
# Clears the data from memory.
Clear-Variable -name RightsAry
# Announce the end of the script.
Write-Host "Script EnumerateUserRights.ps1 has completed" `
    -ForegroundColor Green -BackgroundColor DarkBlue

# == End of Main Code =====================================

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.