Как я могу отсортировать пользователей Active Directory во взаимоисключающие группы, используя PowerShell? - PullRequest
0 голосов
/ 15 мая 2019

Я пытаюсь отсортировать всех пользователей Active Directory в одну из восьми групп, но не могу найти эффективный и чистый способ построения своих функций.На практике у меня уже есть кое-что, что работает, поэтому мой вопрос только для моего собственного образования.Я впервые задаю вопрос здесь, поэтому я прошу прощения, если информации слишком мало или слишком много.

По сути, мне нужно выполнить логику Active Directory, чтобы отсортировать каждого пользователя в моей среде в одну извосемь групп.
Каждый пользователь должен входить в одну (и только одну) из восьми групп.
Каждый шаг сортировки просто помещает пользователей в одну или другую категорию.
Есть три ветви.
Вна самом деле, я пытаюсь дать пользователям право на VDI, который соответствует их обязанностям.Сейчас я сделаю вид, что сортирую RPG-преступников по группам снаряжения или что-то в этом роде.

Логика примерно такая:

  • Все преступники являются членами СемиНожи или организации «Сломанные ворота».
  • Все члены этих организаций - либо разбойники, либо бойцы.
  • Все разбойники - воры или убийцы.
  • Все бойцы - либоСкоты или Чемпионы.
  • В зависимости от организации, класса и подкласса у каждого преступника будет разное снаряжение.

Конечный результат состоит в том, что пользователи будут помещены в соответствующую группу для ихпуть вниз по дереву - например, CRIM_SK_ROG_THF, CRIM_BG_FTR_BRT и т. д. Я не имею никакого контроля над этим, я просто должен разобраться с ними.Я также не настоящий программист;Я просто системный администратор, который проходил курсы программирования для колледжей на 101 и 102 уровнях.

Проблема, с которой я столкнулся, заключается в том, что я просто не могу упростить свои функции до одной ответственности.PowerShell позволяет мне записывать более одного вывода, поэтому первым делом я должен был иметь только одну функцию, которая возвращает два списка.Это работает хорошо, но это кажется глупым и смутно разочаровывающим.

Function filter_organization ($criminals) {
    $seven_knives    =    New-Object System.Collections.ArrayList;
    $broken_gate     =    New-Object System.Collections.ArrayList;
    forEach ($criminal in $criminals) {
        if ($criminal.MemberOf -contains "CN=Seven Knives,OU=Classes,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm") {
            [void]$seven_knives.Add($criminal);
        }
        else {
            [void]$broken_gate.Add($criminal);
        }
    }
    Write-Output $seven_knives,$broken_gate;
}
$seven_knives, $broken_gate    =    filter_organization $all_criminals;

Я рассмотрел использование глобальных переменных, но я недостаточно осведомлен, чтобы решить, где табу против них применяется или не применяется.

Function filter_class ($seven_knives) {
    forEach ($criminal in $seven_knives) {
        if ($criminal.MemberOf -contains "CN=Fighters,OU=Classes,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm") {
            $global:seven_knives_fighters.Add($criminal);
        }
        else {
            $global:seven_knives_rogues.Add($criminal);
        }
    }
}

Я также рассматривал ссылочные переменные в качестве параметров, но это похоже на глобальные переменные и увеличивает параметры до трех:

$seven_knives_rogues_thieves      =    New-Object System.Collections.ArrayList;
$seven_knives_rogues_assassins    =    New-Object System.Collections.ArrayList;

Function filter_subclass ($rogues, [ref]$thieves, [ref]$assassins) {
    forEach ($rogue in $rogues) {
        if ($rogue.MemberOf -contains "CN=Thieves,OU=Organizations,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm") {
            $thieves.Value.Add($rogue);
        }
        else {
            $assassins.Value.Add($rogue);
        }
    }
}
filter_subclass $seven_knives_rogues ([ref]$seven_knives_rogues_thieves) ([ref]$seven_knives_rogues_assassins);

Но я не особоЯ хочу обработать весь список дважды для каждого разделения:

