【问题标题】:Comparing values in arrays from Get-ADUser比较来自 Get-ADUser 的数组中的值
【发布时间】:2017-04-19 00:46:47
【问题描述】:

我正在尝试编写一个脚本,如果用户不在特定 OU 中,则将其从安全组中删除。

我在比较来自 OU 的用户数组与来自安全组的用户数组时遇到问题。

为了测试,我遍历了 $testGroup$userList 中的内容。两者看起来都与我相似,但很明显它们不能比较,因为仅输出 $userList -contains $user 会给我一堆 false 结果,即使它应该是真的。

$userList = @()
$testGroup = @()

#Get current members of group. Using this instead of get-adgroupmember due to speed
$testGroup = Get-AdGroup "testGroup" -properties member | select-object -ExpandProperty member | get-aduser 

#Define OUs that we want to get members from
$OUlist = "OU1","OU2"

#Populate $userList with members of each OU
$OUlist | foreach {
    $userList += get-aduser -filter {Enabled -eq $True} -SearchBase "OU=$_,DC=dc,DC=dc2,DC=dc3"

}

#Check the group for anyone no longer in one of the approved OUs
$testGroup | foreach {

    if($userList -notcontains $user){
        #remove the user from $testGroup
    }

}

【问题讨论】:

  • 不确定你是否知道,但是当你使用 $x | foreach,您需要开始使用管道。所以在这种情况下,个人用户是 $_(当前项目)。我不确定这里的 $user 是什么,但您可能需要用 $_ 替换它。

标签: powershell


【解决方案1】:

考虑将Compare-Objectproperty 值设置为按可分辨名称进行比较;即

compare-object -ReferenceObject $OUList -DifferenceObject $userList -Property 'DistinguishedName' | 
    ?{$_.SideIndicator -eq '=>'} | 
    select -expand InputObject

完整代码:

(未经测试)

$userList = @()
$testGroup = @()

$groupName = 'testGroup'

#Get current members of group. Using this instead of get-adgroupmember due to speed
$testGroup = Get-AdGroup $groupName -properties member | select-object -ExpandProperty member | get-aduser 

#Define OUs that we want to get members from
$OUlist = "OU1","OU2"

#Populate $userList with members of each OU
$OUlist | foreach {
    $userList += get-aduser -filter {Enabled -eq $True} -SearchBase "OU=$_,DC=dc,DC=dc2,DC=dc3" | Get-AdUser

}

#Check the group for anyone no longer in one of the approved OUs & remove group group
Remove-ADGroupMember -Identity $groupName -Members (compare-object -ReferenceObject $OUList -DifferenceObject $userList -Property 'DistinguishedName' | ?{$_.SideIndicator -eq '=>'} | select -ExpandProperty InputObject)

【讨论】:

    【解决方案2】:

    有一些问题...在 $Variable | Foreach 中使用 $Variable 而不是 $_ 就像 MacroPower 提到的那样。

    你可以这样浓缩整个事情:

    # Get-ADGroupMember is easier than Get-ADGroup | Get-ADUser. 
    # You also only need the SamAccountName.
    # $TestGroup will be an array automatially... No need to $TestGroup = @()
    $TestGroup = (Get-ADGroupMember 'TestGroup').SamAccountName
    
    #Define OUs using their full paths.
    $OUList = @(
        'OU=Whatever,DC=example,DC=com',
        'OU=Something,DC=example,DC=com'
    )
    
    # Easily call the OU's from $OUList using $_.
    # Again, we only need SamAccountName
    # Again, $UserList will automaticall be an array no '= @()' needed.
    $OUList | ForEach-Object {
        $UserList += (Get-ADUser -Filter * -SearchBase $_).SamAccountName
    }
    
    
    # A proper foreach construct will let you work with $User instead of $_
    foreach ($User in $TestGroup) 
    {
        if ($User -notin $UserList)
        {
            # Put your action here.
        }
    }
    

    最后一点,您可以在驼峰式、PascalCase 和小写之间随意切换。虽然 PowerShell 一致性没有官方标准,但使代码更易于阅读。由于 .NET 样式指南,PascalCase 也倾向于被推荐。

    另外,如果您想使用比较而不是 foreach ($User in $TestGroup)

    $Compare = Compare-Object -ReferenceObject ($UserList | Select -Unique) -DifferenceObject $TestGroup
    
    $Compare | ForEach-Object {
        if ($_.sideindicator -eq '=>')
        {
            # Action here.
        }
    }
    

    【讨论】:

      【解决方案3】:

      这里是一个比较数组的例子:

       $a1=@(1,2,3,4,5)
       $b1=@(1,2,3,4,5,6)
      
       $result = Compare-Object -ReferenceObject ($a1) -DifferenceObject ($b1) -PassThru
       write-host $result
      

      也看看这个帖子compare arrays

      【讨论】:

        猜你喜欢
        • 2019-10-28
        • 1970-01-01
        • 1970-01-01
        • 2019-08-03
        • 1970-01-01
        • 1970-01-01
        • 2015-06-01
        • 2023-03-16
        • 1970-01-01
        相关资源
        最近更新 更多