基本上,在我们的环境中,我们有很多安全组。嵌套在其他组中的安全组等。因此,找到设置适用于用户的原因是真正的PITA,因为其中一个嵌套组可能是也可能不是
的一部分。例如如果将用户添加到组X,他们会突然在Citrix中发布已发布的应用程序。 Citrix已配置为安全组Y.尝试查找X和Y之间的链接非常耗时,但可以自动完成。
我想创建一个脚本,您输入用户和结束安全组(上面的组Y),脚本输出将用户连接到最终组的中间组。如果这是有道理的吗?
这样的事情:
function get-grouprelationship($username, $knownsecuritygroup)
{
$getallgroups = get-adgroupmember $knownsecuritygroup | where-object {$_.ObjectClass -eq "Group" | select-object SamAccountName | foreach-object {get-adgroupmember $_.SamAccountName}
}
(以上变量占用您的组,并循环遍历该组的所有成员,打印其成员)
$usergroups = (get-aduser -identity $username -Properties memberof | select-object memberof).memberof
(以上获取用户所在的所有群组)
$usergroups1 = $usergroups.split(",")
$usergroups2 = $usergroups1[0]
$usergroups3 = $usergroups2.substring(3)
(上面很好地格式化了文本)
if ($usergroups3 -contains $groupname){write-host "$username is directly in $groupname}
从这里开始,我非常困难,因为我基本上需要嵌套多个for循环,具体取决于每组中有多少组。然后做一个条件检查
if ($groupname -eq $currentgroup){write-host "connected by $groupname and $currentgroup}
我也坚持使用$getallgroups
变量,因为它只检查1级。然后它需要另外一个foreach
循环,其中需要另外一个等等。
由于没有先前的编码经验,我真的很难想到实现目标的简单方法。
编辑:
我在这里找到了这个脚本 - script。下面基本上有效,除了它是详细的方式:
import-module activedirectory
$username = read-host "What's their username?"
Function RecurseUsersInGroup {
Param ([string]$object = "", [int]$level = 0)
$indent = "-" * $level
$x = Get-ADObject -Identity $object -Properties SamAccountName
if ($x.ObjectClass -eq "group") {
Write-Host "# $($x.SamAccountName)"
$y = Get-ADGroup -Identity $object -Properties Members
$y.Members | %{
$o = Get-ADObject -Identity $_ -Properties SamAccountName
if ($o.ObjectClass -eq "user" -and $o.SamAccountName -eq $username) {
Write-Host "-> $($o.SamAccountName)"
} elseif ($o.ObjectClass -eq "group") {
RecurseUsersInGroup $o.DistinguishedName ($level + 1)
}
}
} else {
Write-Host "$($object) is not a group, it is a $($x.ObjectClass)"
}
}
$thegroup = read-host "What's the Group?"
RecurseUsersInGroup (get-adgroup $thegroup).DistinguishedName
工作正常,但似乎输出每个安全组,反对连接的安全组。当然,这是朝着正确方向迈出的一步!如果我找到了来源,我也会发布信用证。
答案 0 :(得分:1)
下面的版本并不简单(可能写得更简洁,但我希望脚本至少是半可读的),但它会搜索该组并返回Active Directory组对象对于找到该组的分支的每个组。
function Get-GroupConnection
{
[CmdletBinding()]
PARAM (
$Username,
$GroupName
)
$User = Get-AdUser -Identity $Username -Properties MemberOf
if (-Not ($User))
{
return;
}
$SearchedGroups = @()
function Find-GroupBranches
{
[CmdletBinding()]
PARAM (
$GroupNameList,
$SearchForGroupName
)
$ADGroups = $GroupNameList | Foreach { Get-ADGroup -Identity $_ -Properties MemberOf }
foreach($group in $ADGroups)
{
Write-Verbose "Testing if either '$($Group.SamAccountName)' or '$($Group.DistinguishedName)' are equal to '$SearchForGroupName'"
if ($Group.SamAccountName -eq $SearchForGroupName -OR $Group.DistinguishedName -eq $SearchForGroupName)
{
Write-Verbose "Found $($Group.DistinguishedName)"
Write-Output $Group
return
}
}
Write-Verbose "No match in current collection, checking children"
foreach ($currentGroup in $ADGroups)
{
if ($SearchedGroups -Contains $currentGroup.DistinguishedName)
{
Write-Verbose "Already checked children of '$($currentGroup.DistinguishedName)', ignoring it to avoid endless loops"
continue
}
$SearchedGroups += $currentGroup.DistinguishedName
if ($currentGroup.MemberOf)
{
Write-Verbose "Checking groups which $($currentGroup.DistinguishedName) is member of"
$foundGroupInTree = Find-GroupBranches -GroupNameList $currentGroup.MemberOf -SearchForGroupName $SearchForGroupName
if ($foundGroupInTree)
{
Write-Output $currentGroup
Write-Output $foundGroupInTree
break
}
}
else
{
Write-Verbose "$($currentGroup.DistinguishedName) is not member of any group, branch ignored"
}
}
}
Write-Verbose "Searching immediate group membership"
Find-GroupBranches -GroupNameList $User.MemberOf -SearchForGroupName $GroupName
}
Get-GroupConnection -Username MyUser -GroupName SubSubGroup -Verbose
关于如何搜索的说明。
给出以下Active Directory结构:
MyUser
Domain Admins
AnotherSubGroup
Other Group
DirectMemberGroup
Domain Admins (same group as MyUser is direct member of, above)
AnotherSubGroup (which is of course the same as above too)
SubGroup
SubSubGroup
Some Other Group
如果我们搜索MyUser和'SubSubGroup'之间的连接,脚本将首先搜索MyUser用户的直接成员资格,即'Domain Admins','Other Group','DirectMemberGroup'和'Some Other Group'。这些都不匹配我们搜索的'SubSubGroup',所以它开始检查'child'groups。
'Domain Admins'是'AnotherSubGroup'的成员,但是与'SubSubGroup'不匹配。 'AnotherSubGroup'不是任何组的成员,因此忽略该分支。
'其他组'不是任何组的成员,因此忽略该分支。
'DirectMemberGroup'是其他组的成员,因此它会遍历这些组。它已经为子项检查了“域管理员”,因此跳过该组以避免陷入循环搜索。因此,它检查'子组'。
'SubGroup'与'SubSubGroup'不匹配,因此它会检查'SubGroup'所属的组。 'SubGroup'是'SubSubGroup'的成员,因此它会检查该组。
'SubSubGroup'匹配'SubSubGroup',因此将被选为匹配。
在上面的示例中,输出组对象将是通向“SubSubGroup”组的分支,按以下顺序:
DirectMemberGroup
SubGroup
SubSubGroup
注意此方法将返回它在用户和组之间找到的第一个连接。例如,如果“其他组”组也是“SubSubGroup”的成员,则不会更改上面提到的输出和搜索过程。