2

I have an ICACLS command running within a powershell script. The script creates a new folder on a server share, creates a new security group in AD and then runs ICACLS to provision the folder. When I execute the function, sometimes it works and sometimes it doesn't. In testing, only 50% of the time does the ICACLS command work successfully.

New-ADGroup -Name "Group Name" -GroupCategory Security -GroupScope Global -SamAccountName "Group Name" -Description "Security Group" -Path "OU=Accounts,DC=Contoso,DC=COM"
New-Item -Path "\\Server1\ServerShare\" -Name "Group Share" -ItemType directory
icacls "\\Server1\ServerShare\Group Share" /Inheritance:r /T /Grant:R "Group Name"

icacls : Group Name: No mapping between account names and security IDs was done. + CategoryInfo :NotSpecified: (Group Name...y IDs was done. :String) [], RemoteException + FullyQualifiedErrorID : NativeCommandError

Sid
  • 21
  • 2
  • 3
    How many domain controllers do you have? You have to give Active Directory a little bit of time to replicate the newly-created group to other domain controllers. Maybe `New-ADGroup` is creating the group on one domain controller, while `icacls` is searching for the group on a different DC. – Ryan Ries Jan 01 '16 at 21:42
  • Good question @Ryan. There are a bunch of domain controllers. I see your point. **New-ADGroup** can use the -Server parameter and target a single DC. Is there a method for `icacls` to do the same? – Sid Jan 02 '16 at 00:27
  • @Sid -nope, and if you think about it, nor could it have that option. – Jim B Jan 02 '16 at 06:43
  • I added a routine in my script to check when the new group replicated to a particular named DC. It took almost 8 minutes to replicate. – Sid Jan 02 '16 at 17:09
  • Further research shows one should provision the folder with the **SID** of the group instead of the **name** of the group. Examples of this are slim to none. – Sid Jan 02 '16 at 17:13

2 Answers2

0

I coded the script to look for an error and take action. I store the results of the ICACLS command in $Results. If $Results is an error, it will display Write-Host "Pausing 5 seconds for AD replication" message and try the command again. Thanks for the tip @Ryan.

I tried to mask the "No Mapping between account names and security IDs was done." red error message with a Try/Catch construct, but no luck. I assume Try/Catch does not work because it is a DOS command. Nevertheless, the script continues as soon as replication completes. I could increase the wait time to 10 seconds and decrease the number of error messages the script displays. I don't want the admin to think something is wrong and usually red error messages means just that.

Do
{
     $Results = icacls "\\Server1\ServerShare\Group Share" /Inheritance:r /T /Grant:R "Group Name"
     If ($Results -eq 'Successfully processed 0 files; Failed processing 1 files')
     {
          # We just saw a RED ERROR message.
          Write-Host "Pausing 5 seconds for AD replication"
          Start-Sleep 5
     }
} While ($Results -eq 'Successfully processed 0 files; Failed processing 1 files'}
Sid
  • 21
  • 2
  • I think you were on the right track to use the SID IdentityReference of the group versus the group friendly name for granting permissions using ICACLS. Using the SID is always safer and more efficient than using the friendly name due to using the friendly name must be translated to the SID, and your group that was created 4 milliseconds ago may not be available depending on which DC you query. – Greg Askew Jan 03 '16 at 13:59
  • I thought I was on the right track also @Greg. So when I coded the error handling, I left the IdentityReference still in tact. Even now, the script provisions the folder by the SID, but can take up to 20 seconds. Sometimes it is immediate. If only we could replicate to 100+ DCs in under 4 milliseconds. – Sid Jan 05 '16 at 18:26
0

The ICACLS usage explains how to use SID's but it could be better... The end of the usage shows an example that does NOT work. The /GRANT section shows the proper way that DOES work. You also need to take care with Powershell as the ICACLS arguments include asterisks, colons, and parentheses that CMD handles without issue, but Powershell treats differently, so you need to escape them with backticks to pass them through to the EXE.

$sid = (get-adgroup "group name").sid.value
$sid
S-1-5-21-444444444-5555555555-666666666-77777
icacls "c:\temp\sid" /Inheritance:r /T /Grant:R `*$sid`:`(R`)
processed file: c:\temp\sid
Successfully processed 1 files; Failed processing 0 files
Clayton
  • 4,523
  • 17
  • 24
  • My code looks exactly like that. Yet still, I had to add error handling around it and give AD time to replicate. – Sid Jan 05 '16 at 18:55