Get-ADPrincipalGroupMembership 发生未指定的错误 [英] Get-ADPrincipalGroupMembership An unspecified error has occurred

查看:133
本文介绍了Get-ADPrincipalGroupMembership 发生未指定的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Windows 10 (x64) 机器上使用 Get-ADPrincipalGroupMembership 命令时遇到错误.我已经按照指定的 int this 文档.我能够执行 Get-AdUser 并查看结果,但 Get-ADPrincipalGroupMembership 抛出以下错误.

I am getting errors with Get-ADPrincipalGroupMembership command on Windows 10 (x64) machine. I have installed the required RSAT- 'Active directory Domain service and Lightweight Directory service tools' and 'Server manager' dependencies as specified int this document. I am able to execute Get-AdUser and see the results but Get-ADPrincipalGroupMembership is throwing below error.

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 的修复方法是什么

but like to know what is the fix for Get-ADPrincipalGroupMembership

推荐答案

正如您所注意到的,如果引用对象的名称包含某些字符,或者它是一个一个或多个名称中包含某些字符的组的成员.

As you have noticed, Get-ADPrincipalGroupMembership fails with an obscure error if the reference object's name contains certain characters, or if it's a member of one or more groups that contain certain characters in their names.

我没有确切的证据,但我的测试表明根本问题是 Get-ADPrincipalGroupMembership 在内部使用 ADSI 并且无法正确转义包含 需要转义的字符.(如果是这种情况,Microsoft 应该使用 IADsPathname 接口 以正确转义名称.这将是他们令人尴尬的疏忽.)

I don't have definitive proof, but my testing indicates that the underlying issue is that Get-ADPrincipalGroupMembership, internally, uses ADSI and fails to correctly escape distinguished names that contain characters that need to be escaped. (If this is the case, Microsoft should be using the IADsPathname interface to escape names correctly. This would be an embarrassing oversight on their part.)

不幸的是,此问题导致 cmdlet 损坏且无法在生产环境中使用.

Unfortunately, this problem renders the cmdlet broken and unusable in production environments.

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

Here's a relatively short PowerShell script that doesn't suffer from this annoyance and also supports retrieving recursive group memberships:

# 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
  }
}

我还将此脚本添加为 github 上的公共要点,以防万一有些东西需要修复或者我添加了新功能.

I've also added this script as a public gist on github in case something needs fixing or if I add new features.

这篇关于Get-ADPrincipalGroupMembership 发生未指定的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