powershell给某个文件夹及递归文件(夹)加上权限

脚本特点:

  • 支持多个用户/组($identityList)
  • 支持为每个用户/组指定一个或多个权限(权限用数组形式,可组合)
  • 递归应用到文件夹及其所有子文件夹和文件
  • 设定自动继承或者不自动继承
  • 遇到访问拒绝自动跳过
  • 路径支持空格、中文、特殊字符

选项 1:对文件夹和文件都有效(推荐,大多数场景使用)权限会应用到所有现有文件夹和文件,并根据 $enableInheritance 决定是否让将来新建的内容自动继承。

# ==================== 配置区域 ====================
$targetPath = "C:\Users\chem\Desktop\新建文件夹"  # 修改为你的路径

# 是否为将来新建内容启用自动继承
$enableInheritance = $false  # $true = 新建子内容自动继承 | $false = 只改现有内容

$excludePaths = @(
    # "Temp"
    # "*\Logs"
)

$accessRules = @(
    @{ Identity = "Everyone"; Permissions = @("ReadAndExecute") },
    @{ Identity = "BUILTIN\Users"; Permissions = @("ReadAndExecute", "Write") },
    @{ Identity = "NT AUTHORITY\Authenticated Users"; Permissions = @("Modify") }
)

$accessControlType = "Allow"

# 决定继承和传播标志
if ($enableInheritance) {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
    Write-Host "启用自动继承:新建的子文件夹和文件将自动获得权限" -ForegroundColor Cyan
} else {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
    Write-Host "禁用自动继承:仅修改当前现有内容" -ForegroundColor Cyan
}

# 检查路径
if (-not (Test-Path $targetPath)) { Write-Error "路径不存在"; exit }
$targetPath = (Resolve-Path $targetPath).Path.TrimEnd('\')

# 排除函数
function Should-Exclude($fullPath) {
    if ($excludePaths.Count -eq 0) { return $false }
    foreach ($pattern in $excludePaths) {
        $comparePattern = if ([System.IO.Path]::IsPathRooted($pattern)) { $pattern } else { Join-Path $targetPath $pattern }
        if ($fullPath -like $comparePattern) { return $true }
    }
    return $false
}

# 获取所有项(包括根文件夹)
$allItems = Get-ChildItem -Path $targetPath -Recurse -Force -ErrorAction SilentlyContinue
$allItems += Get-Item -Path $targetPath -Force

foreach ($item in $allItems) {
    $fullName = $item.FullName

    if (Should-Exclude $fullName) {
        Write-Host "跳过: $fullName" -ForegroundColor Gray
        continue
    }

    try {
        $acl = Get-Acl -Path $fullName

        foreach ($rule in $accessRules) {
            foreach ($perm in $rule.Permissions) {
                if ($item.Attributes -band [System.IO.FileAttributes]::Directory) {
                    # 文件夹:带继承参数
                    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                        $rule.Identity, $perm, $inheritance, $propagation, $accessControlType
                    )
                } else {
                    # 文件:如果启用继承,也需要带继承参数(否则将来新建文件不会继承)
                    if ($enableInheritance) {
                        $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                            $rule.Identity, $perm, "ObjectInherit", "None", $accessControlType
                        )
                    } else {
                        $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                            $rule.Identity, $perm, $accessControlType
                        )
                    }
                }
                $acl.AddAccessRule($accessRule)
            }
        }

        Set-Acl -Path $fullName -AclObject $acl
        Write-Host "成功设置: $fullName" -ForegroundColor Green
    }
    catch [System.UnauthorizedAccessException] {
        Write-Warning "访问拒绝: $fullName"
    }
    catch {
        Write-Warning "失败: $fullName - $($_.Exception.Message)"
    }
}

Write-Host "全部完成!现有文件夹和文件均已设置权限。" -ForegroundColor Green

选项 2:只对文件夹有效(不修改任何文件权限)只处理所有层级的文件夹,完全跳过文件。

