Powershell 获取ADPrincipalGroupMembership发生未指定的错误

Powershell 获取ADPrincipalGroupMembership发生未指定的错误,powershell,active-directory,Powershell,Active Directory,我在Windows 10(x64)计算机上使用Get-ADPrincipalGroupMembership命令时出错。我已经安装了所需的RSAT-“Active directory域服务和轻型目录服务工具”和“服务器管理器”依赖项,如int文档中指定的。我能够执行Get AdUser并查看结果,但Get ADPrincipalGroupMembership抛出以下错误 PS C:\Users\JYOTHI> Get-ADPrincipalGroupMembership jyothi Get

我在Windows 10(x64)计算机上使用Get-ADPrincipalGroupMembership命令时出错。我已经安装了所需的RSAT-“Active directory域服务和轻型目录服务工具”和“服务器管理器”依赖项,如int文档中指定的。我能够执行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-ADPrincipalGroupMembership-Identity“jyothi”

如果引用对象的名称包含某些字符,
Get-AdPrincipalGroupMembershi
会失败,并出现一个模糊的错误,或者,如果它是一个或多个组的成员,而这些组的名称中包含某些字符


我没有确凿的证据,但我的测试表明根本的问题是
获取ADPrincipalGroupMembership
,在内部使用ADSI,并且无法正确转义包含的可分辨名称。(如果是这样的话,微软应该正确使用转义名称。这将是他们一个令人尴尬的疏忽。)

不幸的是,此问题导致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
  }
}
#Get-ADGroupMembership.ps1
#作者比尔·斯图尔特
#需要-版本2
#版本历史记录:
# 1.0 (2019-12-02)
#*初始版本。仅搜索当前域。
获得ADGroupMembership kendyer的会员资格
.举例
获取kendyer帐户所属组的可分辨名称,包括嵌套组:
PS C:\>获取ADGroupMembership kendyer-递归
.举例
获取代表kendyer帐户所属组的ADGroup对象(需要Active Directory模块):
PS C:\>获取ADGroupMembership kendyer \>获取ADGroupMembership
#>
[CmdletBinding()]
param(
[参数(必需=$true,ValueFromPipeline=$true)]
[String[]]$Identity,
[开关]$Recursive
)
开始{
$CommandName=$MyInvocation.MyCommand.Name
#设置路径名COM对象
$ADS\u ESCAPEDMODE\u ON=2
$ADS\u SETTYPE\u DN=4
$ADS\u格式\u X500\u DN=7
$Pathname=新对象-ComObject“路径名”
if(-not$Pathname){
返回
}
[Void]$Pathname.GetType().InvokeMember(“EscapedMode”、“SetProperty”、$null、$Pathname、$ADS_EscapedMode_ON)
#使用Pathname对象输出正确转义的可分辨名称
函数Get EscapedName{
param(
[字符串]$DiscrimitedName
)
[Void]$Pathname.GetType().InvokeMember(“Set”、“InvokeMethod”、$null、$Pathname、@($distincidencedName、$ADS\u SETTYPE\u DN))
$Pathname.GetType().InvokeMember(“检索”、“InvokeMethod”、$null、$Pathname、$ADS\U格式\U X500\U DN)
}
#使用分页搜索输出对象的memberOf属性(在
#对象是大量组的成员)
函数Get MemberOfAttribute{
param(
[字符串]$DiscrimitedName,
[Ref]$memberOf,
[开关]$recursive
)
$searcher=[ADSISearcher](objectClass=*)”
$searcher.SearchRoot=[ADSI]“LDAP://$(获取EscapedName$DiscrimitedName)”
$lastQuery=$false
$rangeStep=1500
$rangeLow=0
$rangeHigh=$rangeLow+($rangeStep-1)
做{
if(-not$lastQuery){
$property=“memberOf;range={0}-{1}”-f$rangeLow,$rangeHigh
}
否则{
$property=“memberOf;range={0}-*”-f$rangeLow
}
$searcher.PropertiesToLoad.Clear()
[Void]$searcher.PropertiesToLoad.Add($property)
$searchResults=$searcher.FindOne()
if($searchResults.Properties.Contains($property)){
foreach($searchResult.Properties[$property]中的searchResult){
如果($memberOf.Value.Count-gt 100){
写进度`
-活动$CommandName`
-状态“正在获取“$DifferentizedName”的成员资格”`
-当前操作$searchResult
}
if($recursive){
if(-not$memberOf.Value.Contains($searchResult)){
获取MemberOfAttribute$searchResult$memberOf-递归
}
}
if(-not$memberOf.Value.Contains($searchResult)){
$memberOf.Value.Add($searchResult)
}
}
$done=$lastQuery
}
否则{
if(-not$lastQuery){
$lastQuery=$true
}
否则{
$done=$true
}
}
if(-not$lastQuery){
$rangeLow=$rangeHigh+1
$rangeHigh=$rangeLow+($rangeStep-1)
}
}
直到($完成)
写进度`
-活动$CommandName`
-状态“正在获取“$DifferentizedName”的成员资格”`
-已完成:$true
}
函数获取ADGroupMembership{
[CmdletBinding()]
param(
[参数(必需=$true)]
[String]$identity,
[开关]$recursive
)
$ldapString=$identity-replace'\\'、'\5c'-replace'\('、'\28'-replace'\)'、'\29'-replace'\*'、'\2a'-replace'\/'、'\2f'
$searcher=[ADSISearcher]“(|(differentizedName=$ldapString)(sAMAccountName=$ldapString))”
试一试{
$searchResults=$searcher.FindAll()
如果($searchResults.Count-gt 0){
foreach($searchResult中的searchResult){
$memberOf=新对象集合.Generic.List[String]
获取MemberOfAttribute$searchResult.Properties[“DifferentizedName”][0]([Ref]$memberOf)-递归:$recursive
$memberOf
}
}
否则{
写入错误“找不到标识为“$identity”的对象”-类别ObjectNotFound
}
}
抓住{
写入错误-错误记录$_
}
最后{
$searchResults.Dispose()
}
}
}
过程{
foreach($Identity)