powershell - 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
解决方案
我不知道您有多少用户,但是每次您在数组上 += 时,整个数组加上新元素都会被复制到一个全新的数组中。这是一种不好的做法,并且随着添加数组的每个项目呈指数级恶化。您可以通过将数组构建为循环结果或使用具有高效 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
推荐阅读
- c# - 如何在 ASP.NET Web API C# 中返回 JSON 数组
- gnuplot - 如何使用 GnuPlot 绘制立方体/矩形?
- python - Cygwin:无法从本地目录安装 paramiko
- amazon-web-services - 我的基于 Cognito 的应用程序如何确定登录用户应该可以使用哪个 UI?
- ignite - 找不到 JDBC 的类“IgniteJdbcThinDataSource”
- sqlalchemy - sqlalchemy load_only 列并使用标签重命名列名
- apache - Apache 代理背后的 Traefik
- c# - IISExpress 对数据库连接的限制
- android - Firebase 推送通知无需单击即可打开活动
- c++ - 为什么 return 语句和 print 语句返回不同的答案?