# ==================== 配置区域(同上) ====================
$targetPath = "C:\Users\chem\Desktop\新建文件夹"
$enableInheritance = $false

$excludePaths = @()
$accessRules = @(
    @{ Identity = "Everyone"; Permissions = @("ReadAndExecute") },
    @{ Identity = "BUILTIN\Users"; Permissions = @("ReadAndExecute", "Write") },
    @{ Identity = "NT AUTHORITY\Authenticated Users"; Permissions = @("Modify") }
)
$accessControlType = "Allow"

if ($enableInheritance) {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
} else {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
}

if (-not (Test-Path $targetPath)) { Write-Error "路径不存在"; exit }
$targetPath = (Resolve-Path $targetPath).Path.TrimEnd('\')

function Should-Exclude($fullPath) {
    if ($excludePaths.Count -eq 0) { return $false }
    foreach ($pattern in $excludePaths) {
        $comparePattern = if ([System.IO.Path]::IsPathRooted($pattern)) { $pattern } else { Join-Path $targetPath $pattern }
        if ($fullPath -like $comparePattern) { return $true }
    }
    return $false
}

# 只获取文件夹(包括根文件夹)
$folders = Get-ChildItem -Path $targetPath -Recurse -Directory -Force -ErrorAction SilentlyContinue
$folders += Get-Item -Path $targetPath -Force

foreach ($folder in $folders) {
    $fullName = $folder.FullName

    if (Should-Exclude $fullName) {
        Write-Host "跳过文件夹: $fullName" -ForegroundColor Gray
        continue
    }

    try {
        $acl = Get-Acl -Path $fullName

        foreach ($rule in $accessRules) {
            foreach ($perm in $rule.Permissions) {
                $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                    $rule.Identity, $perm, $inheritance, $propagation, $accessControlType
                )
                $acl.AddAccessRule($accessRule)
            }
        }

        Set-Acl -Path $fullName -AclObject $acl
        Write-Host "成功设置文件夹: $fullName" -ForegroundColor Green
    }
    catch [System.UnauthorizedAccessException] {
        Write-Warning "访问拒绝: $fullName"
    }
    catch {
        Write-Warning "失败: $fullName - $($_.Exception.Message)"
    }
}

Write-Host "全部完成!仅文件夹权限已设置(文件未触及)。" -ForegroundColor Green

选项 3:只对文件有效(不修改任何文件夹权限)只处理所有层级的文件,完全跳过文件夹。

# ==================== 配置区域(同上) ====================
$targetPath = "C:\Users\chem\Desktop\新建文件夹"
$enableInheritance = $false  # 对文件来说,这个设置通常无实际继承效果,但保留以保持一致

$excludePaths = @()
$accessRules = @(
    @{ Identity = "Everyone"; Permissions = @("ReadAndExecute") },
    @{ Identity = "BUILTIN\Users"; Permissions = @("ReadAndExecute", "Write") },
    @{ Identity = "NT AUTHORITY\Authenticated Users"; Permissions = @("Modify") }
)
$accessControlType = "Allow"

if (-not (Test-Path $targetPath)) { Write-Error "路径不存在"; exit }
$targetPath = (Resolve-Path $targetPath).Path.TrimEnd('\')

function Should-Exclude($fullPath) {
    if ($excludePaths.Count -eq 0) { return $false }
    foreach ($pattern in $excludePaths) {
        $comparePattern = if ([System.IO.Path]::IsPathRooted($pattern)) { $pattern } else { Join-Path $targetPath $pattern }
        if ($fullPath -like $comparePattern) { return $true }
    }
    return $false
}

# 只获取文件(不包括文件夹)
$files = Get-ChildItem -Path $targetPath -Recurse -File -Force -ErrorAction SilentlyContinue

foreach ($file in $files) {
    $fullName = $file.FullName

    if (Should-Exclude $fullName) {
        Write-Host "跳过文件: $fullName" -ForegroundColor Gray
        continue
    }

    try {
        $acl = Get-Acl -Path $fullName

        foreach ($rule in $accessRules) {
            foreach ($perm in $rule.Permissions) {
                # 文件使用简单版本(无继承参数)
                $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                    $rule.Identity, $perm, $accessControlType
                )
                $acl.AddAccessRule($accessRule)
            }
        }

        Set-Acl -Path $fullName -AclObject $acl
        Write-Host "成功设置文件: $fullName" -ForegroundColor Green
    }
    catch [System.UnauthorizedAccessException] {
        Write-Warning "访问拒绝: $fullName"
    }
    catch {
        Write-Warning "失败: $fullName - $($_.Exception.Message)"
    }
}

