PowerShell script to set permissions on multiple folders

Set folder permissions on folder remotely using PowerShell function. Sometimes you need to give yourself full control permissions on specific path on all servers in your environment, to do this you can use below function.

To display permission on specific folder using PowerShell we can use Get-ACL command. In previous article I explained about how to get permissions remotely – link.

$Path = "D:\Scripts\"
Get-Acl $Path | Select -ExpandProperty Access | Where-Object {$_.PropagationFlags -match "InheritOnly"}
#or
Get-Acl $Path | Select -ExpandProperty Access

In the parameter section you can add more options if needed. As I default I added FullControl, Write and Read:

        [Parameter(Position=3, Mandatory = $true, HelpMessage="Permissions = FullControl, Write, Read)", ValueFromPipeline = $true)][ValidateSet("FullControl", "Write", "Read")][string]
        $Permissions

Final script:

Function Set-FolderPermission{
    [CmdletBinding()]
         
    param
    (
        [Parameter(Position=0, Mandatory=$false, HelpMessage="Servers names", ValueFromPipeline = $true)]
        $Servers = $env:COMPUTERNAME,
 
        [Parameter(Position=1, Mandatory=$true, HelpMessage="Provide user name", ValueFromPipeline = $true)] 
        $UserName,

        [Parameter(Position=2, Mandatory=$true, HelpMessage="Provide path", ValueFromPipeline = $true)]
        $Path,

        [Parameter(Position=3, Mandatory = $true, HelpMessage="Permissions = FullControl, Write, Read)", ValueFromPipeline = $true)][ValidateSet("FullControl", "Write", "Read")][string]
        $Permissions
    ) 

    $Results = @()

    Write-Verbose "Validate user"
    Try
    {
        $User = (Get-ADUser -Identity $Username -Properties name).name
    }
    Catch
    {
        $_.Exception.Message
        Break
    }

    If($User)
    {
        Write-Verbose "User found"
        ForEach($Server in $Servers)
        {
            Write-Verbose "Checking server"
            Try
            {
                #$TestPath = Invoke-Command $Server -ScriptBlock{param($path)Test-Path -Path $Path} -arg $path
                $TestPath = Test-Path -Path $Path
            }
            Catch
            {
                $Error = $_.Exception.Message
                Continue
            }

            If(!$TestPath)
            {
                Write-Error $Error
            }
            Else
            {
                Write-Verbose "Setting permissions"
                Try
                {
                    $Acl = Invoke-Command $Server -ScriptBlock{param($path)Get-Acl -Path $Path} -arg $path
                    $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("$User", "$Permissions", "ContainerInherit,ObjectInherit", "None", "Allow")
                    $Acl.SetAccessRule($Ar)
                    Invoke-Command $Server -ScriptBlock{param($path,$Acl)Set-Acl $Path $Acl} -arg $path,$Acl
                }
                Catch
                {
                    $_.Exception.Message
                    Continue
                }

                Write-Verbose "Validate permissions"
                Try
                {
                    $Check = Invoke-Command $Server -ScriptBlock{param($path)Get-Acl $Path | Select -ExpandProperty Access | Where-Object {$_.IdentityReference -like "*$User*"} | select IdentityReference,FileSystemRights } -arg $path,$Acl
                }
                Catch
                {
                    $Error = $_.Exception.Message
                    Continue
                }

                If(!$Check)
                {
                    Write-Error $Error
                }
                Else
                {
                    Switch ($Check.FileSystemRights)
                    {
                        "2032127"     { $Val = "FullControl" }
                        "1179785"     { $Val = "Read" }
                        "1180063"     { $Val = "Read, Write" }
                        "1179817"     { $Val = "ReadAndExecute" }
                        "-1610612736" { $Val = "ReadAndExecuteExtended" }
                        "1245631"     { $Val = "ReadAndExecute, Modify, Write" }
                        "1180095"     { $Val = "ReadAndExecute, Write" }
                        "268435456"   { $Val = "FullControl (Sub Only)" }
                    }
                    
                    Write-Verbose "Creating PS object for user"
                    $Object = New-Object PSObject -Property ([ordered]@{ 
   
                        Server                  = $Server
                        Path                    = $Path
                        User                    = $Check.IdentityReference
                        Permissions             = $Val
  
                    })
    
                    $Results += $Object
                }
            }
        }
    }
    If($Results)
    {
        Return $Results
    }
}

Usage:

Set-FolderPermission -Servers DC01,DC02 -UserName Pawel.Janowicz -Path D:\Scripts\ -Permissions FullControl | Format-Table

Script will display results with the following information:

– Server
– Path
– User
– Permissions

I hope that this has been informative for you 🙂

Does chmod apply to subfolders?

Changing permissions with chmod To modify the permission flags on existing files and directories, use the chmod command ("change mode"). It can be used for individual files or it can be run recursively with the -R option to change permissions for all of the subdirectories and files within a directory.

How to set ACL in PowerShell?

To use Set-Acl , use the Path or InputObject parameter to identify the item whose security descriptor you want to change. Then, use the AclObject or SecurityDescriptor parameters to supply a security descriptor that has the values you want to apply. Set-Acl applies the security descriptor that is supplied.