【问题标题】:Get-ADPrincipalGroupMembership An unspecified error has occurredGet-ADPrincipalGroupMembership 发生未指定的错误
【发布时间】:2020-03-22 06:04:01
【问题描述】:

我在 Windows 10 (x64) 机器上使用 Get-ADPrincipalGroupMembership 命令出错。我已经按照 int this 文档的指定安装了所需的 RSAT-“活动目录域服务和轻量级目录服务工具”和“服务器管理器”依赖项。我能够执行 Get-AdUser 并查看结果,但 Get-ADPrincipalGroupMembership 抛出错误。

PS C:\Users\JYOTHI> Get-ADPrincipalGroupMembership jyothi
Get-ADPrincipalGroupMembership : An unspecified error has occurred
At line:1 char:1
+ Get-ADPrincipalGroupMembership gapalani
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (jyothi:ADPrincipal) [Get-ADPrincipalGroupMembership], ADException
    + FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADPrincipalGroupMembership

我可以试试其他方法

(Get-Aduser jyothi -Properties MemberOf | Select MemberOf).MemberOf

但想知道 Get-ADPrincipalGroupMembership 的修复方法是什么

【问题讨论】:

  • 我已经看到 Get-ADGroupMember 用于外部受信任域上的成员。但不是Get-ADPrincipalGroupMembership。当您导出memberOf 的内容时,您是否注意到任何组有什么不同?
  • 在组中没有看到任何特殊字符或任何差异,注意到在 windows 服务器机器上执行相同的命令正常
  • 是否有任何组包含/ 字符?
  • 有一个组名包含'\'
  • 如果您查询用户的组成员身份,该用户的组成员资格不是名称包含\/ 字符的组的成员,该cmdlet 是否会失败?

标签: powershell active-directory


【解决方案1】:

如您所见,如果引用对象的名称包含某些字符,或者如果它是一个或多个名称中包含某些字符的组的成员,Get-ADPrincipalGroupMembership 将失败并出现一个模糊的错误。

我没有明确的证据,但我的测试表明根本问题是 Get-ADPrincipalGroupMembership 在内部使用 ADSI 并且无法正确转义包含 characters that need to be escaped 的专有名称。 (如果是这种情况,Microsoft 应该使用 IADsPathname interface 来正确转义名称。这对他们来说将是一个令人尴尬的疏忽。)

很遗憾,此问题导致 cmdlet 在生产环境中损坏且无法使用。

这是一个相对较短的 PowerShell 脚本,它不会受到这种烦恼的影响,还支持检索递归组成员身份:

# Get-ADGroupMembership.ps1
# Written by Bill Stewart

#requires -version 2

# Version history:
# 1.0 (2019-12-02)
# * Initial version. Only searches the current domain.

<#
.SYNOPSIS
Gets the distinguished names of the Active Directory groups that have a specified object as a member.

.DESCRIPTION
Gets the distinguished names of the Active Directory groups that have a specified object, represented by the -Identity parameter, as a member.

.PARAMETER Identity
Specifies an Active Directory object. You can specify either the distinguishedName or the sAMAccountName of the object.

.PARAMETER Recursive
Specifies to include the object's nested group memberships.

.NOTES
If you use the ActiveDirectory PowerShell module and want Microsoft.ActiveDirectory.Management.ADGroup objects as output, pipe this command's output to the Get-ADGroup cmdlet.

.EXAMPLE
Get the distinguished names of the groups that the kendyer account is a member of:
PS C:\> Get-ADGroupMembership kendyer

.EXAMPLE
Get the distinguished names of the groups that the kendyer account is a member of, including nested groups:
PS C:\> Get-ADGroupMembership kendyer -Recursive

.EXAMPLE
Get the ADGroup objects representing the groups that the kendyer account is a member of (requires the Active Directory module):
PS C:\> Get-ADGroupMembership kendyer | Get-ADGroup
#>

