I am developing a powershell script that does few checks like:
Check if the group has an certain attribute empty, check if group has certain names.
What I want to achieve now is to get all groups that are nested on the group that I am checking and run the same checks as I described above but on the memberof.
I know how to get the memberof and list it, but I want to get the group and edit an attribute.
What you’re trying to do is called a recursive function. Look at this function from the AZSBTools PS module:
function Get-SBADGroupMembers {
<#
.SYNOPSIS
Function to get members of AD group including sub-groups
.DESCRIPTION
Function to get members of AD group including sub-groups using LDAP
Does not need ActiveDirectory PowerShell module
Must be run from a domain-joined computer
.PARAMETER GroupName
Name of the AD group - required
.PARAMETER Parent
Name of the parent AD group - optional - used to enable the recursive use to search sub-groups
.PARAMETER Recurse
Switch that is set to True by default. It causes this function to search sub-groups
.EXAMPLE
Get-SBADGroupMembers testgroup1
.OUTPUTS
Returns a PowerShell object containing the following properties/example:
UserName DN OU MemberOf
-------- -- -- --------
testuser1 CN=testuser1,DC=TW24,DC=local TW24 testgroup1
testuser2 CN=testuser2,DC=TW24,DC=local TW24 testgroup2.testgroup1
Returns nothing if the group name is not found
.LINK
https://superwidgets.wordpress.com/category/powershell/
.NOTES
Function by Sam Boutros
v0.1 - 15 June 2019
v0.2 - 25 September 2019 - Fixed bug with Group members, added 'mail' property to group members
#>
[CmdletBinding(ConfirmImpact='Low')]
Param(
[Parameter(Mandatory=$true)][String]$GroupName,
[Parameter(Mandatory=$false)][String]$Parent,
[Parameter(Mandatory=$false)][Switch]$Recurse = $true
)
Begin { }
Process{
$myOutput = if ((Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain) {
$adsi = [adsisearcher]"objectcategory=group"
$adsi.filter = "(&(objectCategory=group)(cn=$GroupName))"
if ($ADGroup = ($adsi.FindAll()).Properties) {
if ($Parent) {
Write-Log 'Processing child group',$ADGroup.distinguishedname,"(Parent: $Parent)" Green,Cyan,DarkYellow
} else {
Write-Log 'Processing group ',$ADGroup.distinguishedname Green,Cyan
}
$GroupObj = [PSCustomObject][ordered]@{
GroupName = [string]$ADGroup.name
MemberNames = $( if ($ADGroup.member) { $ADGroup.member | foreach { $_.Split(',')[0].Split('=')[1] } } )
}
foreach ($Member in $GroupObj.MemberNames) {
$adsi = [adsisearcher]''
$adsi.filter = "cn=$Member"
$MemberObj = ($adsi.FindAll()).Properties
if ($MemberObj.objectclass -match 'group') {
if ($Recurse) { Get-SBADGroupMembers $MemberObj.name -Parent $GroupObj.GroupName }
} else {
[PSCustomObject][ordered]@{
UserName = [string]$MemberObj.name
Mail = [string]$MemberObj.mail
DN = [string]$MemberObj.distinguishedname
OU = [string](($MemberObj.distinguishedname) -replace '^CN=[\w\d-_]+,\w\w=','' -replace ',OU=','/' -replace ',DC=.*')
MemberOf = $(
if ($Parent) { "$($GroupObj.GroupName).$Parent" } else { $GroupObj.GroupName }
)
}
}
}
} else {
Write-Log 'Group',$GroupName,'not found' Green,Yellow,Cyan
}
} else {
Write-Log 'This function','Get-SBADGroupMembers','must be invoked from a domain-joined computer' Magenta, Yellow, Magenta
}
}
End { $myOutput }
}