问题: 从 CSV 文件中获取用户名列表,并递归地从他们所属的所有用户组中删除他们。我想根据组名的前缀来限制从哪些组中删除他们。
例子: 如果 user_bob(CSV 中的众多用户名之一)是以下组的成员(递归确定):abc-users、abc-printers、abc-users-limited、xzy-users、xyz-secure,那么我希望 PowerShell 脚本将他从所有以“abc-”为前缀的组中删除,然后转到 CSV 中的下一个用户名并执行相同的过程。
笔记: 我一直在网上搜索类似的例子,但似乎找不到任何线索。如果能提供一些代码片段或示例,让我可以开始测试或将其整合成解决方案,我将不胜感激。我一直在寻找TechNet 文档对于命令行程序,还没有取得很大进展。提前致谢!
答案1
您正在寻找的基本算法看起来像这样(无论如何,根据我的说法):
- 枚举具有正确前缀的所有内容。
- 递归地跟踪它们的 GroupMembers 来枚举其中的任何嵌套组。
- 一旦获得一个没有组作为成员的组,请停止递归。
- 获取用户列表,针对每个用户
- 枚举其团体成员
- 如果有正确的前缀,则将其从中删除。
- 如果任何剩余组在上一个主要步骤中枚举的组列表中,也将其从该列表中删除。
现在来谈谈实际的代码类似的事情。
枚举所有带前缀的组(未经测试,会有错误):
$RecurseList=dsquery group -name "abc-*"
$TargetList=$RecurseList
foreach $Grp in $RecurseList {
# Now get the members of that group, do not expand
$GrpMembers=dsget group "$Grp" -members
foreach ($Member in $GrpMembers) {
$isGroup=dsget group $Member
if ($isGroup.dn -eq $Member) {
$TargetList.add("$Member")
RecurseIntoGroup($isGroup.dn)
}
}
}
然后,当需要讨论 CSV 列表时,获取用户的成员资格,并检查该组是否存在于上面的 $TargetList 中。如果是,则将其删除。
从数千个组中删除一个用户需要做大量的工作,但如果您要进行大量这样的操作,那么拥有预先构建的列表将节省您的时间。
如果您只需要为少数用户(比如 10 个左右)执行此操作,则可以沿树返回。
$UserGroups = dsquery user -name $Username -memberof
foreach ($uGroup in $UserGroups) {
if (isConcerning($uGroup)) {
$ConcerningGroups.add("$uGroup")
}
}
function isConcerning {
param ($uGroup)
$parentGroups=dsget group $uGroup -memberOf
$found=$False
foreach ($pg in $parentGroup) {
if ($parentGroup.startswith("abc-")) {
return($true)
$found=$true
} else {
$concerning=isConcerning($pg)
if ($concerning) {
return($true)
$found=$true
}
}
}
if (-not $found) {
return($False)
}
然后根据需要删除相关组。
答案2
假设您想要做的是从所有具有特定前缀的组中删除每个用户,而不基于任何其他标准(例如从组 xyz 中删除用户 abc,从组 abc 中删除用户 xyz)。那么您可以这样做。不过首先要说明几点:
- 您的 CSV 文件中的用户名是什么格式?这将决定您如何搜索用户,您需要相应地更新参数(例如更改
$user.Identity
为$user.SAMAccountName
) - 这需要 AD Powershell cmdlet,因此您要么需要先导入 AD 模块(或者在安装了管理工具的 DC 或计算机上的 AD Powershell 控制台中运行它)
- 以下内容仅适用于直接组成员资格,不适用于递归组成员资格。
$前缀 = “CN = abc- *”$userlist = 导入-CSV 用户列表.csv
foreach ($user 在 $userlist 中) { $currentuser = Get-ADUser $user.Identity -properties memberof $grouplist = $currentuser.memberof
foreach ($group in $grouplist) { if ($group -like $prefix) { Get-ADGroup $group | Remove-ADGroupMember -members $currentuser -Confirm:$false } } }
如果您需要递归搜索,则需要尝试其他方法。您可以看看第 11 项。这个帖子看看是否有帮助。