Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Tuesday, April 5, 2011

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.


Here is the PowerShell script.

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

Blog site:
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.

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

Known Issues:



$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 = 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.
                    $Final += $Name[$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

                # 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
                    # 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.
                    # $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'
                        # 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,

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

    # 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 =====================================