PowerShell:显示文件夹与其父文件夹之间的权限差异

PowerShell: Display the differences in permissions between folders and their parents

我希望想出一个脚本,可以在 Windows 服务器上遍历目录树,并向我展示一棵仅包含权限不同于其父(或子)目录的目录的树.我想生成一个易于理解的报告,可以帮助我快速审核文件夹结构的权限。

这是我目前得到的:

DIR "Z:\FileShare" -directory -recurse | GET-ACL | where {$_.AreAccessRulesProtected -eq $true} | select path, accessToString | format-list  |out-file c:\permissions.txt

这会按原样生成一组可用的数据,但有点庞大。

我不知道如何让它过滤掉冗余文本,即像“BUILTIN\Administrators Allow FullControl”这样的行,而不是只显示增量。人类可读的伪代码可能是“如果可以在直接父目录中找到此 ACL 行,则不要在此处显示它。”

我用我自己的用户设置了不同 ACL 的几个文件夹对此进行了测试,它似乎可以正常工作,但我还没有进行足够的测试来确定。基本上,脚本将遍历目录并将 ACL 添加到字典中,其中 Keys 每个 IdentityReferenceValues 是除了文件夹的绝对路径之外,您感兴趣的 ACL 中的属性(FileSystemRightsAccessControlType)。在枚举目录时,将使用 Compare-Acl 函数将每个对象与存储的值进行比较,如果对象不同,则只有 returns $true

using namespace System.Collections
using namespace System.Collections.Generic

$map = [Dictionary[string, ArrayList]]::new()

$outObj = {
    [pscustomobject]@{
        AbsolutePath      = $dir.FullName
        FileSystemRights  = $acl.FileSystemRights
        IdentityReference = $acl.IdentityReference
        AccessControlType = $acl.AccessControlType
    }
}

function Compare-Acl {
param(
    [object[]]$Reference,
    [object]$Difference
)
    foreach($ref in $Reference)
    {
        $fsRights = $ref.FileSystemRights -eq $Difference.FileSystemRights
        $actRef = $ref.AccessControlType -eq $Difference.AccessControlType
        if($fsRights -and $actRef)
        {
            return $false
        }
    }
    $true
}

foreach($dir in Get-ChildItem Z:\FileShare -Directory -Recurse)
{
    foreach($acl in (Get-Acl $dir.FullName | Where-Object AreAccessRulesProtected).Access)
    {
        if($thisKey = $map[$acl.IdentityReference])
        {
            $obj = & $outObj
            if(Compare-Acl -Reference $thisKey -Difference $obj)
            {
                $null = $thisKey.Add($obj)
            }
            continue
        }
        $obj = & $outObj
        $null = $map.Add($acl.IdentityReference, [object[]]$obj)
    }
}

$map.Keys.ForEach({ $map[$_] })| Export-Csv path\to\acls.csv -NoTypeInformation