[CmdletBinding()]
param(
  [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
  [String[]] $Identity,

  [Switch] $Recursive
)

begin {
  $CommandName = $MyInvocation.MyCommand.Name

  # Set up Pathname COM object
  $ADS_ESCAPEDMODE_ON = 2
  $ADS_SETTYPE_DN = 4
  $ADS_FORMAT_X500_DN = 7
  $Pathname = New-Object -ComObject "Pathname"
  if ( -not $Pathname ) {
    return
  }
  [Void] $Pathname.GetType().InvokeMember("EscapedMode","SetProperty",$null,$Pathname,$ADS_ESCAPEDMODE_ON)

  # Outputs correctly escaped distinguished name using Pathname object
  function Get-EscapedName {
    param(
      [String] $distinguishedName
    )
    [Void] $Pathname.GetType().InvokeMember("Set","InvokeMethod",$null,$Pathname,@($distinguishedName,$ADS_SETTYPE_DN))
    $Pathname.GetType().InvokeMember("Retrieve","InvokeMethod",$null,$Pathname,$ADS_FORMAT_X500_DN)
  }

  # Outputs the memberOf attribute of an object using paged search (in case
  # an object is a member of a large number of groups)
  function Get-MemberOfAttribute {
    param(
      [String] $distinguishedName,
      [Ref] $memberOf,
      [Switch] $recursive
    )
    $searcher = [ADSISearcher] "(objectClass=*)"
    $searcher.SearchRoot = [ADSI] "LDAP://$(Get-EscapedName $distinguishedName)"
    $lastQuery = $false
    $rangeStep = 1500
    $rangeLow = 0
    $rangeHigh = $rangeLow + ($rangeStep - 1)
    do {
      if ( -not $lastQuery ) {
        $property = "memberOf;range={0}-{1}" -f $rangeLow,$rangeHigh
      }
      else {
        $property = "memberOf;range={0}-*" -f $rangeLow
      }
      $searcher.PropertiesToLoad.Clear()
      [Void] $searcher.PropertiesToLoad.Add($property)
      $searchResults = $searcher.FindOne()
      if ( $searchResults.Properties.Contains($property) ) {
        foreach ( $searchResult in $searchResults.Properties[$property] ) {
          if ( $memberOf.Value.Count -gt 100 ) {
            Write-Progress `
              -Activity $CommandName `
              -Status "Getting membership of '$distinguishedName'" `
              -CurrentOperation $searchResult
          }
          if ( $recursive ) {
            if ( -not $memberOf.Value.Contains($searchResult) ) {
              Get-MemberOfAttribute $searchResult $memberOf -recursive
            }
          }
          if ( -not $memberOf.Value.Contains($searchResult) ) {
            $memberOf.Value.Add($searchResult)
          }
        }
        $done = $lastQuery
      }
      else {
        if ( -not $lastQuery ) {
          $lastQuery = $true
        }
        else {
          $done = $true
        }
      }
      if ( -not $lastQuery ) {
        $rangeLow = $rangeHigh + 1
        $rangeHigh = $rangeLow + ($rangeStep - 1)
      }
    }
    until ( $done )
    Write-Progress `
      -Activity $CommandName `
      -Status "Getting membership of '$distinguishedName'" `
      -Completed:$true
  }

  function Get-ADGroupMembership {
    [CmdletBinding()]
    param(
      [Parameter(Mandatory = $true)]
      [String] $identity,
      [Switch] $recursive
    )
    $ldapString = $identity -replace '\\','\5c' -replace '\(','\28' -replace '\)','\29' -replace '\*','\2a' -replace '\/','\2f'
    $searcher = [ADSISearcher] "(|(distinguishedName=$ldapString)(sAMAccountName=$ldapString))"
    try {
      $searchResults = $searcher.FindAll()
      if ( $searchResults.Count -gt 0 ) {
        foreach ( $searchResult in $searchResults ) {
          $memberOf = New-Object Collections.Generic.List[String]
          Get-MemberOfAttribute $searchResult.Properties["distinguishedname"][0] ([Ref] $memberOf) -recursive:$recursive
          $memberOf
        }
      }
      else {
        Write-Error "Cannot find an object with identity '$identity'." -Category ObjectNotFound
      }
    }
    catch {
      Write-Error -ErrorRecord $_
    }
    finally {
      $searchResults.Dispose()
    }
  }
}

process {
  foreach ( $IdentityItem in $Identity ) {
    Get-ADGroupMembership $IdentityItem -recursive:$Recursive
  }
}

我还将此脚本添加为public gist on github,以防需要修复或添加新功能。

【讨论】:

    【解决方案2】:

    Get-ADPrincipalGroupMembership -Identity "jyothi"

    【讨论】:

    • Get-ADPrincipalGroupMembership -Identity jyothi 忘记引号
    猜你喜欢
    • 1970-01-01
    • 2011-02-06
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多