首页 > 解决方案 > Powershell 获取活动用户 OU、用户名和组成员身份

问题描述

我正在尝试获取一个 powershell 脚本来导出 OU 和子 OU 中的所有用户,我可以做得很好,但是当我尝试获取用户的 OU 时,我没有得到任何 OU。我在网上到处查看,发现一些脚本只提取用户的 OU,但它们有点慢,我似乎无法让他们拉出组,或者是从一个组中拉出而不是列出所有用户及其团体。我正在尝试导出此列表并按 OU 排序,以便我可以确保每个学生都在正确的组中。我们有一些学生在额外的小组中,我想快速轻松地找到这些学生。

#Student
$Report = @()
#Collect all users
$Users = Get-ADUser -Filter * -SearchBase 'OU=Student,DC=domain,DC=com' -Properties distinguishedname, Name, GivenName, SurName, SamAccountName, UserPrincipalName, MemberOf, Enabled -ResultSetSize $Null
# Use ForEach loop, as we need group membership for every account that is collected.
# MemberOf property of User object has the list of groups and is available in DN format.
Foreach($User in $users){
$UserGroupCollection = $User.MemberOf
#This Array will hold Group Names to which the user belongs.
$UserGroupMembership = @()
#To get the Group Names from DN format we will again use Foreach loop to query every DN and retrieve the Name property of Group.
Foreach($UserGroup in $UserGroupCollection){
$GroupDetails = Get-ADGroup -Identity $UserGroup
#Here we will add each group Name to UserGroupMembership array
$UserGroupMembership += $GroupDetails.Name
}
#As the UserGroupMembership is array we need to join element with ',' as the seperator
$Groups = $UserGroupMembership -join ','
#Creating custom objects
$Out = New-Object PSObject
$Out | Add-Member -MemberType noteproperty -Name DistinguishedName -Value @{Name="DistinguishedName";Expression={$_.distinguishedname | ForEach-Object {$_ -replace '^.+?(?<!\\),',''}}}
$Out | Add-Member -MemberType noteproperty -Name Name -Value $User.Name
$Out | Add-Member -MemberType noteproperty -Name UserName -Value $User.SamAccountName
$Out | Add-Member -MemberType noteproperty -Name Status -Value $User.Enabled
$Out | Add-Member -MemberType noteproperty -Name Groups -Value $Groups
$Report += $Out
}
#Output to screen as well as csv file.
$Report | Sort-Object DistinguishedName | FT -AutoSize
$Report | Sort-Object DistinguishedName | Export-Csv -Path $env:temp\students.csv -NoTypeInformation

标签: powershell

解决方案


我不知道您有多少用户,但是每次您在数组上 += 时,整个数组加上新元素都会被复制到一个全新的数组中。这是一种不好的做法,并且随着添加数组的每个项目呈指数级恶化。您可以通过将数组构建为循环结果或使用具有高效 add() 方法的dotnet列表对象来避免这种情况。

您还重复查找相同的组名。我不知道这些数字,但将所有组放在哈希表中一次然后查找它们可能会好得多。

您的问题尚不清楚,但是如果您想要用户及其组的列表,那么您将走很长一段路。您提到了 ou 但 AFAICS 代码中没有使用组织单位。您想要 AD ou 属性还是 DN 的一部分?你似乎也没有使用。请注意,DN 是一个字符串,按 DN 排序只会给出一个无用的 alpha 字符串排序。您的学生是否在 OU=students 下的不同组织单位中?这还不清楚。如果是这样,请使用 AD canonicalName 对列表进行排序。

无需在 -property 中包含默认属性。溅射很好看。

你应该通过指出你的广告结构是什么样的以及你认为你的输出应该是什么样的来改进你的问题。

此外,格式化您的代码以提高可读性。

你想要一些类似的东西:

# group hashtable, for efficient name lookup
$groupName = @{}
$ignoredGroups = @( 'AllStudents','AllUsers', 'etc' ) # don't clutter list with these groups 
Get-AdGroup -filter '*' |                         # any restrictions? searchbase, etc 
  ForEach-Object {
    if ( $ignoredGroups -notcontains $_.Name ) {
      $groupName[ $_.distinguishedName ] = $_.Name
    }  
  }

# ADsplat, for readability 
$AD_Splat = @{
  Filter        = '*'
  SearchBase    = 'OU=Student,DC=domain,DC=com'  
  Properties    = 'MemberOf,CanonicalName,sn,givenName'.split(',')   # split to array 
  ResultSetSize = $Null                    # !? also, there are system limits to size
}
 
$results = Get-ADUser @ad_splat |
   ForEach-Object {
     $DN     = $_.distinguishedName  # do you need this at all?
     $CName  = $_.canonicalName  # for sorting by AD org unit
     $XName  = $_.sn + ', ' + $_.givenName  
     if ( $_.Enabled ) { $Enabled = 'Y'} else { $Enabled = '.' }
     $groups = (
        $_.memberOf | 
        ForEach-Object { $GroupName[ $_ ] } | # lookup name 
        where-Object { $_ } |                 # ignore nulls (when group not in hashtable)
        sort-object                           # consistent ordering between users
      ) -join ';'                             # don't use comma, csv conflict

      # leave custom object in pipe! This builds the array efficiently.
    New-Object PSObject -Property @{
    DistinguishedName = $dn
    Name              = $_.name
    XName             = $XName
    Login             = $_.SamAccountName
    CName             = $CName
    Groups            = $Groups
    }
} | Sort-Object CName   # sort the objects by canonical name

$results | format-table
$results | Export-Csv -Path 'c:\temp\usersgroups.csv' -NoTypeInformation

推荐阅读