Write-Host "全部完成!仅文件权限已设置(文件夹未触及)。" -ForegroundColor Green

可以设置多个文件夹及多个权限:

# ==================== 配置區域 ====================

$targetPaths = @(
    "C:\Windows\appcompat",
    "C:\ProgramData\MyApp\Cache",
    "D:\Tools\Public"
    # 可繼續新增路徑
)

# 是否讓新建的子物件自動繼承這些權限
$enableInheritance = $false

# 要排除的路徑樣式(支援相對或絕對,支援 * 萬用字元)
$excludePaths = @(
    # "*\Temp",
    # "*\Logs",
    # "C:\Windows\appcompat\Private"
)

# ────────────── 權限規則(可同時設定多個身分、多個權限) ──────────────
$accessRules = @(
    # 規則1:Everyone 只讀 + 執行
    @{
        Identity    = "Everyone"
        Permissions = @("ReadAndExecute")
    },
    
    # 規則2:Users 群組 可讀寫
    @{
        Identity    = "Users"
        Permissions = @("ReadAndExecute", "Write", "Modify")
    },
    
    # 規則3:Administrators 完全控制(通常系統預設已有,可視需求加)
    @{
        Identity    = "Administrators"
        Permissions = @("FullControl")
    }
    
    # 你可以繼續新增其他規則,例如:
    # @{
    #     Identity    = "NETWORK SERVICE"
    #     Permissions = @("ReadAndExecute")
    # }
)

$accessControlType = "Allow"   # Allow / Deny

# ────────────────────────────────────────────────
# 以下通常不用修改
# ────────────────────────────────────────────────

if ($enableInheritance) {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
    Write-Host "已啟用自動繼承(新建檔案/資料夾會自動套用)" -ForegroundColor Cyan
} else {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
    Write-Host "未啟用繼承(僅修改現有檔案與資料夾)" -ForegroundColor Cyan
}

# 排除判斷函式
function Should-Exclude {
    param([string]$fullPath)
    if ($excludePaths.Count -eq 0) { return $false }
    foreach ($pattern in $excludePaths) {
        $comparePattern = if ([System.IO.Path]::IsPathRooted($pattern)) { $pattern } else { Join-Path $using:targetPath $pattern }
        if ($fullPath -like $comparePattern) { return $true }
    }
    return $false
}

