Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Generate PowerShell Tree View HTML diagram of Active Directory group recursive memberships

Long back I wrote article on Powershell Active Directory: Show treeview of User or Group memberof hierarchy, where it was showing group Tree View on the PowerShell command console. In the hierarchy it was only showing Tree View of groups only. I improvised this script and included users as well. As adding users and multiple groups on the screen console was possible but not much practical to view it on the screen. So I generated diagram in HTML with the using of https://mermaid.js.org/.

Microsoft ActiveDirectory active directory ad domain controller users and group tree view diagram plantuml mermaid.js html css javascript gui wpf windows forms automation visualization.png

To use this onnce you launch PowerShell Script, it pops up GUI box and asks for Group name. Once you provide group name in the text box. It will take to input and create a Tree View diagram chart for you. Open Diagram.html in your favorite browser.

Microsoft ActiveDirectory active directory ad domain controller users and group tree view diagram html mermaid.js html css.png

Download Show-ADGroupTreeViewDiagramGUI.zip.zip here or it is also available on github.com

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form
$form.Text = 'AD Group Info Form'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Please enter the AD Group in the space below:'
$form.Controls.Add($label)

$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$textBox.Text = "Administrators"
$form.Controls.Add($textBox)

$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(150,120)
$cancelButton.Size = New-Object System.Drawing.Size(75,23)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)

$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(75,120)
$okButton.Size = New-Object System.Drawing.Size(75,23)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)

$form.Topmost = $true

