我试图将所有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条件运行每个用户?我还需要学习另一个更高级的概念吗?
答案 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