【问题标题】:Powershell command to compare AD user group memberships to a baseline用于将 AD 用户组成员身份与基线进行比较的 Powershell 命令
【发布时间】:2016-05-11 17:33:04
【问题描述】:

我正在尝试找出这样做的逻辑:

  • 查询特定 OU 中的所有 AD 组
  • 查询特定OU中的所有用户
  • 查询所有用户的组成员身份
  • 如果任何用户在初始组查询中属于一个或多个组,则输出该信息
  • 如果任何用户不属于初始组查询中的任何组,也输出该信息

我在这个网站上进行了挖掘,发现了一个大部分都可以使用的脚本,但我一直在思考如何将用户的组成员身份与我正在提取的原始组查询进行比较。看起来我可以使用 compare-object cmdlet,但参数似乎没有包含任何可以让我跟踪两个对象共有多少组的内容。

我在网上找到的代码如下:

$groups = Get-ADGroup -Filter * | where {$_.distinguishedname -like "*,OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv"}
$users = Get-ADUser -Filter * | where {$_.distinguishedname -like "*,OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv"}

foreach ( $User in $Users ) {
    $userGroups =  Get-ADPrincipalGroupMembership $User
    if ( $userGroups.Count -gt 1 ) {
        "{0} is a member of the following {1} groups:" -f $User.SamAccountName, $userGroups.Count
        foreach ( $group in $userGroups ) {
            "`t{0}" -f $group.Name 
        }
    } elseif ( $userGroups.Count -lt 1 ) {
        "{0} is a member of the following {1} groups:" -f $User.SamAccountName, $userGroups.Count
        foreach ( $group in $userGroups ) {
            "`t{0}" -f $group.Name 
        }
      }
}

问题在于我无法将用户组名称与第 1 行中的组查询名称进行比较。我也无法确定用户属于其中的 1 个或多个组列表。我不确定我是否可以使用相同的计数方法。

【问题讨论】:

  • 实际上,我认为我可以将初始组和用户查询都导出到 csv 中,并使用嵌套在 foreach 循环中的 if/else 语句遍历它们。会试一试并报告

标签: powershell active-directory


【解决方案1】:

您可以使用Compare-Object 验证帐户是否属于您的参考列表中的至少一个组:

foreach ( $User in $Users ) {
    $userGroups =  Get-ADPrincipalGroupMembership $User
    if (!(Compare-Object $userGroups $groups -IncludeEqual -ExcludeDifferent)) {
        "{0} doesn't belong to any reference group." -f $User.SamAccountName
    }
}

旁注:使用-SearchBase 参数,而不是通过可分辨名称上的通配符匹配过滤Get-ADUserGet-ADGroup 的结果:

$groups = Get-ADGroup -Filter * -SearchBase 'OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv' -SearchScope Subtree
$users  = Get-ADUser -Filter * -SearchBase 'OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv' -SearchScope Subtree

【讨论】:

  • 忽略我之前的评论。这似乎运作良好。我只是颠倒了检查并添加了 + $userGroups.name 来附加它找到的每个匹配项。认为这已解决。
  • 唯一奇怪的是它在列表中输出“域用户”组,即使该组在参考列表中不存在。没什么大不了的
  • 实际上这仅适用于检查两个位置是否存在同一个组。如果我希望它实际输出出现在两个地方的组的名称,它似乎不起作用。它只输出用户所属的所有组。
【解决方案2】:

我最终做了以下事情,它可以很好地满足我的需要。如果有人感兴趣,示例代码如下:

#gets a list of all groups in a given OU and stores the objects in the $groups variable
$groups = Get-ADGroup -Filter * -SearchBase 'OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv' -Properties name | select name

#pipe each group object into a foreach loop and output a string value of the same group name and stores it into the $groups_string variable
$groups_string = $groups | % {$_.name}

#gets a list of all users in a given OU and stores the objects in the $users variable
$users = Get-ADUser -Filter * -SearchBase 'OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv'


$results=@{
"Username" = ""
"Groupname" = ""
}

$table=@()

#iterates through every user in the $users variable and retrieves their group memberships
foreach ($user in $users) {
    #selects each group name and stores it in the $groupMembership variable
    $groupMembership = Get-ADPrincipalGroupMembership $user | select name

    #compares the names of each user's group to the baseline group name.
    $groupMembership | foreach ($_) {

        #If there is a match add the group name and the username to the $results hash table
        if ($groups_string -contains $_.name) {
            $results."Groupname" = $_.name
            $results."Username" = $user.Name

            #create a new PS object and supply the properties of the $results hash table to each object
            $objresults = New-Object psobject -Property $results

            #add each object to the $table array
            $table += $objresults
        }
    }  

}

#display/output the $table array and format it to fit 
$table | ft -AutoSize

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 2016-10-26
    相关资源
    最近更新 更多