找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 44|回复: 2

关于ntfs文件系统的acl 访问控制列表

[复制链接]
发表于 2025-11-23 14:13:23 | 显示全部楼层 |阅读模式
本帖最后由 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 - 在符号链接而不是其目标上执行操作











 楼主| 发表于 2025-11-25 15:42:50 | 显示全部楼层
$folderPath = "g:\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 {if($_.psiscontainer){
$acl=get-acl $_.fullname
$acl.setaccessrule($rule)
set-acl -path $_.fullname -aclobject $acl
}else{
$acl=get-acl $_.fullname
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("Everyone","changepermissions,takeownership,delete,deletesubdirectoriesandfiles","none", "None","Deny")
$acl.setaccessrule($rule)
set-acl -path $_.fullname -aclobject $acl
}}    -对于子文件能否继承权限,确实牢绑了,但可能会这样的问题:对于子文件夹和子文件,一是继承了权限,二是又用foreach-object又专门弄了一遍权限,get-acl的时候会看到isInherited一个false一个true 2个deny权限。
        就当练习if else语句了





回复

使用道具 举报

 楼主| 发表于 2025-11-27 15:18:37 | 显示全部楼层
# 判定父文件夹的权限与子文件和子文件夹是否一致

# 获取父文件夹路径
$parentPath = "C:\Program Files (x86)\SogouInput\Components\biz_center"

# 获取所有子项(包括文件和文件夹)
$allItems = Get-ChildItem -Path $parentPath -Recurse

# 查询没有特定Deny权限的项目
$itemsWithoutDeny = $allItems | Where-Object {
    $currentItem = $_
    $acl = Get-Acl -Path $currentItem.FullName

    # 检查是否有Everyone的特定Deny权限
    $hasTargetDeny = $acl.Access | Where-Object {
        $_.IdentityReference -eq "Everyone" -and
        $_.AccessControlType -eq "Deny" -and
   #下边这句对应想测试的权限 ,也就是父文件夹的权限
       $_.filesystemrights -eq "DeleteSubdirectoriesAndFiles, Write, Delete, ChangePermissions, TakeOwnership"
    }

    # 如果没有找到匹配的Deny权限,则返回True(包含在结果中)
    return (-not $hasTargetDeny)
}

# 输出结果
Write-Host "以下项目没有Everyone的特定Deny权限:" -ForegroundColor Green
$itemsWithoutDeny | ForEach-Object {
    Write-Host "  $($_.FullName)" -ForegroundColor Yellow
}

# 统计信息
Write-Host "`n统计信息:" -ForegroundColor Cyan
Write-Host "  总项目数: $($allItems.Count)" -ForegroundColor White
Write-Host "  无Deny权限项目数: $($itemsWithoutDeny.Count)" -ForegroundColor White







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1|闽公网安备35020302032614号 )

GMT+8, 2026-8-5 03:45

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表