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.
            
                    
        
            
    
        
              
        
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