如何通过PowerShell重置文件权限 修复扫描文件移动权限异常
用户通过复印机扫描PDF到文件服务器的个人用户文件夹中。复印机持有专属域用户账户,在每位用户的个人文件夹(路径示例:D:\FileShare\Users\JohnSmith\Scans)下拥有专属子文件夹所有权,扫描生成的PDF会存入该子文件夹。
这类PDF默认继承所在文件夹权限,仅对应用户、扫描账号、管理员拥有访问权限,且扫描账号保留PDF的所有权。当用户将该PDF在服务器内直接移动到其他位置时,由于权限不会自动更新,除原始用户外其余人员均无权限查看该文件。
针对新生成的文件已有临时规避方法:用户不在服务器内直接移动/剪切粘贴文件,而是采用复制粘贴操作,或是先将文件移到本地计算机再传回服务器。该操作会生成新文件,自动继承目标文件夹权限,但无法修复已经移动完成的存量异常文件。
- 困难模式:遍历服务器
D:\FileShare目录下所有路径,对所有仍由扫描账号所有、且不在用户个人目录(路径示例:D:\FileShare\Users\JohnSmith)下的文件,将其权限替换为所在父目录的权限,对应伪代码如下:
For each file If owner == Scanners, replace current permissions with that of parent directory next
- 简单模式:遍历所有文件夹,将所有文件的权限设置为匹配其父目录权限,不对文件夹本身做任何权限修改,对应伪代码如下:
For each file, replace permissions with that of parent directory.
执行前请以管理员身份启动PowerShell,首次运行建议先注释实际修改权限的代码行,确认待处理文件范围符合预期后再执行正式修改,避免误改权限。
简单模式脚本
脚本递归遍历D:\FileShare下所有文件,跳过所有目录,将每个文件的权限重置为继承父目录配置,自动清除文件上留存的旧显式权限,不会修改任何文件夹的权限设置:
# 配置根扫描路径 $rootPath = "D:\FileShare" # 递归遍历所有文件 Get-ChildItem -Path $rootPath -Recurse -File | ForEach-Object { $currentFile = $_ try { $fileAcl = Get-Acl -Path $currentFile.FullName # 关闭文件的独立权限保护,开启父目录权限继承,不保留原有自定义权限 $fileAcl.SetAccessRuleProtection($false, $false) Set-Acl -Path $currentFile.FullName -AclObject $fileAcl Write-Host "权限修复完成: $($currentFile.FullName)" -ForegroundColor Green } catch { Write-Warning "处理失败: $($currentFile.FullName),错误: $($_.Exception.Message)" } }
困难模式脚本
脚本仅处理同时满足以下两个条件的文件:1. 文件所有者为指定的扫描服务账号;2. 文件不在用户个人目录路径范围内。处理逻辑同样为重置文件权限继承父目录,不会修改其他文件、不会修改任何文件夹权限。
使用前请先修改$scannerAccount变量为实际的扫描账号,格式为域名\用户名,例如CORP\PrinterScanner01:
# 配置参数 $rootPath = "D:\FileShare" # 替换为实际的复印机扫描服务账号 $scannerAccount = "你的域名\扫描账号名" # 匹配用户个人目录路径的正则规则 $userDirRegex = [regex]::Escape("D:\FileShare\Users\") + "[^\\]+" # 递归遍历所有文件 Get-ChildItem -Path $rootPath -Recurse -File | ForEach-Object { $currentFile = $_ try { $fileAcl = Get-Acl -Path $currentFile.FullName $fileOwner = $fileAcl.Owner # 校验是否符合处理规则 if ($fileOwner -eq $scannerAccount -and $currentFile.FullName -notmatch $userDirRegex) { $fileAcl.SetAccessRuleProtection($false, $false) Set-Acl -Path $currentFile.FullName -AclObject $fileAcl Write-Host "异常权限文件修复完成: $($currentFile.FullName)" -ForegroundColor Green } } catch { Write-Warning "处理失败: $($currentFile.FullName),错误: $($_.Exception.Message)" } }
- 试运行验证方法:将脚本中
Set-Acl所在行注释后执行,脚本只会输出命中的待处理文件路径,确认列表无异常后再取消注释执行正式修改 - 若扫描账号为服务器本地账号,
$scannerAccount格式写为服务器主机名\账号名即可 - 执行账号需要对目标路径下所有文件拥有「取得所有权」「修改权限」的权限,否则会出现处理失败的报错
- 脚本不会修改任何文件夹的权限配置,不会破坏现有目录结构的权限体系
内容的提问来源于stack exchange,提问作者Darius Dauer

