Reference Material | Authentication policy for users outside scope

If an authentication policy is created for the administrators and/or helpdesk group, but they are outside the Secure Service Desk Active Directory scope (“Allow users outside scope” is enabled), the Secure Service Desk Gatekeeper’s group must be granted permission to read/write relevant information on the user objects.

Complete the steps below to allow administrators/helpdesk users outside of the Secure Service Desk scope to enroll with Specops Authentication.

Pre-requisites: The Active Directory PowerShell snapin

  1. Save the script below into a file (e.g. “C:\Scripts\SpecopsUserPermissions.ps1”)
  2. Dot source the script into a PowerShell session.
  3. Run the Grant-SpecopsPermissionForUserOutsideScope cmdlet for each user outside the scope that needs to enroll with uReset.

Command: 

# "Dot source the script to load the 'Grant-SpecopsPermissionForUserOutsideScope' cmdlet.
. C:\Scripts\SpecopsUserPermissions.ps1
 
# Run this script for each user outside scope that needs to enroll with uReset
# GatekeepersGroup: sAMAccountName or DN of the Gatekeepers group (default is 'Specops Authentication Gatekeepers')
# TargetUser: sAMAccountName or DN of the target user
Grant-SpecopsPermissionForUserOutsideScope -GatekeepersGroup 'Specops Authentication Gatekeepers' -TargetUser JohnDoe


Script:

$VerbosePreference = 'Continue'
$ErrorActionPreference = 'Stop'
 
function Grant-SpecopsPermissionForUserOutsideScope {
[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$GatekeepersGroup,
 
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$TargetUser,
 
    [Parameter(Mandatory=$false)]
    [ValidateNotNullOrEmpty()]
    [string]$MobileNumberAttribute='mobile'
)
    $VerbosePreference = 'Continue'
    $ErrorActionPreference = 'Stop'
 
    Write-Verbose "Gatekeeper's group: $GatekeepersGroup"
    Write-Verbose "Target user:        $TargetUser"
 
    $domain = Get-ADDomain
    try
    {
        $gkGroup = Get-ADGroup $GatekeepersGroup
        $gatekeepersGroup = $domain.NetBIOSName + '\' + $gkGroup.sAMAccountName
    }
    catch
    {
        throw ("Could not find Gatekeepers group ('{0}') failed." -f $GatekeepersGroup)
    }
 
    try
    {
        $user = Get-ADUser $TargetUser
        $targetUserDn = $user.DistinguishedName
    }
    catch
    {
        throw ("Could not find target user ('{0}') failed." -f $TargetUser)
    }
 
    [array]$permissionsArray = @(
        'CCDC;classStore;',                       # CreateChild DeleteChild
        'LC;;',                                   # List children
        'RP;userAccountControl;',
        'RP;msDS-User-Account-Control-Computed;',
        'RP;pwdLastSet;',                         # Force password change
        'RP;lockoutTime;',                        # Reset if locked out from AD
        'RP;tokenGroups;',                        # Determine group membership
 
        # mobile attribute - change if using a custom mobile attribute
        "RPWP;$MobileNumberAttribute;"            # Read+Write mobile number
    )
 
    $sb = New-Object System.Text.StringBuilder
 
    [void]$sb.Append('"')
    [void]$sb.Append($targetUserDn)
    [void]$sb.Append('"')
    [void]$sb.Append(' /G')
 
    $permissionsArray | foreach {
        [void]$sb.Append(' "')
        [void]$sb.Append($gatekeepersGroup)
        [void]$sb.Append(':')
        [void]$sb.Append($_)
        [void]$sb.Append('"')
    }
 
    $commandLine = $sb.ToString()
 
    function RunDsAcls($commandLine)
    {
        $startInfo = New-Object System.Diagnostics.ProcessStartInfo
        $startInfo.FileName = 'dsacls.exe'
        $startInfo.Arguments = $commandLine
        $startInfo.UseShellExecute = $false
        $startInfo.CreateNoWindow = $true
        $startInfo.RedirectStandardOutput = $true
        $startInfo.RedirectStandardError = $true
 
        $process = New-Object System.Diagnostics.Process
        $process.StartInfo = $startInfo
 
        Write-Verbose ''
        Write-Verbose "dsacls $commandLine"
        Write-Verbose ''
        $process.Start() | Out-Null
 
        $stdout = $process.StandardOutput.ReadToEnd()
        $stderr = $process.StandardError.ReadToEnd()
 
        $process.WaitForExit()
 
        if ($process.ExitCode -ne 0)
        {
            $msg = ("dsacls failed with exit code {0}." -f $process.ExitCode)
            Write-Verbose $stdout
            Write-Verbose $stderr
            write-verbose $msg
            throw $msg
        }
 
        Write-Verbose $stdout
        Write-Verbose "dsacls completed successfully."
    }
 
    Write-Verbose ''
    Write-Verbose "Will grant permission for `"$($gatekeepersGroup)`" to operate on `"$($targetUserDn)`"."
    Write-Verbose ''
 
    RunDsAcls $commandLine
}