Windows Server 2 min read

How to Restrict Account Operators to See the Password in LAPS

Michael Wu ·

By default, Domain Admins and Enterprise Admins can view LAPS passwords due to their full control permissions. However, the Account Operators group can also access these passwords because they have full control of computer objects, which may be undesirable.

Check Current Rights

Find-AdmPwdExtendedrights -identity <OU name> | Format-Table

Solution: Modify Schema

Prerequisites

  • Membership in the Schema Admins security group
  • Access to the Domain Controller with the Schema Master role

Find the Schema Master:

Get-ADForest yourdomain | Select-Object SchemaMaster

Steps

  1. Open MMC and add the Active Directory Schema Snap-in
  2. Locate the Computer Class and access Properties
  3. Click Advanced for special permissions
  4. Find Account Operators and select Edit
  5. Uncheck “All extended rights” and confirm

Update Existing Objects

Schema changes only apply to new computer objects. For existing computers, reset permissions using the PowerShell script below:

Function Reset-VirotADPermissions {
<#
.SYNOPSIS
    Reset AD Object permissions
.DESCRIPTION
    Resets a single AD Objects permissions to the default permissions.
.PARAMETER DistinguishedName
    Distinguishedname of the object to be reset
.EXAMPLE
    Reset-VirotADPermissions -DistinguishedName 'CN=Server01,OU=Servers,DC=wu,DC=local'
#>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [String]$DistinguishedName
    )

    Begin {
        Try {
            if ((Get-Module ActiveDirectory) -eq $Null) {
                Import-Module ActiveDirectory
            }
        }
        Catch {
            Throw 'Failed to load ActiveDirectory module'
        }

        $defaultSecurityDescriptor = @{}
        $rootDSE = Get-ADRootDSE
        ForEach ($Class in (Get-ADObject -SearchBase $RootDSE.schemaNamingContext `
            -ldapFilter '(&(Objectclass=classSchema)(defaultSecurityDescriptor=*))' `
            -Properties defaultSecurityDescriptor)) {
            $defaultSecurityDescriptor[$class.Name] = $Class.defaultSecurityDescriptor
        }
    }

    Process {
        Try {
            $Object = Get-ADObject -ErrorAction Stop -Identity $DistinguishedName

            if ($defaultSecurityDescriptor[$Object.ObjectClass]) {
                $CorrectACL = New-Object System.DirectoryServices.ActiveDirectorySecurity
                $CorrectACL.SetSecurityDescriptorSddlForm(
                    $defaultSecurityDescriptor[$Object.ObjectClass]
                )
            }
            else {
                Exit
            }

            Set-ADObject -Identity $DistinguishedName `
                -Replace @{'ntsecuritydescriptor' = $CorrectACL} -Verbose
        }
        catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
            Throw "Unable to find the adobject: $DistinguishedName"
        }
        catch [Microsoft.ActiveDirectory.Management.ADException] {
            Throw "Unable to update the adobject: $DistinguishedName"
        }
        Catch {
            Throw "Unknown error: $($_.Exception)"
        }
    }
}

# Change the OU below
$OU = "OU=Servers,DC=wu,DC=local"
$allobjs = Get-ADComputer -Filter * -SearchBase $OU

foreach ($obj in $allobjs) {
    $dn = $obj.DistinguishedName
    Reset-VirotADPermissions -DistinguishedName $dn
}

Script credit: Oscar Virot — virot.eu