Link to home
Start Free TrialLog in
Avatar of carbonbase
carbonbaseFlag for United Kingdom of Great Britain and Northern Ireland

asked on

modify permission on root folder as well as sub-folders

Hello,

I have a script to modify permissions on all sub-folders and files of any folder i point it too.  For example, I can point the script at a folder I want to modify say:  "Z:\data_folder".

 So this script works great if I want to modify permissions on all files and folders below "Z:\data_folder" but it doesn't touch the "z:\data_folder" itself.  I've been scratching my head but I can't work out the best to get the script to modify permissions on "Z:\data_folder" as well as modifying permissions on the sub-folders and files, and I can't simply change the path to "Z:" as there are other folders on "Z:" I don't want touched.



Basic script is below:

$rights = [System.Security.AccessControl.FileSystemRights]::FullControl
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]::None
$allowdeny = [System.Security.AccessControl.AccessControlType]::Allow


# Customize the domain name
$myDomain = "Domain"
$adminUserName = "AD_Group"

[string]$ErrorLog = 'c:\temp\Permission_Errors.txt'

$foldernames=cmd /c 'dir \\?\Z:\data_folder\ /s /ad /b| findstr "\\\\?\\"'
$foldernames.substring(4) | ForEach `
{
    $folder = $_

            $Account = [System.Security.Principal.NTAccount]"$myDomain\$adminUserName"
            
            $Acl = Get-Acl $folder 
            $newAcl = @((Get-Acl $folder).Access | Select-Object -ExpandProperty IdentityReference)


            If ($newAcl -Contains $Account)    
            {
                Write-Host  "Skipping folder.  This user account already has permission: " $Account
                Write-Host  "To the folder: $($folder)"
            }       
            Else
            {
                $Ace = New-Object System.Security.AccessControl.FileSystemAccessRule ($Account,$rights,$inheritance,$propagation,$allowdeny)
                $Acl.AddAccessRule($Ace)
            
                Write-Host "Setting permission for folder: $($folder)" -ForegroundColor Yellow

            $error.Clear()

            Try
            {
                Set-Acl $folder -AclObject $Acl `
                -erroraction Stop
            } 
            catch {
                        Write-Warning "Problem setting permission to folder:  $($folder)"
                        Write-Warning "The following error occurred: $error " 

                        "Problem setting permission to folder: '$($folder)'.  The Error encountered was: '$error'" | Out-File $ErrorLog -Append
                  }
            }
}

Open in new window

Avatar of oBdA
oBdA

Any specific reason why you're shelling out to cmd, then use the "\\?\" prefix, only to strip it off again? A simple Get-ChildItem will get the same result.
To process the start folder as well, replace lines 13-14 in your original script with this:
$StartFolder = "Z:\data_folder"
$StartFolder, (Get-ChildItem -Path $StartFolder -Recurse -Directory | Select -ExpandProperty FullName) | ForEach `

Open in new window

The whole script with this change:
$rights = [System.Security.AccessControl.FileSystemRights]::FullControl
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]::None
$allowdeny = [System.Security.AccessControl.AccessControlType]::Allow


# Customize the domain name
$myDomain = "Domain"
$adminUserName = "AD_Group"

[string]$ErrorLog = 'c:\temp\Permission_Errors.txt'

$StartFolder = "Z:\data_folder"
$StartFolder, (Get-ChildItem -Path $StartFolder -Recurse -Directory | Select -ExpandProperty FullName) | ForEach `
{
    $folder = $_

            $Account = [System.Security.Principal.NTAccount]"$myDomain\$adminUserName"
            
            $Acl = Get-Acl $folder 
            $newAcl = @((Get-Acl $folder).Access | Select-Object -ExpandProperty IdentityReference)


            If ($newAcl -Contains $Account)    
            {
                Write-Host  "Skipping folder.  This user account already has permission: " $Account
                Write-Host  "To the folder: $($folder)"
            }       
            Else
            {
                $Ace = New-Object System.Security.AccessControl.FileSystemAccessRule ($Account,$rights,$inheritance,$propagation,$allowdeny)
                $Acl.AddAccessRule($Ace)
            
                Write-Host "Setting permission for folder: $($folder)" -ForegroundColor Yellow

            $error.Clear()

            Try
            {
                Set-Acl $folder -AclObject $Acl `
                -erroraction Stop
            } 
            catch {
                        Write-Warning "Problem setting permission to folder:  $($folder)"
                        Write-Warning "The following error occurred: $error " 

                        "Problem setting permission to folder: '$($folder)'.  The Error encountered was: '$error'" | Out-File $ErrorLog -Append
                  }
            }
}

Open in new window

Avatar of carbonbase

ASKER

i'm calling CMD to get round errors with long file paths that i was getting with get-childitem.  

I don't mind using a combination of the CMD command to do the sub-folders and files and get-childitem to do the top level folder only, where i don't have to worry about long file paths.

Maybe i could run the CMD command on sub-folders and files, then run the get-childitem (without -recurse) to take care of the top level folder?
ASKER CERTIFIED SOLUTION
Avatar of oBdA
oBdA

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry not got back sooner...

Script works well thanks!  Yes i still get a few long file name errors but not nearly as many as when I was using get-childitem

Thanks again.
Having a problem with line 10 of the code

It works fine when i enter:

$startfolder="Z:\data_folder"

but when i enter a path containing spaces (e.g.)

$startfolder="Z:\data folder"

I get the following error:

WARNING:  Problem setting permission to folder:  Z:\data folder
WARNING:  The following error occurred:  Cannot find drive.  A drive with the name '"Z' does not exist.
Replace line 13 with the following (note the escaped double quotes before and after the search path):
& cmd.exe /c "echo \\?\$($StartFolder)&dir /s /a:d /b `"\\?\$($StartFolder)`"" | ForEach `

Open in new window

That's great, was wondering where to place those escaped quotes.  Thanks very much!