使用PowerShell有效访问Active Directory对象

3
我正试图获取各种Active Directory对象上某些活动目录用户的有效权限。我可以从UI中看到这些权限-enter image description here 我正在尝试使用Powershell来实现这一点。我已经尝试过dsacls和Get-Acls,但这些都没有给出有效的权限。这两者都给出了“谁有访问/权限”,而这不同于“谁拥有什么有效权限”。它们也没有列出提供有效访问背景的所有细节。
对于如何通过编程实现这一点的任何指示都将不胜感激。
更新-
这里的有效权限意味着基于继承或在不同级别设置的其他规则,该对象实际允许哪些权限。
例如-
在下面的示例中,Get-ACL中没有显示所有属性。 enter image description here 当我通过Get-ACL拉取域管理员对其中一个OU的权限时,解析ObjectType和InheritedObjectType中的值(使用Santiago Squarzon提到的get-effective access函数)后,我得到- enter image description here 而UI有效访问显示-enter image description here 我的最终目标是使用powershell获取上述屏幕截图中的所有权限。

Get-Acl 应该给你提供那些信息。使用分组运算符(..)来公开该代码属性。(Get-ACL .\).Access。您可以澄清一下“有效权限”是什么意思吗? - Abraham Zinala
ACL 中显示的“所有对象(完全控制)”表示对 ActiveDirectoryRights 的完全控制,这与“高级安全设置”的“有效访问”不同。将您已知具有完全控制权限的 IdentityReference 与您正在显示的 IdentityReference 进行比较,您会看到差异。此外,您没有显示是否存在其他 ACL 拒绝对该 IdentityReference 的“完全控制”。正如我在答案中所说,您需要知道如何阅读“Get-ACL”的输出结果。 - Santiago Squarzon
这是域控制器的唯一条目。它没有任何拒绝规则。我没有包含身份引用,因为我想避免对图像进行审查。两个屏幕截图显示相同身份引用的结果。 - Steve_Greenwood
仅供参考,我编辑了我的答案,以向您展示完全控制WriteDACL相比的外观。 - Santiago Squarzon
2个回答