$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
    $GroupName = $textBox.Text
}
else 
{
    $GroupName = 'Administrators'
}
function Show-ADGroupTreeViewDiagram {
    #requires -version 5
    <#
    .SYNOPSIS
        Show DownStream tree view hierarchy of members groups recursively of a Active Directory Group in GUI HTML.
    .DESCRIPTION
        The Show-ADGroupTreeViewDiagram list all nested group list of a AD user and created diagram from it and show on GUI HTML page. It requires only valid parameter AD username, 
    .PARAMETER GroupName
        Prompts you valid active directory Group name. You can use first character as an alias, If information is not provided it provides 'Domain Admins' group information.
    .INPUTS
        Microsoft.ActiveDirectory.Management.ADGroup
    .OUTPUTS
        Microsoft.ActiveDirectory.Management.ADGroup
        Microsoft.ActiveDirectory.Management.ADuser
    .NOTES
        Version:        3.0
        Author:         Janvi
        Creation Date:  01 May 2024
        Purpose/Change: Get the nested downstream group info of member and view in HTML
        Useful URLs: http://vcloud-lab.com
    .EXAMPLE
        PS C:\>.\Show-ADGroupTreeViewDiagram -GroupName 'Administrators'
    
        This list all the upstream memberof group of a Group.
    #>
    
    [CmdletBinding(SupportsShouldProcess=$True,
        ConfirmImpact='Medium',
        HelpURI='http://vcloud-lab.com')]
    Param
    (
        [parameter(Position=0, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, HelpMessage='Type valid AD Group')]
        [alias('Group')]
        [String]$GroupName = 'Domain Admins',
        [parameter(DontShow=$True)]
        [alias('U')]
        $UpperValue = [System.Int32]::MaxValue,
        [parameter(DontShow=$True)]
        [alias('L')]
        $LowerValue = 2
    )
    begin {
        if (!(Get-Module Activedirectory)) {
            try {
                Import-Module ActiveDirectory -ErrorAction Stop 
            }
            catch {
                Write-Host -Object "ActiveDirectory Module didn't find, Please install it and try again" -BackgroundColor DarkRed
                Break
            }
        }
        try {
            $Group =  Get-ADGroup $GroupName -Properties members -ErrorAction Stop 
            $Members = $Group | Select-Object -ExpandProperty members 
            $rootname = $Group.Name
            $memberOfGroups = Get-ADGroupMember $Group.Name
            foreach ($memberOf in $memberOfGroups.Name) 
            {
                $groupInfo = "{0}({1}) --> {2}({3});" -f $($rootname -replace '\s',''), $rootname, $($memberOf -replace '\s',''), $memberOf
                $groupInfo | Out-File -FilePath $PSScriptRoot\Extras\rawdiagram.mmd -Append
            }
        }
        catch {
            Write-Host -Object "`'$GroupName`' groupname doesn't exist in Active Directory, Please try again." -BackgroundColor DarkRed
            $result = 'Break'
            Break
        }
    }
    Process {
        $Minus = $LowerValue - 2
        $Spaces = " " * $Minus
        $Lines = "__"
        "{0}{1}{2}{3}" -f $Spaces, '|', $Lines, $rootname        
        $LowerValue++
        $LowerValue++
        if ($LowerValue -le $UpperValue) {
            foreach ($member in $Members) {
                try {
                    $UpperGroup = Get-ADGroup $member -Properties Members, Memberof -ErrorAction Stop
                }
                catch {
                    Continue
                }
                #$LowerGroup = $UpperGroup |
                $LowerGroup = $UpperGroup | Get-ADGroupMember
                $LoopCheck = $UpperGroup.memberof | ForEach-Object {$_ -contains $lowerGroup.distinguishedName}
                if ($LoopCheck -Contains $True) {
                    $rootname = $UpperGroup.Name
                    Write-Host "Loop found on $($UpperGroup.Name), Skipping..." -BackgroundColor DarkRed
                    Continue
                }
                #"xxx $($LowerGroup.name)"
                #$Member
                #"--- $($UpperGroup.Name) `n"
                Show-ADGroupTreeViewDiagram -GroupName $member -LowerValue $LowerValue -UpperValue $UpperValue
            } #foreach ($member in $MemberOf) {
        }
    } #Process
}
Clear-Content -Path $PSScriptRoot\Extras\diagram.mmd -Force
Clear-Content -Path $PSScriptRoot\Extras\rawdiagram.mmd -Force
'flowchart TD;' | Out-File -FilePath $PSScriptRoot\Extras\diagram.mmd
Show-ADGroupTreeViewDiagram -GroupName $GroupName
$rawDiagram = Get-Content $PSScriptRoot\Extras\rawdiagram.mmd #-Raw
$null = $rawDiagram[1] -match '^(.*?)\('
$rawDiagram[0] = "{0} style {1} fill:#CC5500,color:white;" -f $rawDiagram[0], $Matches[1]
Add-Content -Path $PSScriptRoot\Extras\diagram.mmd -Value ($rawDiagram | Sort-Object | Get-Unique)
$diagram = Get-Content -Path $PSScriptRoot\Extras\diagram.mmd #-Raw
Write-Host "`nLoading Diagram $($diagram.noinfo)"
Import-Module "$PSScriptRoot\Extras\EPS\1.0.0\EPS.psm1" -Force | Out-Null
$html = Invoke-EpsTemplate -Path "$PSScriptRoot\Extras\Diagram.eps"
$html | Out-File -FilePath "$PSScriptRoot\Diagram.html"
#Invoke-Expression $PSScriptRoot\Diagram.html
Write-Host "Open $PSScriptRoot\Diagram.html in your favorite browser!" -ForegroundColor White -BackgroundColor DarkCyan

Useful Articles
Powershell Active Directory: Show treeview of User or Group memberof hierarchy
Different ways to bypass Powershell execution policy :.ps1 cannot be loaded because running scripts is disabled
POWERSHELL: INSTALLING AND CONFIGURING ACTIVE DIRECTORY
Powershell Active Directory: List complete hierarchy of upstream nested groups recursively of User
Powershell Active Directory 1: Check, enable and disable child OU protect object from accidental deletion
Oneliner Powershell how to add or remove AD user members and objects in groups
Microsoft Active directory additional features - AD Recycle Bin Powershell
Powershell: Temporary group membership on Windows 2016 Active Directory PAM (Privileged Access Management Feature)
Adding user to administrators from another cross domain - Part 1
PowerShell: Copy group membership from one user to another user in Active Directory
PowerShell GUI: Copy group membership from one user to another user in Active Directory
PowerShell Active Directory: Sync group membership from one user to another user and move to OU

 

Go Back

Comment

Blog Search

Page Views

12085112

Follow me on Blogarama