# 主處理迴圈
foreach ($targetPath in $targetPaths) {
    Write-Host "`n處理路徑:$targetPath" -ForegroundColor Yellow
    
    if (-not (Test-Path $targetPath -PathType Container)) {
        Write-Warning "路徑不存在或不是資料夾,跳過 → $targetPath"
        continue
    }
    
    $targetPath = (Resolve-Path $targetPath).Path.TrimEnd('\')
    
    # 收集所有項目(包含根目錄本身)
    $allItems = @()
    $allItems += Get-Item -Path $targetPath -Force -ErrorAction SilentlyContinue
    $allItems += Get-ChildItem -Path $targetPath -Recurse -Force -ErrorAction SilentlyContinue
    
    $countSuccess = 0
    $countSkip    = 0
    $countFail    = 0
    
    foreach ($item in $allItems) {
        if (-not $item) { continue }
        $fullName = $item.FullName
        
        if (Should-Exclude $fullName) {
            $countSkip++
            continue
        }
        
        try {
            $acl = Get-Acl -Path $fullName
            
            foreach ($rule in $accessRules) {
                foreach ($permission in $rule.Permissions) {
                    $fsAccessRule = if ($item.PSIsContainer) {
                        # 資料夾
                        New-Object System.Security.AccessControl.FileSystemAccessRule(
                            $rule.Identity,
                            $permission,
                            $inheritance,
                            $propagation,
                            $accessControlType
                        )
                    } else {
                        # 檔案
                        if ($enableInheritance) {
                            New-Object System.Security.AccessControl.FileSystemAccessRule(
                                $rule.Identity,
                                $permission,
                                [System.Security.AccessControl.InheritanceFlags]"ObjectInherit",
                                [System.Security.AccessControl.PropagationFlags]::None,
                                $accessControlType
                            )
                        } else {
                            New-Object System.Security.AccessControl.FileSystemAccessRule(
                                $rule.Identity,
                                $permission,
                                $accessControlType
                            )
                        }
                    }
                    
                    $acl.AddAccessRule($fsAccessRule)
                }
            }
            
            Set-Acl -Path $fullName -AclObject $acl -ErrorAction Stop
            $countSuccess++
        }
        catch {
            $countFail++
            Write-Warning "設定失敗:$fullName → $($_.Exception.Message)"
        }
    }
    
    Write-Host "完成 $targetPath :成功 $countSuccess 個 | 跳過 $countSkip 個 | 失敗 $countFail 個" -ForegroundColor Cyan
}

Write-Host "`n所有路徑處理完畢。" -ForegroundColor Green



设置多个文件夹及权限,还可以添加排除规则:

# ==================== 配置區域 ====================

# 要處理的目標資料夾清單
$targetPaths = @(
    "C:\Windows\appcompat",
    "C:\ProgramData\MyApp\Cache",
    "D:\Tools\Public"
    # 可繼續新增路徑
)

# 是否讓新建立的子物件自動繼承這些權限
$enableInheritance = $false

# 排除規則(支援 * 萬用字元)
# 只要路徑符合這裡任一規則,就不會修改該項目(檔案或資料夾)的權限
$excludePaths = @(
    # "*\Temp",
    # "*\Logs",
    # "C:\Windows\appcompat\Private",
    # "*.bak",
    # "C:\Windows\appcompat\somefile.exe"
)

# ────────────── 權限規則(可同時設定多個身分、多個權限) ──────────────
$accessRules = @(
    # 規則1:Everyone 只讀 + 執行
    @{
        Identity    = "Everyone"
        Permissions = @("ReadAndExecute")
    },
    
    # 規則2:Users 群組 可讀寫
    @{
        Identity    = "Users"
        Permissions = @("ReadAndExecute", "Write", "Modify")
    },
    
    # 規則3:Administrators 完全控制
    @{
        Identity    = "Administrators"
        Permissions = @("FullControl")
    }
)

$accessControlType = "Allow"   # Allow / Deny

# ────────────────────────────────────────────────
# 以下通常不用修改
# ────────────────────────────────────────────────

# 設定繼承與傳播旗標
if ($enableInheritance) {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
    Write-Host "已啟用自動繼承(新建檔案/資料夾會自動套用)" -ForegroundColor Cyan
} else {
    $inheritance = [System.Security.AccessControl.InheritanceFlags]::None
    $propagation = [System.Security.AccessControl.PropagationFlags]::None
    Write-Host "未啟用繼承(僅修改現有檔案與資料夾)" -ForegroundColor Cyan
}

# 判斷是否應該排除的函式
function Should-Exclude {
    param([string]$fullPath)

    if ($excludePaths.Count -eq 0) { return $false }

    foreach ($pattern in $excludePaths) {
        $comparePattern = if ([System.IO.Path]::IsPathRooted($pattern)) {
            $pattern
        } else {
            Join-Path $using:targetPath $pattern
        }

        if ($fullPath -like $comparePattern) {
            return $true
        }
    }
    return $false
}

# 主處理迴圈
foreach ($targetPath in $targetPaths) {
    Write-Host "`n處理路徑:$targetPath" -ForegroundColor Yellow
    
    if (-not (Test-Path $targetPath -PathType Container)) {
        Write-Warning "路徑不存在或不是資料夾,跳過 → $targetPath"
        continue
    }
    
    $targetPath = (Resolve-Path $targetPath).Path.TrimEnd('\')
    
    # 先檢查根目錄是否要排除
    if (Should-Exclude $targetPath) {
        Write-Host "根目錄符合排除規則,整個路徑跳過 → $targetPath" -ForegroundColor Magenta
        continue
    }
    
    Write-Host "開始處理(根目錄未被排除):$targetPath" -ForegroundColor Green
    
    # =============================================
    # 收集項目:更穩健的方式,忽略存取被拒絕的錯誤
    # =============================================
    $allItems = @()
    
    # 根目錄本身
    $rootItem = Get-Item -Path $targetPath -Force -ErrorAction SilentlyContinue
    if ($rootItem) {
        $allItems += $rootItem
    }
    
    # 嘗試取得所有子項目,遇到拒絕存取會自動跳過,不會中斷整個指令
    $childItems = Get-ChildItem -Path $targetPath `
        -Recurse `
        -Force `
        -ErrorAction SilentlyContinue
    
    if ($childItems) {
        $allItems += $childItems
    }
    
    $countSuccess = 0
    $countSkip    = 0
    $countFail    = 0
    
    foreach ($item in $allItems) {
        if (-not $item) { continue }
        
        $fullName = $item.FullName
        
        # 排除檢查
        if (Should-Exclude $fullName) {
            $countSkip++
            continue
        }
        
        try {
            $acl = Get-Acl -Path $fullName -ErrorAction Stop
            
            foreach ($rule in $accessRules) {
                foreach ($permission in $rule.Permissions) {
                    $fsAccessRule = if ($item.PSIsContainer) {
                        # 資料夾
                        New-Object System.Security.AccessControl.FileSystemAccessRule(
                            $rule.Identity,
                            $permission,
                            $inheritance,
                            $propagation,
                            $accessControlType
                        )
                    } else {
                        # 檔案
                        New-Object System.Security.AccessControl.FileSystemAccessRule(
                            $rule.Identity,
                            $permission,
                            $accessControlType
                        )
                    }
                    
                    $acl.AddAccessRule($fsAccessRule)
                }
            }
            
            Set-Acl -Path $fullName -AclObject $acl -ErrorAction Stop
            $countSuccess++
        }
        catch {
            $countFail++
            Write-Warning "設定失敗:$fullName → $($_.Exception.Message)"
        }
    }
    
    Write-Host "完成 $targetPath :成功 $countSuccess 個 | 跳過 $countSkip 個 | 失敗 $countFail 個" `
        -ForegroundColor Cyan
}

Write-Host "`n所有路徑處理完畢。" -ForegroundColor Green


给文本的结尾加上符号"," 脚本示例(powershell 中运行):


$text = @"
"C:\Windows\CbsTemp"
"C:\Windows\appcompat"
"C:\Windows\apppatch"
"C:\Windows\AppReadiness"
"C:\Windows\assembly"
"C:\Windows\bcastdvr"
"C:\Windows\Boot"
"C:\Windows\Branding"
"C:\Windows\BrowserCore"
"@

$lines = $text -split "`n" | ForEach-Object { $_.Trim() }
if ($lines.Count -gt 0) {
    for ($i = 0; $i -lt $lines.Count; $i++) {
        if ($i -lt $lines.Count - 1) {
            $lines[$i] + ','
        } else {
            $lines[$i]
        }
    }
}

登录

注册

重设密码

请输入您的用户名或电子邮箱地址。您会收到一封包含创建新密码链接的电子邮件。