本帖最后由 likeyouli 于 2025-11-27 17:02 编辑
因为很多知识我也没搞懂, 所以暂时发布在娱乐区, 权当娱乐. 官方:https://learn.microsoft.com/zh-c ... missions-powershell
第一步是声明包含 Folder1 的现有 ACL 规则的变量。 $ACL = Get-Acl -Path C:\Folder1第二步是新建 FileSystemAccessRule 变量,该变量指定要应用的访问规范: $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("User1","Modify","Allow")第三步是将新的访问规则添加到 Folder1 的现有 ACL 规则中: $ACL.SetAccessRule($AccessRule)最后,需要将新的 ACL 应用于 Folder1: $ACL | Set-Acl -Path C:\Folder1
1. 获取文件的权限 :
(Get-ACL -Path "d:\14").Access | Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited,InheritanceFlags,PropagationFlags -AutoSize
IsInherited: False:表示这两条规则是直接应用在 D:\14 这个文件夹上的,而不是从它的父级(比如 D:\)继承来的
InheritanceFlags: ContainerInherit, ObjectInherit:表示这两条规则会向下传递。任何在 D:\14 内部新建的子文件夹或文件,都将自动继承这两条(一个拒绝、一个允许)权限规则。PropagationFlags 的取值:None 无特殊传播,这是默认行为,继承的权限会正常应用到目标对象及其子对象;InheritOnly 仅继承,该权限规则不会应用到当前对象,只会传播给其子对象。
2. 针对文件夹可以这样写权限(文件会报错,因为文件不能有这几个参数"ContainerInherit, ObjectInherit"、ListDirectory、DeleteSubdirectoriesAndFiles):
$folderPath = "C:\11"
$acl = Get-Acl $folderPath
# 移除所有现有的Everyone规则
$rulesToRemove = $acl.Access | Where-Object { $_.IdentityReference -eq "Everyone" }
foreach ($rule in $rulesToRemove) {
$acl.RemoveAccessRule($rule) | Out-Null
}
# 关键步骤:禁用权限继承并清除所有现有权限
$acl.SetAccessRuleProtection($false, $true)
# 使用枚举值定义权限
$allowRights = [System.Security.AccessControl.FileSystemRights]::ReadData -bor
[System.Security.AccessControl.FileSystemRights]::ReadAttributes -bor
[System.Security.AccessControl.FileSystemRights]::ReadExtendedAttributes -bor
[System.Security.AccessControl.FileSystemRights]::ExecuteFile -bor
[System.Security.AccessControl.FileSystemRights]::ListDirectory -bor
[System.Security.AccessControl.FileSystemRights]::Synchronize
$denyRights = [System.Security.AccessControl.FileSystemRights]::WriteData -bor
[System.Security.AccessControl.FileSystemRights]::AppendData -bor
[System.Security.AccessControl.FileSystemRights]::WriteAttributes -bor
[System.Security.AccessControl.FileSystemRights]::WriteExtendedAttributes -bor
[System.Security.AccessControl.FileSystemRights]::Delete -bor
[System.Security.AccessControl.FileSystemRights]::DeleteSubdirectoriesAndFiles -bor
[System.Security.AccessControl.FileSystemRights]::ChangePermissions -bor
[System.Security.AccessControl.FileSystemRights]::TakeOwnership -bor
[System.Security.AccessControl.FileSystemRights]::WriteDacl -bor
[System.Security.AccessControl.FileSystemRights]::WriteOwner
# 创建允许规则
$allowRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Everyone",
$allowRights,
"ContainerInherit, ObjectInherit",
"None",
"Allow"
)
$acl.setAccessRule($allowRule)
# 创建拒绝规则
$denyRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Everyone",
$denyRights,
"ContainerInherit, ObjectInherit",
"None",
"Deny"
)
$acl.setAccessRule($denyRule)
Set-Acl $folderPath $acl
3. powershell中可以自定义到函数,方便使用:function zhinengduqu {
$folderPath = $PWD.Path
$acl = Get-Acl $folderPath
#$acl.SetAccessRuleProtection($true, $false) 权限继承的问题,先注释掉测试测试再说吧
#Get-Childitem $folderPath -Recurse | ForEach-Object {
#$itemAcl = Get-Acl $_.FullName
#$itemAcl.SetAccessRuleProtection($false,$false)} 同上,权限继承的问题,先注释掉测试测试再说吧,因为后边对每个子文件夹#和子文件都用了ForEach-Object set-acl
# 移除所有现有的Everyone规则
$rulesToRemove = $acl.Access | Where-Object { $_.IdentityReference -eq "Everyone" }
foreach ($rule in $rulesToRemove) {
$acl.RemoveAccessRule($rule) | Out-Null
}
# 分解权限设置,避免组合权限
$allowPermissions = @(
"ReadData", # 读取文件数据
"ReadAttributes", # 读取文件属性
"ReadExtendedAttributes", # 读取扩展属性
"ExecuteFile", # 执行文件
"ListDirectory", # 列出文件夹内容
"Synchronize" # 同步
)
$denyPermissions = @(
"WriteData", # 写入数据
"AppendData", # 追加数据
"WriteAttributes", # 写入属性
"WriteExtendedAttributes", # 写入扩展属性
"Delete", # 删除文件
"DeleteSubdirectoriesAndFiles", # 删除子项
"ChangePermissions", # 更改权限
"TakeOwnership" # 取得所有权
# "WriteDacl" # 防止修改DACL 必须得注释掉,否则报错
# "WriteOwner" # 防止修改所有者 必须得注释掉,否则报错
)
# 创建允许规则
$allowRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Everyone",
($allowPermissions -join ","),
"ContainerInherit, ObjectInherit",
"None",
"Allow"
)
$acl.AddAccessRule($allowRule)
# 创建拒绝规则
$denyRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Everyone",
($denyPermissions -join ","),
"ContainerInherit, ObjectInherit",
"None",
"Deny"
)
$acl.AddAccessRule($denyRule)
Set-Acl -Path $folderPath -AclObject $acl
Get-ChildItem -Path $folderPath -Recurse | ForEach-Object {
Set-Acl -Path $_.FullName -AclObject $acl
}}
4. 更简单的写法 : $folderPath = "C:\11";$acl = Get-Acl $folderPath;$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("Everyone","changepermissions,takeownership,delete,deletesubdirectoriesandfiles","ContainerInherit, ObjectInherit", "None","Deny");$acl.SetAccessRule($rule);Set-Acl -path $folderPath -aclobject $acl;Get-ChildItem -Path $folderPath -Recurse | ForEach-Object {Set-Acl -Path $_.FullName -AclObject $acl} -- 这里的$acl.SetAccessRule($rule)可以改为$acl.AddAccessRule($rule)、$acl.removeAccessRule($rule)
5. # 只移除 BUILTIN\Administrators 的 Deny 权限:icacls "C:\" /remove:d "BUILTIN\Administrators"
# 只移除 BUILTIN\Administrators 的 Allow 权限 :icacls "C:\" /remove:g "BUILTIN\Administrators"
# 移除 BUILTIN\Administrators 的所有权限(包括 Allow 和 Deny):icacls "C:\" /remove "BUILTIN\Administrators"
6. 将安全描述符复制到新对象Get-Acl -Path C:\Folder1|Set-ACL -Path C:\Folder2 ,经过多次测试确认,C:\Folder1的权限复制给C:\Folder2,但不会传递给C:\Folder2的子文件夹和子文件,如果要想传递下去,可以这样,利用模板:$folderpath= "d:\14"; $muban = get-acl -path $folderpath; get-childitem -r $folderpath | set-acl -aclobject $muban ,而且这样弄的权限显示为继承权限(isInherited显示为true,糟糕,经过测试发现又发现显示为false,可能muban那里为true后边就显示true,muban那里为false,就显示为false)。
使文件夹的权限传递到子文件和子文件夹(尤其当$acl.removeAccessRule($rule) 去掉文件夹的deny权限后,子文件和子文件夹还是deny,这样处理下就可以了):
$folderPath = "d:\14";icacls $folderPath /reset /t /c /l
# /reset - 用默认继承的权限替换所有显式权限
# /t - 递归应用到所有子文件夹和文件
# /c - 继续操作尽管有错误
# /l - 在符号链接而不是其目标上执行操作
|