$criminals                =    Get-ADUser -Properties * -Filter *;
$seven_knives             =    filter_seven_knives $criminals;
$broken_gate              =    filter_broken_gate $criminals;
$seven_knives_fighters    =    filter_fighters $seven_knives;
$seven_knives_rogues      =    filter_rogues $seven_knives

Итак: как я могу разделить этих пользователей на восемь взаимоисключающих групп, не нарушая лучшие практики, единую ответственность или СУХОЙ?Должен ли я отказаться от функций и просто использовать цикл ForEach для запуска каждого пользователя через восемь условий If?Есть ли другая, более продвинутая концепция, которую мне нужно изучить?

1 Ответ

0 голосов
/ 15 мая 2019

Не уверен, почему я написал это, но мы здесь.Кроме того, я не проверял это, потому что у меня нет вашей структуры рекламы или ваших преступников.

function Add-UserToGroup {
    [CmdletBinding(SupportsShouldProcess = $true)]
    Param (
        [Parameter(ValueFromPipeline = $true)]
        [Microsoft.ActiveDirectory.Management.ADUser]
        $Identity
    )
    try {
        # Use this to create the group name
        $StringList = New-Object -TypeName System.Collections.Generic.List[System.String]
        $StringList.Add('CRIM')

        # Get the membership if it doesn't exist
        if ($null -eq $Identity.MemberOf) {
            Get-ADUser -Identity $Identity -Properties MemberOf
        }

        # Process SevenKnives/BrokenGate
        $SevenKnives = $Identity.MemberOf -contains "CN=Seven Knives,OU=Classes,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
        $BrokenGate = $Identity.MemberOf -contains "CN=Broken Gate,OU=Classes,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
        if ($SevenKnives -and $BrokenGate) {
            throw "Criminal '$Identity' is a member of both Seven Knives and Broken Gate"
        }
        elseif ($SevenKnives) {
            $StringList.Add('SK')
        }
        elseif ($BrokenGate) {
            $StringList.Add('BG')
        }

        # Process Rogues/Fighters
        $Rogues = $Identity.MemberOf -contains "CN=Rogues,OU=Classes,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
        $Fighters = $Identity.MemberOf -contains "CN=Fighters,OU=Classes,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
        if ($Rogues -and $Fighters) {
            throw "Criminal '$Identity' is both a rogue and a fighter"
        }
        elseif ($Rogues) {
            $StringList.Add('ROG')

            # Process Theives/Assassins
            $Thieves = $Identity.MemberOf -contains "CN=Thieves,OU=Organizations,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
            $Assassins = $Identity.MemberOf -contains "CN=Assassins,OU=Organizations,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
            if ($Thieves -and $Assassins) {
                throw "Criminial '$Identity' is both a Thieve and an Assassian"
            }
            elseif ($Thieves) {
                $StringList.Add('THF')
            }
            elseif ($Assassins) {
                $StringList.Add('Ass')
            }
        }
        elseif ($Fighters) {
            $StringList.Add('FTR')

            # Process Brutes/Champions
            $Brutes = $Identity.MemberOf -contains "CN=Brutes,OU=Organizations,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
            $Champions = $Identity.MemberOf -contains "CN=Champions,OU=Organizations,OU=Groups,OU=Accounts,DC=Quodeth,DC=Thule,DC=dm"
            if ($Brutes -and $Champions) {
                throw "Criminial '$Identity' is both a Brute and an Champion"
            }
            elseif ($Brutes) {
                $StringList.Add('BRT')
            }
            elseif ($Champions) {
                $StringList.Add('CHP')
            }
        }

        $GroupName = $StringList -join '_'

        if ($PSCmdlet.ShouldProcess($Identity,"Adding to group $GroupName")) {
            Add-ADGroupMember -Identity $GroupName -Members $Identity
        }
    }
    catch {
        $PSCmdlet.ThrowTerminatingError($_)
    }
}

Get-ADUser -Filter * -Properties MemberOf | Add-UserToGroup -WhatIf
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...