replacing dsacls (and forloop) with PS; 2008 DJ article

I am trying to set permissions for a service principle (User object) on about 100 newly introduced Exhange 2013 schema class objects with this command:

dsacls "DC=company,DC=dev" /I:S /G "\s-account:RPWP;ms-Exch-Archive-GUID;user"

but want to run this against about 100 more classes…

I was reading a 2008 article by Don Jones here: Don Jones article on PS and setting permissions

So I don’t have files or folder to set, but schema classes. Is it worth it to try PS to do this or if not, how could I use a forloop to set them with DSACLs (which does work just fine).


There is a provider that is available for active directory that you could use:

To use a for loop if you get all the items into an object you can iterate thorugh the object using foreach

here is a small demo of the foreach

$object = get-process
foreach($o in $object){write-output $o}

Not seeing an answer there.

I’m trying to do the same kind of thing, and find it fascinating that all the examples I can find eventually wind up calling a .exe like dsacls rather than going pure powershell so to speak.

Consider the following code which works fine:

$ComputerName = "HOST1234"

$computerDN = (Get-ADComputer -Identity $ComputerName).DistinguishedName
dsacls $computerDN /g “MYDOMAIN\user123:ca;allowed to authenticate"


  • should we even bother replacing 'dsacls' with a powershell equivalent ?
  • does anybody have a 'complete' working example of this that's better than just pointing us to set-acl and expecting us to try (again) to decipher the non-examples there ?

Coming at this with 30 years of unix experience, it’s pretty tough finding the right terminology to ask the question, so apologies in advance there…

I just copied all my dsacls statements in a .bat file and ran against the schema objects I was trying to ACL on behalf of the service account.

was quick 'n easy.

you’ll find that some tools are hard to beat in PS for one off situations. Dsacls and robocopy are two. No issues using them as they’ll execute fine within the shell. The only issue is the output if you needed it isn’t ideal.

duly noted, and thanks.

Here’s a simple, working example of set-ACL:

$WebServersGroup = get-adgroup -Identity "Web Servers" | Select-Object SID
$ACL = get-acl "AD:OU=Servers,DC=domain,DC=com"
$ACL.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $WebServersGroup.SID,'GenericRead','Allow'))
set-ACL "AD:OU=Servers,DC=domain,DC=com" -AclObject $ACL

For what it’s worth I prefer DSACLS :slight_smile:

Here is a way to copy acls from one object to another. I did this just for the heck of it…and yes I use write-host in my oneoff scripts:D

$forestdns = @(#bunchofforestonlyzones)

$zones = Get-DnsServerZone 

$sourceacl = get-acl 'ad:\,cn=MicrosoftDNS,DC=DomainDnsZones,DC=mycompany,DC=com' | select -ExpandProperty access | ? { $_.identityreference -eq 'mycompany\dnsadmins' }

$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(

foreach ($zone in $zones) {
	$i = $zone.zonename
	if ($i -in $forestdns) {
		$path = 'ad:\dc=' + $i + ',cn=MicrosoftDNS,DC=ForestDnsZones,DC=myforest,DC=LOCAL'
		$newacl = [ADSI]"LDAP://dc=$i,cn=MicrosoftDNS,DC=ForestDnsZones,DC=myforest,DC=LOCAL"
	} else {
		$path = 'ad:\dc=' + $i + ',cn=MicrosoftDNS,DC=DomainDnsZones,DC=mycompany,DC=com'
		$newacl = [ADSI]"LDAP://dc=$i,cn=MicrosoftDNS,DC=DomainDnsZones,DC=mycompany,DC=com"
	$acl = get-acl $path -erroraction 'silentlycontinue' | select -ExpandProperty access | ? { $_.identityreference -eq 'mycompany\dnsadmins' }
	if ($acl) {
		$return = $false
		write-host "reset perms for $i"
		$newacl.objectsecurity.ModifyAccessRule("Reset", $rule, [ref]$return)
		if ($return) {
	} else {
		$return = $false
		write-host "add perms for $i"
		$newacl.objectsecurity.ModifyAccessRule("Add", $rule, [ref]$return)
		if ($return) {