如何使用PowerShell将Active Directory用户分类到互斥的组中?

时间:2019-05-15 12:08:32

标签: function powershell active-directory

我试图将所有Active Directory用户分类为八个组之一,但是我找不到一种有效且干净的方法来构建函数。在实践中,我已经有了一些行之有效的东西,所以我的问题只是为了自己的学业。这是我第一次在这里问问题,因此对信息太少或太多感到抱歉。

基本上,我必须执行一些Active Directory逻辑,以将环境中的每个用户分为八个组之一。
每个用户都应该属于八个组中的一个(并且只有一个)。
每个排序步骤只会将用户置于一个或另一个类别中。
一共有三个分支。
实际上,我试图使用户有权使用与其职责相匹配的VDI。现在,我假装将RPG犯罪分子分类到设备组之内。

逻辑是这样的:

  • 罪犯都是“七刀”组织或“破门”组织的成员。
  • 这些组织的成员都是盗贼或斗士。
  • 盗贼都是盗贼或刺客。
  • 战士都是野蛮人或冠军。
  • 根据组织,阶级和子阶级,每个罪犯将拥有不同的装备。

最终结果是,用户将按照其在树上的路径被放入适当的组中,例如CRIM_SK_ROG_THF,CRIM_BG_FTR_BRT等。我对此没有任何控制权,我只需要对它们进行分类即可。我也不是一个真正的程序员。我只是一个叫101和102级别的大学编程课程的callow系统管理员。

我遇到的问题是我似乎无法将我的功能简化为一项职责。 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

那么:如何在不违反最佳实践,单一责任或DRY的情况下将这些用户分为八个互斥的组?我是否应该放弃功能,而仅使用ForEach循环通过八个If条件运行每个用户?我还需要学习另一个更高级的概念吗?

1 个答案:

答案 0 :(得分:0)

不确定我为什么要写这篇文章,但是我们来了。另外,我没有进行测试,因为我没有您的广告结构或罪犯。

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