Назад | Перейти на главную страницу

PowerShell и управление пользователями Active Directory

Проблема: Возьмите список имен пользователей из файла CSV и рекурсивно удалите их из всех групп пользователей, членами которых они являются. Я хотел бы ограничить, из каких групп они удаляются, на основе префикса имени группы.

Пример: Если бы user_bob (одно из многих имен пользователей в CSV) был членом следующих групп (определяемых рекурсивно): abc-users, abc-printers, abc-users-limited, xzy-users, xyz-secure, то я бы хотелось бы, чтобы сценарий PowerShell удалил его из всех групп с префиксом «abc-», а затем перешел к следующему имени пользователя в CSV и выполнил тот же процесс.

Ноты: Я искал в Интернете примеры чего-то подобного и, похоже, не нашел никаких потенциальных клиентов. Фрагменты кода или образцы, с которых я могу начать процесс тестирования или объединения в решение, были бы очень признательны. Я просматривал Документация TechNet для командлетов и не добились большого прогресса. Заранее спасибо!

Предполагая, что вы хотите удалить КАЖДОГО пользователя из всех групп с определенным префиксом, не основываясь на каких-либо других критериях (например, удалить пользователей abc из групп xyz и пользователей xyz из групп abc). Тогда вы могли бы сделать это вот так. Но сначала пара моментов:

  1. В каком формате имена пользователей в вашем CSV-файле? Это определит, как вы будете искать пользователя, вам нужно будет соответствующим образом обновить параметр (например, изменить $user.Identity к $user.SAMAccountName)
  2. Для этого требуются командлеты AD Powershell, поэтому вам нужно либо сначала импортировать модуль AD (или запустить его в консоли AD Powershell на контроллере домена или компьютере с установленными инструментами администрирования).
  3. Следующее будет работать только для прямого членства в группе, но не для рекурсивного членства в группе.

$prefix = "CN=abc-*"

$ userlist = Импорт-CSV userlist.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. в эта почта чтобы посмотреть, поможет ли это.

Базовый алгоритм того, что вы ищете, выглядит примерно так (по крайней мере, по моему мнению):

  1. Пронумеруйте всю группу правильным префиксом.
  2. Рекурсивно следуйте за их участниками GroupMembers, чтобы перечислить в них все вложенные группы.
    1. Как только вы получите группу без групп в качестве участников, прекратите повторение.
  3. Возьмите список пользователей для каждого пользователя
    1. Перечислить их членство в группах
    2. Если у них есть правильный префикс, удалите их.
    3. Если какая-либо из оставшихся групп находится в списке групп, перечисленных на предыдущем основном шаге, удалите их также из этого списка.

Теперь о реальных кодах.

Перечисление всех групп с префиксом (не проверено, будут ошибки):

$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)
}

Затем удалите соответствующие группы по мере необходимости.