如何改进PowerShell函数以返回ADObject的全部可用属性?
问题:验证AD域对象属性可用性的函数改进
我需要查询多个域的用户数据,由于不同域的配置和功能存在差异,因此在执行查询前,我希望验证所需返回的属性是否在目标域中可用,以避免执行过程中出现错误。
为此我编写了如下函数:
function Get-ADDomainSupportedProperty { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Server = $Env:USERDNSDOMAIN, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$ObjectType = "User", [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string[]]$Property ) # Get all available properties in the domain $params = @{ SearchBase = (Get-ADRootDSE -Server $Server).SchemanamingContext Filter = { Name -eq $ObjectType } Server = $Server Properties = "*" } $allProperties = Get-ADObject @params # Select all default properties $allDefaultProperties = $allProperties | Get-Member -MemberType "Properties" | Select-Object -ExpandProperty Name | Where-Object { $_ -notin @("MayContain", "SystemMayContain") } # Select all extended properties $allExtendedProperties = $allProperties | Select-Object @{ Name = "Properties"; Expression = { $_.MayContain + $_.SystemMayContain }} | Select-Object -ExpandProperty "Properties" $allAvailableProperties = $allDefaultProperties + $allExtendedProperties | Sort-Object -Unique # Return available properties if ($Property) { $Property | Where-Object { $_ -in $allAvailableProperties } } else { $allAvailableProperties } }
该函数基本能按预期工作,可返回扩展属性数组,但无法返回部分默认属性(例如sn或Company)。请问有谁能提供改进建议,让我的函数可以返回所有可用属性?
编辑
在社区帮助下,以下是最终版函数,供有需要的人使用:
<# .SYNOPSIS 检索指定Active Directory对象类型支持的属性。 .DESCRIPTION Get-ADDomainSupportedAttribute函数检索指定Active Directory对象类型支持的属性。 你可以指定服务器、对象类型和要检索的属性,也可以选择只检索必填或可选属性。 .PARAMETER Server 要连接的服务器,默认为当前用户的DNS域。 .PARAMETER ObjectType 要检索属性的Active Directory对象类型,默认为"User"。 .PARAMETER Attribute 要检索的特定属性,属于Attribute参数集。 .PARAMETER MandatoryOnly 仅检索必填属性的开关,属于Mandatory参数集。 .PARAMETER OptionalOnly 仅检索可选属性的开关,属于Optional参数集。 .EXAMPLE PS> Get-ADDomainSupportedAttribute -Server "dc.domain.local" -ObjectType "User" 检索指定服务器上"User"对象类型的所有支持属性。 .EXAMPLE PS> Get-ADDomainSupportedAttribute -ObjectType "Computer" -MandatoryOnly 仅检索"Computer"对象类型的必填属性。 .EXAMPLE PS> Get-ADDomainSupportedAttribute -Attribute "cn", "sn" 检索指定属性"cn"和"sn"。 .NOTES 在社区帮助下创建 #> # 模块作用域的哈希表,用于缓存每个服务器的架构信息 $schemaCache = @{} function Get-ADDomainSupportedAttribute { [CmdletBinding(DefaultParameterSetName = "Default")] param ( [Parameter(Mandatory = $false, ParameterSetName = "Default")] [Parameter(Mandatory = $false, ParameterSetName = "Attribute")] [Parameter(Mandatory = $false, ParameterSetName = "Mandatory")] [Parameter(Mandatory = $false, ParameterSetName = "Optional")] [ValidateNotNullOrEmpty()] [string]$Server = $env:USERDNSDOMAIN, [Parameter(Mandatory = $false, ParameterSetName = "Default")] [Parameter(Mandatory = $false, ParameterSetName = "Attribute")] [Parameter(Mandatory = $false, ParameterSetName = "Mandatory")] [Parameter(Mandatory = $false, ParameterSetName = "Optional")] [ValidateNotNullOrEmpty()] [string]$ObjectType = "User", [Parameter(Mandatory = $false, ParameterSetName = "Attribute")] [ValidateNotNullOrEmpty()] [string[]]$Attribute, [Parameter(Mandatory = $false, ParameterSetName = "Mandatory")] [switch]$MandatoryOnly, [Parameter(Mandatory = $false, ParameterSetName = "Optional")] [switch]$OptionalOnly ) # 如果当前服务器不在缓存中,添加到缓存 if (-not $script:schemaCache.ContainsKey($Server)) { $classSchemaSearchParams = @{ SearchBase = (Get-ADRootDSE -Server $Server).schemaNamingContext Server = $Server Filter = { objectClass -eq "classSchema" } Properties = "lDAPDisplayName", "auxiliaryClass", "systemAuxiliaryClass", "mayContain", "systemMayContain", "mustContain", "systemMustContain", "subClassOf" } $allClassSchemas = @{} Get-ADObject @classSchemaSearchParams | ForEach-Object { $allClassSchemas[$_.lDAPDisplayName] = $_ } $script:schemaCache[$Server] = $allClassSchemas } # 从缓存中获取架构表 $allClassSchemas = $script:schemaCache[$Server] # 用于跟踪发现的属性和已解析的类的数组 $mayBag = @() $mustBag = @() $resolved = @() [array]$unresolved = @($ObjectType) while ($unresolved.Count) { # 选择下一个要解析属性和关系的类名 $next, $unresolved = $unresolved if (-not $allClassSchemas.ContainsKey($next)) { Write-Error "未找到LDAP显示名为'${next}'的类架构" return } # 查找给定类的架构对象 $nextSchema = $allClassSchemas[$next] # 确保不重复工作或进入循环 if ($nextSchema.lDAPDisplayName -in $resolved) { continue } # 获取与当前类架构关联的属性 $mayBag += @( $nextSchema.mayContain $nextSchema.systemMayContain ) $mustBag += @( $nextSchema.mustContain $nextSchema.systemMustContain ) # 除非架构指向自身(top类),否则将父类加入解析队列 if ($nextSchema.subClassOf -and $nextSchema.subClassOf -ne $nextSchema.lDAPDisplayName) { $unresolved += $nextSchema.subClassOf } # ...然后加入辅助类 if ($nextSchema.auxiliaryClass) { $unresolved += @($nextSchema.auxiliaryClass) } if ($nextSchema.systemAuxiliaryClass) { $unresolved += @($nextSchema.systemAuxiliaryClass) } # ...最后将当前架构添加到已解析类列表中 $resolved += $nextSchema.lDAPDisplayName } # 返回可用属性 if ($Attribute) { # 仅返回$Attribute参数中指定的属性名 $Attribute | Where-Object { $_ -in $mayBag + $mustBag | Sort-Object -Unique } } elseif ($MandatoryOnly) { # 仅返回必填属性名 $mustBag | Sort-Object -Unique } elseif ($OptionalOnly) { # 仅返回可选属性名 $mayBag | Sort-Object -Unique } else { # 返回所有属性名 $mayBag + $mustBag | Sort-Object -Unique } }
内容的提问来源于stack exchange,提问作者TheBrickAdmin
相关产品推荐
相关产品推荐

