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]
}
}
}