0

私が書いているスクリプトで使用したいこの関数を見つけましたが、アカウントがグループにあることがわかり、その理由がわからない場合でも、$false が返され続けます。

function Check-IsGroupMember{

Param($user,$grp)

$strFilter = "(&(objectClass=Group)(name=" + $grp +"))"

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
 $objSearcher.SearchRoot = $objDomain
 $objSearcher.PageSize = 1000
 $objSearcher.Filter = $strFilter
 $objSearcher.SearchScope = "Subtree"

$colResults = $objSearcher.FindOne()

$objItem = $colResults.Properties
 ([string]$objItem.member).contains($user)

}
Usage:

Check-IsGroupMember "name of user" "DomainAdmins"
4

1 に答える 1

1

$objItem.memberDistinguishedNameグループのメンバーである各プリンシパルの値が含まれます。

個人の正式名称は かもしれませんが、John Doeユーザー アカウント オブジェクトの一般名は などかもしれません。これは、チェック (単純な部分文字列検索) が期待どおりに機能することが保証されていないことを意味します。Doe, JohnJohn G. DoeContains()

チェックする唯一の実際の方法は、ユーザーが別の検索を実行して自分の を見つけることDistinguishedNameです。

個人的には、を使用するのではなく、RSATの AD PowerShell モジュールを使用しDirectorySearcherます。

function Test-GroupMembership 
{
  Param(
    [string]$UserName,
    [string]$GroupName
  )

  $User  = Get-ADUser -Identity $UserName
  $Group = Get-ADGroup -Identity $GroupName -Properties member

  $Group.member -contains $User.DistinguishedName
}

サイズ制限が問題の場合は、 を使用してメンバー属性の範囲結果DirectoryServerを取得できます。

function Test-GroupMembership 
{
  [CmdletBinding()]
  Param(
    [string]$UserName,
    [string]$GroupName
  )

  # Fetch User
  $User = Get-ADUser -Identity $UserName

  # return on failure
  if(-not $User){
    Write-Error -Message ('User "{0}" not found' -f $GroupName)
    return $false
  }

  # Use DirectorySearcher to retrieve ranged member attribute
  $GroupSearcher = '' -as [adsisearcher]
  $GroupSearcher.Filter = '(&(objectClass=group)(name={0}))' -f $GroupName
  $GroupSearcher.SearchScope = 'Subtree'
  $GroupSearcher.SearchRoot = '' -as [adsi]

  # AD reponds with at least 1500 values per multi-value attribute since Windows Server 2003
  $Start = 1
  $Range = 1500
  $GroupMembers = @()

  $HasMoreMembers = $false

  # Keep retrieving member values until we've got them all
  do{

    # Use range operator to "page" values
    # Ref: https://msdn.microsoft.com/en-us/library/aa367017(v=vs.85).aspx
    $RangedMember = 'member;range={0}-{1}' -f $Start,$($Start + $Range - 1)
    $GroupSearcher.PropertiesToLoad.Add($RangedMember) | Out-Null

    # Retrieve group        
    $Group = $GroupSearcher.FindOne()

    # return on failure
    if(-not $Group) {
      Write-Error -Message ('Group "{0}" not found' -f $GroupName)
      return $false
    }

    # If we've reached the end of the member list, 
    # AD will return a property where the upper range
    # value is *, so it might not be the same property 
    # name we specified in PropertiesToLoad
    $ReturnedMember = @($Group.Properties.PropertyNames) -like 'member;*'

    # Add all members to the $GroupMembers variable
    foreach($member in $Group.Properties."$ReturnedMember") { 
      # Test if user is in the member list
      if($member -eq $User.DistinguishedName){
        return $true
      }
    }

    # If we've reached the end, exit the loop
    if($ReturnedMember -eq $RangedPropertyName){
      $HasMoreMembers = $true
    }

  } while ($HasMoreMembers)

  # User wasn't found
  return $false
}

ユーザー エクスペリエンスに一貫性を持たせるために、PowerShell のコマンド名には承認された動詞Test-*を使用してください (例:の代わりにCheck-*)

[adsisearcher]DirectorySearcherクラスの型アクセラレータです

于 2015-10-30T21:54:14.243 に答える