2
这很接近你所寻找的内容。有关更多详细信息,请参见源代码。使用Get-ACL的访问控制列表不像高级安全设置中的有效访问那样易于阅读,我认为这是无法避免的。但是,一旦习惯了它,当你知道自己在寻找什么时,Get-ACL会提供更多详细信息并可筛选ACL以获取所需内容。
function Get-EffectiveAccess {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidatePattern('(?:(CN=([^,]*)),)?(?:((?:(?:CN|OU)=[^,]+,?)+),)?((?:DC=[^,]+,?)+)$')]
        [alias('DistinguishedName')]
        [string] $Identity,

        [parameter()]
        [alias('Domain')]
        [string] $Server
    )

    begin {
        $guid    = [guid]::Empty
        $GUIDMap = @{}

        if($PSBoundParameters.ContainsKey('Server')) {
            $domain = Get-ADRootDSE -Server $Server
        }
        else {
            $domain = Get-ADRootDSE
        }

        $params = @{
            SearchBase  = $domain.schemaNamingContext
            LDAPFilter  = '(schemaIDGUID=*)'
            Properties  = 'name', 'schemaIDGUID'
            ErrorAction = 'SilentlyContinue'
        }
        $adObjParams = @{
            Properties = 'nTSecurityDescriptor'
        }

        if($PSBoundParameters.ContainsKey('Server')) {
            $params['Server']  = $Server
            $adObjParams['Server'] = $Server
        }
        $schemaIDs = Get-ADObject @params

        $params['SearchBase'] = "CN=Extended-Rights,$($domain.configurationNamingContext)"
        $params['LDAPFilter'] = '(objectClass=controlAccessRight)'
        $params['Properties'] = 'name', 'rightsGUID'
        $extendedRigths = Get-ADObject @params

        foreach($i in $schemaIDs) {
            if(-not $GUIDMap.ContainsKey([guid] $i.schemaIDGUID)) {
                $GUIDMap.Add([guid] $i.schemaIDGUID, $i.name)
            }
        }
        foreach($i in $extendedRigths) {
            if(-not $GUIDMap.ContainsKey([guid] $i.rightsGUID)) {
                $GUIDMap.Add([guid] $i.rightsGUID, $i.name)
            }
        }
    }

    process {
        try {
            $adObjParams['Identity'] = $Identity
            $object = Get-ADObject @adObjParams

            foreach($acl in $object.nTSecurityDescriptor.Access) {
                if($guid.Equals($acl.ObjectType)) {
                    $objectType = 'All Objects (Full Control)'
                }
                elseif($GUIDMap.ContainsKey($acl.ObjectType)) {
                    $objectType = $GUIDMap[$acl.ObjectType]
                }
                else {
                    $objectType = $acl.ObjectType
                }

                if($guid.Equals($acl.InheritedObjectType)) {
                    $inheritedObjType = 'Applied to Any Inherited Object'
                }
                elseif($GUIDMap.ContainsKey($acl.InheritedObjectType)) {
                    $inheritedObjType = $GUIDMap[$acl.InheritedObjectType]
                }
                else {
                    $inheritedObjType = $acl.InheritedObjectType
                }

                [PSCustomObject]@{
                    Name                  = $object.Name
                    IdentityReference     = $acl.IdentityReference
                    AccessControlType     = $acl.AccessControlType
                    ActiveDirectoryRights = $acl.ActiveDirectoryRights
                    ObjectType            = $objectType
                    InheritedObjectType   = $inheritedObjType
                    InheritanceType       = $acl.InheritanceType
                    IsInherited           = $acl.IsInherited
                }
            }
        }
        catch {
            $PSCmdlet.WriteError($_)
        }
    }
}

例子

  • 获取名为ExampleOU的组织单位的有效访问权限
Get-ADOrganizationalUnit -Filter "Name -eq 'ExampleOU'" |
    Get-EffectiveAccess | Out-GridView
  • 获取受信任域上名为ExampleOU的组织单位的有效访问权限
Get-ADOrganizationalUnit -Filter "Name -eq 'ExampleOU'" -Server trustedDomain |
    Get-EffectiveAccess -Server trustedDomain | Out-GridView
  • 使用OU的DistinguishedName属性,方法同上:
Get-EffectiveAccess -Identity 'OU=ExampleOU,DC=domainName,DC=com' | Out-GridView
  • 将名为exampleGroup的组的有效访问权限存储在一个变量中:
$effectiveAccess = Get-ADGroup exampleGroup | Get-EffectiveAccess
  • 获取域中前10个OU的有效访问权限
Get-ADOrganizationalUnit -Filter * | Select -First 10 |
    Get-EffectiveAccess | Out-GridView

示例

供参考,以下是使用 Get-ACL 命令查看完全控制权限的效果:

fullcontrol

相比之下,BUILTIN\Administrators 对此 OU 具有写入权限,但没有完全控制权限

writepermissions


1
感谢您提供信息和代码,这非常有用。根据我的初步测试,这比解析ObjectType和InheritedObjectType中的值提供了更多的信息。它仍然无法获取您可以在Effective Access中看到的权限。 此外,使用get-acls函数的权限(如Write ObjectSid、Read ObjectSid等)是不可见的。(将更新问题)而且像Write Property这样的属性并没有告诉我哪些属性是用户被授予访问权限,哪些属性被拒绝了。 - Steve_Greenwood

1
你可以尝试PowerShellAccessControl模块,我认为该模块的详细信息在这个youtube视频中已经介绍了,其中包含函数Get-EffectiveAccess。这应该可以帮助您获取所需的信息。该模块已从Microsoft的PS Gallery删除。我不确定如何从Github安装该模块,因为我使用的是Mac。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接