title: Define where permissions apply with Set-Acl
body: <p>I'm trying to emulate in PowerShell what I typically do in the windows folder properties window available from: <em>Folder properties &rarr; Secutity &rarr; Advanced &rarr; Permissions &rarr; Change Permissions...</em></p>
  
  <p>In that GUI there are tick boxes for</p>
  
  <ul>
  <li>Include inheritable permissions from this object's parent</li>
  <li>Replace all child object permissions with inheritable permissions from this object - I believe corresponds to <code>PropagationFlag</code> = <code>None</code></li>
  </ul>
  
  <p>When you click the Add/Edit... button you have a drop down list with the following options, what <code>InheritanceFlags</code> correspond with each of them? I've filled in the ones I've found by experimentation</p>
  
  <ul>
  <li>This folder only - <code>None</code></li>
  <li>This folder subfolders and files</li>
  <li>This folder and subfolders</li>
  <li>This folder and files</li>
  <li>subfolders and files only - <code>ContainerInherit, ObjectInherit</code></li>
  <li>subfolders only - <code>ContainerInherit</code></li>
  <li>files only - <code>ObjectInherit</code></li>
  </ul>
  
  <p>What flags correspond with the check box <em>Apply these permissions to objects and/or containers within this container only</em>?</p>
  
  <p>I've also determined that these <code>PropagationsFlags</code> mean: </p>
  
  <ul>
  <li>InheritOnly (the ACE is propagated to all current child objects only if they are set to inherit)</li>
  <li>NoPropagateInherit (the ACE is not propagated to any current child objects)</li>
  <li>None (this ACE is propagated to ALL child objects overwriting what they had before and turns on their inheritance)</li>
  </ul>
  
  <p><strong>I'm wanting to find out how to</strong> add extra permissions for existing users/groups or add extra users/groups to the permissions of a folder and have that propagate with "This folder subfolders and files" but NOT "Replace all child object permissions with inheritable permissions from this object" in case there is a subfolder with other special permissions on it on purpose for a good reason, such as the symbolic link folders in user profiles.</p>
  
  <p>The code I'm working with at the moment is below. Eventually I'm going to be using it on a lot of different folders on many computers in multiple domains including user profiles in <code>c:\users\{username}</code></p>
  
  <pre><code>function check-permissions ( $folder ) {
      $GroupName = "Domain Admins"
      if ( -not (Test-Path -LiteralPath $folder) ) {
          Write-Output "Cannot find $folder"
      } else {
          ((get-acl -literalPath $folder).access).IdentityReference.Value |
              findstr /i ($env:USERDOMAIN + "\"+ $GroupName) |
              out-null
          $result = $?
          if ( -not $result ) {
              write-output ($folder + ": adding permissions")
              #adding new permissions
              $colRights = [System.Security.AccessControl.FileSystemRights]"FullControl" 
              $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
              $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::InheritOnly
              $objType =[System.Security.AccessControl.AccessControlType]::Allow
              $objUser = New-Object System.Security.Principal.NTAccount($env:USERDOMAIN + "\" + $GroupName)
              $objACE  = New-Object System.Security.AccessControl.FileSystemAccessRule ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
              # output the ACE
              $objACE | format-list *
              #$objACL = Get-Acl -literalPath $folder    # This gets the full security info but substitutes the different user as owner, which we don't want or it will overwrite the owner info with the wrong user when we use set-acl
              $objACL = (Get-Item -literalPath $folder).GetAccessControl('Access')
              if ( -not $? ) {
                  Write-Output ("Failed to get permissions on: " + $folder)
              } else {
                  $objACL.AddAccessRule($objACE)
                  if ( $objACL ) { #objACL exists
                      #Set-ACL -literalPath ($folder) -AclObj $objACL  # This tries to set the owner too
                      [System.IO.Directory]::SetAccessControl($folder,$objACL) # This seems to work
                  } else { # $objACL is null
                      write-output "Error developing new permissions object. Leaving folder permissions alone."
                  }
              }
          } else {
              write-debug ($folder + ": Permissions OK")
          }
      }
  }
  
  check-permissions "c:\temp\test\a"
  </code></pre>