How to give local admin rights (on a specific machine only) to a domain user

We live in a time where users are working remotely more than ever. This throws IT departments a lot of challenges with regards to support, particularly when it comes to doing it securely.

This security challenge has been exacerbated in recent years with worm-based malware targeting users with admin rights on a local workstation. The attack makes it easy to infect others in the network, especially as a lot of organizations switch off things like Windows Firewall. Now more than ever, there’s a need to find a balance between the security of your Windows workstation estate, and local administrative autonomy.

The standard toolset for granting admin rights is to add an AD group via “restricted groups” to machines affected by a GPO.

This may be fine for Desktop and Service desk support groups, but it also means that anyone in these groups automatically gets admin rights to every machine where the policy applies. For an individual user who may need to add a printer driver while working remotely, or perform any other local task that requires elevated rights, this is not a great approach.

You could create lots of different GPOs, but that’s not a great/scalable solution to the problem. You could also use LAPS, but that requires the user to contact the service desk and get a complex password sent to them, which again isn’t ideal.

The solution below will give a specific user the administrator rights to a single machine. This limits the impact on other machines should they make a mistake, and we can withdraw those same rights very easily if they no longer need that level of access.

We’re still going to use a GPO, but now with an attribute on the computer object in AD to specify the individual user. A small but clever piece of PowerShell, created by our Head of Research, Thorbjorn Sjovold, is run as a startup script to add that user to the local administrators group.

Firstly, we do have a pre-req. You will need to have PowerShell v5 installed on all of your client workstations. Anything pre-Windows 10 will need an update to get this version of PowerShell. Then, you need to create the script (see below).

############################################################################### 
# Script intended to run as a computer startup script to add a user that      #
# is referenced in the "manager" attribute to the local administrator group.  #
#                                                                             #
# The "manager" attribute for the computer should be populated with the DN of #
# the user, just like the managedBy attribute.                                #
###############################################################################


# Change to $VerbosePreference = "Continue" if more output is required
$VerbosePreference = "SilentlyContinue"

function Get-ADSIUser ($UserDistinguishedName)
{
        $root = [ADSI]'';
        $searcher = New-Object System.DirectoryServices.DirectorySearcher($root);
        $searcher.filter = "(&(objectClass=user)(distinguishedName= $UserDistinguishedName))";
        $user = $searcher.FindOne().GetDirectoryEntry()
        return $user
} 

function Get-ADSIComputer ($ComputerAccountName)
{
        $root = [ADSI]'';
        $searcher = New-Object System.DirectoryServices.DirectorySearcher($root);
        $searcher.filter = "(&(objectCategory=computer)(sAMAccountName=$ComputerAccountName))";
        $computer = $searcher.FindOne().GetDirectoryEntry()
        return $computer
} 


try {
    New-EventLog -LogName Application -Source "Specops Local Admin Mgmt" -ErrorAction SilentlyContinue

    $computerName = $Env:COMPUTERNAME + "$"
    
    $currentComputer = Get-ADSIComputer($computerName)

    if ($currentComputer.manager -ne $null) {
        Write-Verbose "Manager attribute in AD is $($currentComputer.manager)"
        
        $managerUser = Get-ADSIUser $currentComputer.manager
        $binarySID = $managerUser.ObjectSid.Value
        $objSID = New-Object System.Security.Principal.SecurityIdentifier($binarySID,0)
        $objUser = ($objSID.Translate( [System.Security.Principal.NTAccount])).Value  
        Write-Verbose "User name referenced in the manager attribute in AD is $objUser"
 
        # The local Administrator group SID is S-1-5-32-544
        $localUserAdded =  Get-LocalGroupMember -SID S-1-5-32-544 -Member $objUser -ErrorAction SilentlyContinue

        if ($localUserAdded -eq $null) {

            Write-Verbose "User $objUser will be added to local Administrators group ..."
            Add-LocalGroupMember -SID S-1-5-32-544 -Member $objUser
            Write-Output "Added user $objUser to local Administrators group ..."            
            Write-EventLog -LogName Application -EntryType Information -EventId 100 -Source "Specops Local Admin Mgmt" -Message "Added user $objUser to local Administrators group."

        } else
        {

            Write-Verbose "User already a member of the local Administrators Group, no action taken ..."
            Write-EventLog -LogName Application -EntryType Information -EventId 101 -Source "Specops Local Admin Mgmt" -Message "User $objUser already a member of the local Administrators Group, no action taken."
        }

     } else
     {
        Write-Verbose "No administrator assigned to this computer, no action taken ..."
        Write-EventLog -LogName Application -EntryType Information -EventId 102 -Source "Specops Local Admin Mgmt" -Message "No administrator assigned to this computer, no action taken."
     }
 }
 catch [System.SystemException]
 {

    Write-Output "Failed to add local admin with the following exception: $_"

    New-EventLog -LogName Application -Source "Specops Local Admin Mgmt" -ErrorAction SilentlyContinue
    Write-EventLog -LogName Application -EntryType Error -EventId 200 -Source "Specops Local Admin Mgmt" -Message "Failed to add local admin with the following exception: $_"
 }

Save this script as AddlocalAdmin.ps1 to a share on your network so that all your computer accounts have read permission, e.g. \\<fqdn-domain-name>\sysvol\<fqdn-domain-name>\Scripts

Open GPMC to create a new GPO, or add it to an existing one if you prefer, that applies to all your workstations where you want to delegate admin permissions.

Navigate to Computer Configuration>Policies>Windows Settings\Scripts (Startup/Shutdown) and add a new Startup Script.

Make sure you have the Advanced Features view enabled in Active Director Users and Computers, and that the attribute list isn’t being filtered.

Once that is done, all we need to do is add our test users Distinguished Name….

….To the Manager attribute of the computer that they use.

Finally reboot the workstation. When it comes back on, the user should be a local admin of that machine.

The above script also generates some Event logs for audit and troubleshooting purposes as well.

EventID 100 = User added successfully
EventID 101 = User already a member of Local Admins
EventID 102 = No Manager assigned to this computer
EventID 200 = Failed to add the user to the local Administrators group

You could use this method to add users to any group with a Known SID.

https://support.microsoft.com/en-gb/help/243330/well-known-security-identifiers-in-windows-operating-systems

As for withdrawing access, I would still recommend using the “restricted groups” GPO to lockdown the local Administrators group. The startup script method I described above will inject the user only at boot time and will not be reapplied at GP refresh. Admin rights will always be temporary until the group policy is refreshed on the workstation. This might be a desirable side effect as it will only grant access for a short time (90-120mins) after reboot, so the exposure to threat is less.

If you would like to grant local admin rights on a more permanent basis, you could use a tool like Specops Command which can package any PowerShell scripts and their dependent modules and deploy them to specific targets using group policy.

(Last updated on August 9, 2023)

Tags: ,

darren james

Written by

Darren James

Darren James is a Senior Product Manager at Specops Software, an Outpost24 company. Darren is a seasoned cybersecurity professional with more than 20 years of experience in the IT industry. He has worked as a consultant across various organizations and sectors, including central and local governments, retail and energy. His areas of specialization include identity and access management, Active Directory, and Azure AD. Darren has been with Specops Software for more than 12 years and brings his expertise to the support and development of world-class password security and authentication solutions. 

Back to Blog