SOLVED

Getting a parent's parent for a folder using power shell

Copper Contributor

Hi,

 

I am using a powershell script to enable inheritance for the folders created in NTFS share. 

In this script, i am getting the folder created for the user by passing a dynamic value and then getting the parent folder and inheriting the permission to the new folder from parent. It is all working good. But i would need to get parent's parent in few of the cases.

 

Use Case :

New Folder : \\localhost\TestShare\s\test6

test6 : is the new folder i am creating.

My current script gives the parent folder as s and test6 inherits the permissions from 's' folder. But i would need to get the parent's parent (in this case it would be TestShare) if the length of the parent is one in few cases.

Is there a way to get it in my current script without interrupting the current logic.

 

 

 

Get-Date
$the_shares = args[0]
$allFolders=Get-ItemProperty -Path $the_shares
$allFolders.Parent.Name
$Permission=get-acl -Path $the_shares
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $the_shares -AclObject $Permission

 

 

 

Thanks in advance.

 

 

17 Replies

@suren424 

 

Hi, 

So just for me to understand a point, so do you need to get the parent parent folder incase the parent length is 1?

if so, I updated your code to be

 

$allFolders=Get-ItemProperty -Path $the_shares
if (($allFolders.Parent.Name).Length -eq 1){
Write-Host "My Length is Only 1, "
Write-Host "Add your condition here :)"
Else{

Write-Host "I am longer than 1 :("
Write-Host "Write another condition here :)"
}

$Permission=get-acl -Path $the_shares
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $the_shares -AclObject $Permission

Thank you@farismalaeb 

 

Yes, if the parent length is 1, i need to get it's parent folder.  Below is the explanation with an example :

 

Example :  $the_shares = ('C:\Share2\a\test', 'C:\Share1\abc1\')

 

Case 1:  'C:\Share2\a\test'

The parent is 'a' and the length=1. So, i need to get it's parent, which is 'Share2' and set the permission on 'test' folder to inherit from 'Share2'.

 

How can i get the parent parent folder ?

 

Case 2:  'C:\Share1\abc1'

 

Here, the parent is 'Share1'. So, i would just need set the permission on 'abc1' folder to inherit from 'Share1'.

 

 

$the_shares = ('C:\Share2\a\test', 'C:\Share1\abc1')
$allFolders=Get-ItemProperty -Path $the_shares
if (($allFolders.Parent.Name).Length -eq 1){
Write-Host "My Length is Only 1," 
Write-Host "The Parent is " -ForegroundColor Green -NoNewline
$allFolders.Parent.Name
Write-Host "Add your condition here :)"

Else{
Write-Host "I am longer than 1 :("
Write-Host "Write another condition here :)"
$Permission=get-acl -Path $the_shares
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $the_shares -AclObject $Permission
}
}

 

 

Thanks in advance.

 

Hi @suren424,

 

Try this:

 

#$the_shares = ('C:\Share2\a\test')
$the_shares = ('C:\Share1\abc1')
$allFolders=Get-ItemProperty -Path $the_shares
if (($allFolders.Parent.Name).Length -eq 1){
Write-Host "The Parent Length is Only 1" 
Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Parent.Name
$Permission=get-acl -Path $allfolders.Parent.Parent.FullName
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allfolders.FullName -AclObject $Permission
}
Else{
Write-Host "The Parent Length is longer than 1"
Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Name
$Permission=get-acl -Path $allfolders.Parent.FullName
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allfolders.FullName -AclObject $Permission
}

 

Thank you very much @Wesley Baker

 

The script is working. But if $the_shares has more than 1, it is throwing error. Do i need to use for loop ?

If yes, i am bit confused on what to use in the for loop.could you please help me on this one too.

 

$the_shares = ('C:\OIMShare2\a\test\', 'C:\OIMShare2\test\')

 

Thanks in advance

@suren424 Sure, Here is how I would handle that:

 

function setPermissions([string]$theshare) {
    $allFolders=Get-ItemProperty -Path $theshare
    if (($allFolders.Parent.Name).Length -eq 1){
    Write-Host "The Parent Length is Only 1" 
    Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Parent.Name
    $Permission=get-acl -Path $allfolders.Parent.Parent.FullName
    $Permission.SetAccessRuleProtection($False,$true)
    Set-Acl -Path $allfolders.FullName -AclObject $Permission
    }
    Else{
    Write-Host "The Parent Length is longer than 1"
    Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Name
    $Permission=get-acl -Path $allfolders.Parent.FullName
    $Permission.SetAccessRuleProtection($False,$true)
    Set-Acl -Path $allfolders.FullName -AclObject $Permission
    }
}


#Method 1 - Hardcoded array
Write-Host "Method 1 - Hardcoded array" -ForegroundColor Green
$the_shares = ('C:\Share2\a\test','C:\Share1\abc1')
foreach ($f in $the_shares) {
    setPermissions $f
}

#Method 2 - Iterate a folder and process all sub folders
Write-Host "Method 2 - Iterate a folder and process all sub folders" -ForegroundColor Green
Get-ChildItem -Path "C:\share1" | foreach{setPermissions $_.FullName}

 

@suren424 


Case 1:  'C:\Share2\a\test'

The parent is 'a' and the length=1. So, i need to get it's parent, which is 'Share2' and set the permission on 'test' folder to inherit from 'Share2'.

 

How can i get the parent parent folder ?

 

 


Just a quick tip, test folder cannot get its permission from Share2, it will get its permission only from a unless you chose to copy the permission, test will only get its permission from a.

So to make sure that the script work, must inherit its permission from share2 first and so on test

Thanks@farismalaeb .

 

I tested the script few more times and yes it is not inheriting the permissions from parents parent.

 

So, will the below logic work ?

If the parent length is one, set the permission on parent to inherit from it's parent and then set the homefolder to inherit from it's parent.

 

Example :

HomeFolder : C:\OIMShare2\b\test\

Here the 'test' parent would be 'b'. so, inherit the permission from OIMShare2 to 'b' and after that set the permissions on 'test' to inherit from 'b'.

 

$the_shares = 'C:\OIMShare2\b\test\'
$allFolders=Get-ItemProperty -Path $the_shares
if (($allFolders.Parent.Name).Length -eq 1){
Write-Host "My Length is Only 1" 
Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Parent.Name
$Permission=get-acl -Path $allfolders.Parent.Parent.FullName
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allfolders.FullName -AclObject $Permission
}
Else{
Write-Host "The Parent Length is longer than 1"
Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Name
$allFolders.Parent.Name
$Permission=get-acl -Path $allfolders.Parent.FullName
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allfolders.FullName -AclObject $Permission
}

 

Thanks in advance

 

Yes surely the logic is possible and doable via powershell
Let me ask u on more question
This is Grandfather, Father, son relation
This should go in order
Maybe ibam asking the question again, but i am a bit confused.
Do u want to enable inherent in all the chain or u want to copy the permission?!
@farismalaeb

I would like enable inheritance so that it would get all the permissions.

But, What is the difference between enable inherent in all the chain or u copying the permission?

Thank you,

@Wesley Baker  @farismalaeb 

 

While going through the script, i had a question. How is the script getting the permission from the parent and inheriting the same. I couldn't figure it out. Am i giving the $the_shares variable in the wrong position?

 

Please advise.

 

I tried the below 2 scripts, both seem to give the same result. couldn't get the difference.

 

Script 1:

$the_shares = 'C:\OIMShare3\test1'
$allFolders=Get-ItemProperty -Path $the_shares
Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Name
$allFolders.Parent.Name
$Permission=get-acl -Path $the_shares
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $the_shares -AclObject $Permission

 

Script 2:

$the_shares = 'C:\OIMShare3\test2'
$allFolders=Get-ItemProperty -Path $the_shares
Write-Host "Setting the permissions of" $allfolders.Name "based on" $allfolders.Parent.Name
$allFolders.Parent.Name
$Permission=get-acl -Path $allFolders.Parent.FullName
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allFolders.FullName -AclObject $Permission

 

Thanks in advance. 

@Wesley Baker  @farismalaeb

Any inputs on this please ?

 

Thanks in advance

@suren424 I am no expert on ACL's, inheritance and permissions, and have never used get-acl in anger, but I can see the difference in your two scripts is on line 5

 

$Permission=get-acl -Path $the_shares

 

vs

 

$Permission=get-acl -Path $allfolders.Parent.FullName

 

$the_shares is a simple text constant, and PS know nothing more about it.  $allfolders is an object that represents the folder named in the text constant.  This allows us to access it's properties dynamically, such as it's parent folder.

$allFolders=Get-ItemProperty -Path $the_shares

In Script 2, we are getting (into $permission variable) the ACL on the Parent's Path, but in Script 1, we are getting the ACL on $the_shares text value.  Therefore, Script 1 does nothing except copy the permissions from $the_shares, and then applies it back to itself without changing it...so it is redundant.

 

If get-acl set-acl is indeed the correct way to set inheritance, then I think you would find Script 2 does what you wanted if the parent folder has a length greater than 1. 

 

But as @farismalaeb mentioned  Here in his post on Monday, if the length is one, you would want to first get-acl of $allfolders.Parent.Parent.FullName, and set-acl on $allfolders.Parent.FullName, THEN you would get-acl of $allfolders.Parent.FullName, and set-acl on $allfolders.FullName, so that you respect the Grandfather, Father, Son relationship  (apologies if the choice of pronoun offends ;) ) and apply the relationship in the correct order

@suren424 

Hi, I am back :)

$Permission=get-acl -Path $allFolders.Parent.FullName

will get the parent folder name, so for C:\Folder1\Folder2, the above script will get the name of Folder1.

$Permission=get-acl -Path $the_shares

Will get the folder you set in the variable

The Different between copying the permission and inheriting it is, let's assume that you got the following folder structure

C:\Folder1\Folder2\Folder3

Inheriting the permission will copy all the permission as set in Folder1 (for example) down below the tree (other family members)

So if Folder1 has permission for User1 full control, this permission will go down the other folders.

Copying the permission won't inherit the permission from the top, but if user1 have full control in Folder1, it doesn't mean that this user will have the permission on the below folder (Folder2), but the same user User1 may have permission on Folder3.

In your case, I guess you care about inheriting more than copying.

 

Why a person may go for Copying the permission,

lets assume that you have the following folder structure

C:\OfficeFolder\Departments\IT

C:\OfficeFolder\Departments\Accounting

C:\OfficeFolder\Departments\HR

User1 need to access the root of OfficeFolder and the IT folder only but should not access the accounting and HR, so technically, (inheritance is not enabled and you can copy the permission to the below folder with some modification. small example is the home folder.

anyway, I can write a script which will do the following if you are intersted.

you set the root folder and from there it will go down the tree, and if the folder length is 1 then it will enable inheritance, or else do nothing, seems good or its something else

sorry, maybe I forget as I was away :)

 

Thank you@farismalaeb and @Wesley Baker for the great explanations.

 

@farismalaebYes, as of now my requirement is to just inherit permissions from the parent folder.

 

So, if the share is '\\MyShare\home\s\abcd\',  the script should display the parent folder in the comments and set permissions on 'abcd' by inheriting from it's parent 's'. Will the below script work

 

$the_shares = '\\MyShare\home\s\abcd\'
$allFolders=Get-ItemProperty -Path $the_shares
Write-Host "Setting permissions on " $allfolders.Name " by inhertiing from " $allfolders.Parent.Name
$allFolders.Parent.Name
$Permission=get-acl -Path $allFolders.Parent.FullName
$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allFolders.FullName -AclObject $Permission

 

I understood on this : It gets the acl of the parent folder  : $Permission=get-acl -Path $allFolders.Parent.FullName

 

If you don't mind, can you explain me on the below 2 commands on what it does ?

 

$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allFolders.FullName -AclObject $Permission

 

Thanks in advance.

best response confirmed by suren424 (Copper Contributor)
Solution

@suren424 

the script seems to be working,

I try it on my side and the result was correct, good job.

$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allFolders.FullName -AclObject $Permission

In the first line and as the $Permission is holding the folder ACL information, there is one of the methods called SetAccessRuleProtection, you can find all other methods and properties by using $Permission | Get-Member.

More info here

The SetAccessRuleProtection accepts 2 input IsProtected and PreservedInheritance 

SetAccessRuleProtection (bool isProtected, bool preserveInheritance);

IsProtected: Type is Bool ($True/$false) , $False= Enable Inheritance

PreservedInheritance : This parameter is actually ignored as the IsProtected is set to false

 

Thanks

 

-------------------------

Feel free to respond and request more information, if you find the answer that satisfy your need, Please make sure to mark it as Best Response and like the other.

 

Hi, Any update on the case, if its OK and no more input is require please select the best response

Thank you@farismalaeb and @Wesley Baker  for your inputs and guidance.

 

Appreciate all your help and support.

1 best response

Accepted Solutions
best response confirmed by suren424 (Copper Contributor)
Solution

@suren424 

the script seems to be working,

I try it on my side and the result was correct, good job.

$Permission.SetAccessRuleProtection($False,$true)
Set-Acl -Path $allFolders.FullName -AclObject $Permission

In the first line and as the $Permission is holding the folder ACL information, there is one of the methods called SetAccessRuleProtection, you can find all other methods and properties by using $Permission | Get-Member.

More info here

The SetAccessRuleProtection accepts 2 input IsProtected and PreservedInheritance 

SetAccessRuleProtection (bool isProtected, bool preserveInheritance);

IsProtected: Type is Bool ($True/$false) , $False= Enable Inheritance

PreservedInheritance : This parameter is actually ignored as the IsProtected is set to false

 

Thanks

 

-------------------------

Feel free to respond and request more information, if you find the answer that satisfy your need, Please make sure to mark it as Best Response and like the other.

 

View solution in original post