set-acl user verification with AD

Hi,
I am writing a script that will import a CSV file to create AD user accounts and then create user folders on a storage server. The number of users can be from 1 to several thousand every semester. User accounts are first created on AD, then once this is complete, invoke-command is made with a second script to the storage server to create directories and set user permissions.

Obviously you can not set user ACL’s if the user does not exist. So here is my issue: When set-acl is run, how is the user account checked against AD? If the users are checked against the AD server that I created the accounts on previously, then I don’t have an issue. But if the call is made to a different AD server and replication has not been completed, an exception is thrown. I haven’t yet had this problem in testing, but I can see this being an issue in the live environment.

How do I handle this?

  1. If the AD check is made against the calling AD because of the invoke-command, then I am done. There should be no problem.
  2. If the OS handles the user name check, is there a powershell cmdlet I can use to force the check against a particular server?
  3. Any other suggestions?

I can probably delay the directory creation process run by an hour or so but would rather not do that as some of the account creations will be during school hours.

Thanks,
-Shawn

You can check each dc to see if the user exists on all of them before proceeding.

$user = 'cduff'

$DCs = Get-ADDomainController -Filter * | 
Select-Object -ExpandProperty Name

$Iterations = 5 #Adjust as reasonable
$Pause = 10 #Adjust as reasonable
$i = 0

Do {
    $i++
    Try {
        ForEach($DC in $DCs) {
            Get-ADUser -Identity $user -Server $DC -ErrorAction Stop
        }
        $verified = $True
    } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
        $verified = $False
        Start-Sleep -Seconds $Pause
    } Catch {
        Throw $Error[0]
    }
} Until ($verified -or $i -ge $Iterations)

If (-not $verified) {
    #Log the user name and continue to next user
}

Nice. Thanks Craig.

I will likely use this if I can’t figure out a way to force the user check against the original AD server. Looking more like I won’t be able to.
If I have to do this, I will have to automate reprocessing of the skipped users. Not a horrible thing of course.

-Shawn

If you use the user’s SID instead of their username, you shouldn’t have to worry about any replication issues. The name lookup is only happening to get the user’s SID because that’s how the principal is stored in the access control entry. If you use a SID instead of a username, though, no lookup happens. You can literally make up a SID and you won’t get any complaints:

$Path = "C:\Path\To\Folder"
$UserSid = [System.Security.Principal.SecurityIdentifier] "S-1-5-1-2-3-4-5"

$Acl = Get-Acl $Path
$Acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule (
    $UserSid,
    "FullControl",
    "ContainerInherit, ObjectInherit",
    "None",
    "Allow"
)))

(Get-Item $Path).SetAccessControl($Acl)

If you fix the $Path and $UserSid variables so they’re accurate, you might be able to use that snippet. You may notice that I didn’t use Set-Acl; that’s because it has some problems when used with the FileSystem provider. I’ve found that using the SetAccessControl() method is much more reliable.

Thanks Rohn,

Exactly what I needed.

I worked your idea into my scripts by grabbing the SID after AD account creation, adding it to the CSV, then using your code during the folder creation on the storage server. Confirmed it worked by deleting the user out of AD before setting the permissions on the folder,

-Shawn

You’re welcome!