Settings NTFS Permissions by SID in PowerShell

I am currently creating a PowerShell script that creates a user with all needed Active Directory attributes, Exchange mailbox, (TS) Home- and Profile directories and so on.

In such a script you can easily get failures because of Active Directory replication.

imageImage that you create a new user account and later on you need set an additional attribute. What happens if the user was created while connected to Domain Controller A and you try to set an additional attribute while connected to Domain Controller B before replication has completed?

We can prevent this easily by performing all actions on the same domain controller. In my script I query for any Domain Controller that has the Global Catalog role:

# We will use a single domain controller for all operations to prevent
# replication issues
$DC = (Get-DomainController -GlobalCatalog )[0].DnsHostName       

Insert the $DC variable in your ldap binding eg:

$User = [ADSI]("LDAP://{0}/CN=Administrator,CN=Users,DC=Contoso,DC=com" -f $DC)

Next problem is when you perform non ADSI operations such as setting NTFS permissions on a fileserver (eg homedirectory).

This server may not yet be able to resolve the username to it’s SID and thus the operation may fail!

We can solve this easily by giving permissions to the SID directory instead to the username. Example:

function SetNTFSPermissionsBySid([string]$directory, [System.DirectoryServices.DirectoryEntry]$objAD)
{
	# Convert byte array sid to sid string
	$sID = New-Object System.Security.Principal.SecurityIdentifier $objAD.objectsid[0],0

	# Inheritance This Folder, Subfolders and Files)
	$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
	$propagation = [system.security.accesscontrol.PropagationFlags]"None"

	# Retrieve the ACL
	$aCL = Get-Acl $directory

	# Create Ace
	$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($sID, "Modify", $inherit, $propagation, "Allow")

	# Add Ace to Acl
	$aCL.AddAccessRule($accessrule)

	# Set Acl to the directory
	Set-Acl -aclobject $aCL -path $directory
}