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 每个 IdentityReference
和 Values 是除了文件夹的绝对路径之外,您感兴趣的 ACL 中的属性(FileSystemRights
和 AccessControlType
)。在枚举目录时,将使用 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
我希望想出一个脚本,可以在 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 每个 IdentityReference
和 Values 是除了文件夹的绝对路径之外,您感兴趣的 ACL 中的属性(FileSystemRights
和 AccessControlType
)。在枚举目录时,将使用 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