PowerShell

PowerShell Problem Solver: Identify Folders with Blocked Inheritance Using PowerShell

I’ll be the first to admit that working with file and folder permissions makes my head hurt. It’s one of the most complicated tasks in Windows that IT pros frequently want to automate. A common task is to identify folders that have been configured to block inheritance. Using inheritance generally makes like easier when it comes to NTFS permissions. A folder that’s blocking inheritance is often the exception to the rule and an indication that someone has done something they probably shouldn’t have. Although there are scenarios when you may be expecting blocked inheritance, any folder that’s not configured is the exception. This is most often the case with user home folders. I’ll demonstrate how to identify these folders using PowerShell.

Using PowerShell ACL cmdlets

I have some local test folders that I’ll use for my demonstration. It is very important that you test everything in this article in a non-production environment, especially if you’re going to change folder permissions. The PowerShell ACL cmdlets can be a little tricky to use. Although I’m running commands locally, you should be able to take the same techniques and commands and wrap them in Invoke-Command so that you can execute them in a PowerShell remoting session. I wouldn’t recommend trying to get or set the ACL of \\file02\c$\shared\foo over the wire because there’s no reason to pass that type of SMB traffic. Instead use remoting so that everthing is secure and goes over a single port.

It should also go without saying, but I will this anyways that you need to run the commands with an account that has enough permissions to read the access control list on a given folder. Typically an account with local administrator privileges is sufficient.

Let’s begin by looking at the ACL of a folder that has had inheritance disabled.

Sponsored Content

Maximize Value from Microsoft Defender

In this ebook, you’ll learn why Red Canary’s platform and expertise bring you the highest possible value from your Microsoft Defender for Endpoint investment, deployment, or migration.

get-acl C:\work\demo3 | select *

The property that’s of interest is AreAccessRulesProtected.

The AreAccessRulesProtected property in Windows  PowerShell. (Image Credit: Jeff Hicks)
The AreAccessRulesProtected property in Windows PowerShell. (Image Credit: Jeff Hicks)

AreAccessRulesProtected is a boolean property. If the value is true, then inheritance has been disabled. I’m going to check this property for all top-level folders.

dir c:\work -Directory | get-acl | 
Select @{Name="Path";Expression={Convert-Path $_.Path}},AreAccessRulesProtected |
Format-table -AutoSize
The AreAccessRulesProtected property for all top-level folders. (Image Credit: Jeff Hicks)
The AreAccessRulesProtected property for all top-level folders. (Image Credit: Jeff Hicks)

I have two top-level folders, which is generally what people test. If you need to drill down, then you can by using –Recurse with the DIR command. By the way, I’m defining a custom property for the path because the Get-ACL cmdlet has a path property, but it looks like this: Microsoft.PowerShell.Core\FileSystem::C:\work\demo3, and I prefer to have more user-friendly paths.

Because the AreAccessRulesProtected property is a boolean, you don’t need to use the –eq operator, so it’s a simple matter to filter out folders that have blocked inheiritance

dir c:\work -Directory -recurse | get-acl | 
Where {$_.AreAccessRulesProtected} | 
Select @{Name="Path";Expression={Convert-Path $_.Path}},AreAccessRulesProtected |
format-table -AutoSize

These are the folders under C:\Work that have inheritance disabled.

Folders that have inheritance disabled. (Image Credit: Jeff Hicks)
Folders that have inheritance disabled. (Image Credit: Jeff Hicks)

If I want to find folders that have inheritance enabled, then I can use the –NOT operator in my filter.

Instances where inheritance is enabled. (Image Credit: Jeff Hicks)
Instances where inheritance is enabled. (Image Credit: Jeff Hicks)

Let’s say you want to re-enable inheritance once you’ve identified folders with blocked inheritance. The following outlines a simple way to do so.

First, we need the access control list for a folder.

$acl = get-acl c:\work\demo2

To modify, we can use the SetAccessRuleProtection() method, which takes a few parameters.

$acl.SetAccessRuleProtection.OverloadDefinitions
Using the SetAccessRuleProtection() method in Windows PowerShell. (Image Credit: Jeff Hicks)
Using the SetAccessRuleProtection() method in Windows PowerShell. (Image Credit: Jeff Hicks)

The parameter values are both boolean. The second parameter indicates if you want to save existing rules, and I generally do.

$acl.SetAccessRuleProtection($False,$True)

All I’ve done is set the property on the ACL object. It hasn’t been applied to the folder. To accomplish that, I need to use Set-ACL.

set-acl -Path c:\work\demo2 -AclObject $acl

Rechecking inheritance, I can see that this folder is now back to normal. At least for my purposes.

Our new inheritance result. (Image Credit: Jeff Hicks)
Our new inheritance result. (Image Credit: Jeff Hicks)

To make life easier, I have a function called Set-Inheritance.

#requires -version 3.0

Function Set-Inheritance {

[cmdletbinding(SupportsShouldProcess)]

Param(
[Parameter(Position=0,Mandatory,HelpMessage="Enter the file or folder path",
ValueFromPipeline=$True,ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias("PSPath")]
[string]$Path,
[switch]$NoInherit,
[switch]$NoPreserve,
[switch]$Passthru
)

BEGIN {
    
    Write-Verbose  "Starting $($MyInvocation.Mycommand)"     

} #begin

PROCESS {
    Try {
        $fitem = Get-Item -path $(Convert-Path $Path) -ErrorAction Stop  
    }
    Catch {
        Write-Warning "Failed to get $path"
        Write-Warning $_.exception.message
        #bail out
        Return
    }
    if ($fitem) {
    Write-Verbose ("Resetting inheritance on {0}" -f $fitem.fullname)
    $aclProperties = Get-Acl $fItem

    Write-Verbose ($aclProperties | Select * | out-string)
    	
    if ($noinherit) {
        Write-Verbose "Setting inheritance to NoInherit"
    	if ($nopreserve) {
    		#remove inherited access rules  
            Write-Verbose "Removing existing rules"          
     		$aclProperties.SetAccessRuleProtection($true,$false)
     	}
     	else {
     		#preserve inherited access rules
     		$aclProperties.SetAccessRuleProtection($true,$true)
     	}
    }
    else {
     	#the second parameter is required but actually ignored
        #in this scenario
     	$aclProperties.SetAccessRuleProtection($false,$false)
    }
    Write-Verbose "Setting the new ACL"
    #hashtable of parameters to splat to Set-ACL
    $setParams = @{
        Path = $fitem
        AclObject = $aclProperties
        Passthru = $Passthru
    }
    
    Set-Acl @setparams
    } #if $fitem

} #process

END {

    Write-Verbose  "Ending $($MyInvocation.Mycommand)"     

} #end

} #end function

Set-Alias -name sin -value Set-Inheritance

With this function, I can easily reset inheritance with a one-line command:

dir c:\work -Directory -recurse | get-acl | Where {$_.AreAccessRulesProtected} | set-inheritance -whatif
This one-line command in Windows PowerShell lets us reset inheritance. (Image Credit: Jeff Hicks)
This one-line command in Windows PowerShell lets us reset inheritance. (Image Credit: Jeff Hicks)

If I intentionally want to disable or block inheritance, I can do that as well.

Set-Inheritance C:\work\demo1 -NoInherit

Be careful about using the –NoPreserve parameter with my function. If you use it all existing permissions will be wiped out, and you’ll need to repopulate access control from scratch. As I mention at the beginning, you must carefully test these steps in a non-production environment. Personally, I like being able to use PowerShell to identify folders blocked inheritance. Unless I’m faced with a lot of folders, I’m just as happy resetting permissions manually. I’ve provided a PowerShell tool you can use, but just because you can doesn’t always mean you should.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (1)

One response to “PowerShell Problem Solver: Identify Folders with Blocked Inheritance Using PowerShell”

  1. <p>Hello. This is an excellent idea and your function works great. The only thing I'd like to see is the ability for it to also handle hidden folders. Since you're using dir to get the data to pipe to your function, hidden folders aren't showing up and thus don't get touched by the set-acl cmdlet. I've tried changing it to dir /a but that seems to not work, as I get the following error:</p><p><br></p><p>PS z:\folder\subfolder&gt; dir /a z:\Folder\subfolder -Directory -recurse | get-acl | Where {$_.AreAccessRulesProtected} | set-inheritance -whatif </p><p><br></p><p>dir : Second path fragment must not be a drive or UNC name.</p><p>Parameter name: path2</p><p>At line:1 char:1</p><p>+ dir /a z:\folder\subfolder -Directory -recurse | get-acl | Where {$_.AreAccess …</p><p>+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p><p>&nbsp;&nbsp;+ CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: InvalidArgument: (z::String) [Get-ChildItem], ArgumentException</p><p>&nbsp;&nbsp;+ FullyQualifiedErrorId : DirArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand</p>

Leave a Reply

External Sharing and Guest User Access in Microsoft 365 and Teams

This eBook will dive into policy considerations you need to make when creating and managing guest user access to your Teams network, as well as the different layers of guest access and the common challenges that accompany a more complicated Microsoft 365 infrastructure.

You will learn:

  • Who should be allowed to be invited as a guest?
  • What type of guests should be able to access files in SharePoint and OneDrive?
  • How should guests be offboarded?
  • How should you determine who has access to sensitive information in your environment?

Sponsored by:

 
Live Webinar: Active Directory Security: What Needs Immediate Priority!Live on Tuesday, October 12th at 1 PM ET

Attacks on Active Directory are at an all-time high. Companies that are not taking heed are being punished, both monetarily and with loss of production.

In this webinar, you will learn:

  • How to prioritize vulnerability management
  • What attackers are leveraging to breach organizations
  • Where Active Directory security needs immediate attention
  • Overall strategy to secure your environment and keep it secured

Sponsored by: