Skip to content

Commit

Permalink
Merge pull request #3 from kyschuler/bugfixes
Browse files Browse the repository at this point in the history
Bugfixes
  • Loading branch information
kyschuler authored Sep 3, 2024
2 parents 26c2708 + a64654d commit a2f232c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 42 deletions.
92 changes: 50 additions & 42 deletions Export-ActiveDirectoryVisioMap.ps1
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
#############################################################################
# Author : Tyler Cox
# Editor : Kyle Schuler
#
# Version : 1.0
# Version : 1.1
# Created : 11/2/2021
# Modified :
# Modified : 09/03/2024
#
# Purpose : This script will build an inventory of all GPOs and their links.
#
# Requirements: A computer with Active Directory Admin Center (ADAC) installed and a
# user account with enough privileges
#
# Change Log: Ver 1.0 - Initial release
# Ver 1.1 - Fixed Visio Cmdlet Parameters,
# - Adjusted for Azure AD joined devices
# - Fixed issue with importing Visio module
# - Reduced output to console
#
#############################################################################

Expand All @@ -36,7 +41,7 @@ Catch
}
Try
{
Import-Module Visio -scope CurrentUser -ErrorAction Stop
Import-Module Visio -ErrorAction Stop
}
Catch
{
Expand All @@ -51,19 +56,22 @@ New-VisioApplication
$VisioDoc = New-VisioDocument
#Create the Visio Page
$Page = $VisioDoc.Pages[1]
#Create the Visio Point at 1,1
$Point_1_1 = New-VisioPoint -X 1.0 -Y 1.0

#Set our counters
$nodeCount = 0
$conCount = 0
$gpoCount = 0

#Get our root domain from the current logged on user
$DNSDomain = $env:USERDNSDOMAIN

#Get all OUs except LostAndFound
$OUs = Get-ADOrganizationalUnit -Filter 'Name -like "*"' -Properties Name, DistinguishedName, CanonicalName, LinkedGroupPolicyObjects | `
Where {$_.canonicalname -notlike "*LostandFound*"} | Select-Object Name, Canonicalname, DistinguishedName, LinkedGroupPolicyObjects | `
$OUs = Get-ADOrganizationalUnit -Server $DNSDomain -Filter 'Name -like "*"' -Properties Name, DistinguishedName, CanonicalName, LinkedGroupPolicyObjects | `
Where-Object {$_.canonicalname -notlike "*LostandFound*"} | Select-Object Name, Canonicalname, DistinguishedName, LinkedGroupPolicyObjects | `
Sort-Object CanonicalName # | Select -First 50

#Get our root domain from the current logged on user
$DNSDomain = $env:USERDNSDOMAIN

#Gather our shapes from Visio's stencils
$ADO_u = Open-VisioDocument "ADO_U.vss"
Expand All @@ -74,13 +82,13 @@ $masterDomain = Get-VisioMaster "Domain" -Document $ADO_u
$masterGPO = Get-VisioMaster "Policy" -Document $ADO_u

#Create our first shape. This is the root domain node
$n0 = New-VisioShape -Masters $MasterDomain -Points 1.0,1.0
$n0 = New-VisioShape -Master $MasterDomain -Position $Point_1_1
#Set shape properties
$n0.Text = $DNSDomain
$n0.Name = "n" + $DNSDomain

#Get Root Domain linked GPOs and process them accordingly
$RootGPOs = Get-ADObject -Identity (Get-ADDomain).distinguishedName -Properties name, distinguishedName, gPLink, gPOptions
$RootGPOs = Get-ADObject -Server $DNSDomain -Identity (Get-ADDomain -Identity $DNSDomain).distinguishedName -Properties name, distinguishedName, gPLink, gPOptions
#Loop through each root GPO
ForEach ($gpolink in $RootGPOs.gPlink -split "\]\[")
{
Expand All @@ -90,24 +98,24 @@ ForEach ($gpolink in $RootGPOs.gPlink -split "\]\[")
#get only the GUID of the gpo
$gpoGUID = ([Regex]::Match($gpoLink,'{[a-zA-Z0-9]{8}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{12}}')).Value
#pull details for the GPO based on the GUID
$gpo = Get-GPO -GUID $gpoGUID
$gpo = Get-GPO -GUID $gpoGUID -Domain $DNSDomain

#declare what we'll call the gpo shape
$shapename = "g" + $gpoCount
#Create the GPO shape
$shapeGPO = New-VisioShape -Masters $MasterGPO -Points 1.0,1.0
$shapeGPO = New-VisioShape -Master $MasterGPO -Position $Point_1_1
#Set the shape properties
$ShapeGPO.Text = $GPO.DisplayName
$ShapeGPO.Name = $shapename
#Set the shape's custom properties
$GUID = "{" + $gpo.id.guid + "}"
If ($GPO.DisplayName) {Set-VisioCustomProperty -Shapes $ShapeGPO -Name "GPOName" -Value $GPO.DisplayName}
If ($GPO.Description) {Set-VisioCustomProperty -Shapes $ShapeGPO -Name "Description" -Value $GPO.Description}
If ($GPO.ID.Guid) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "GUID" -Value $GUID}
If ($GPO.GPOStatus) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "Status" -Value $GPO.GpoStatus.ToString()}
If ($GPO.CreationTime) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "CreationTime" -Value $GPO.CreationTime.ToString()}
If ($GPO.ModificationTime) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "ModifiedTime" -Value $GPO.ModificationTime.ToString()}
If ($GPO.WmiFilter) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "WMIFilterName" -Value $GPO.WMIFilter.Name}
If ($GPO.DisplayName) {Set-VisioCustomProperty -Shape $ShapeGPO -Name "GPOName" -Value $GPO.DisplayName}
If ($GPO.Description) {Set-VisioCustomProperty -Shape $ShapeGPO -Name "Description" -Value $GPO.Description}
If ($GPO.ID.Guid) {Set-VisioCustomProperty -Shape $shapeGPO -Name "GUID" -Value $GUID}
If ($GPO.GPOStatus) {Set-VisioCustomProperty -Shape $shapeGPO -Name "Status" -Value $GPO.GpoStatus.ToString()}
If ($GPO.CreationTime) {Set-VisioCustomProperty -Shape $shapeGPO -Name "CreationTime" -Value $GPO.CreationTime.ToString()}
If ($GPO.ModificationTime) {Set-VisioCustomProperty -Shape $shapeGPO -Name "ModifiedTime" -Value $GPO.ModificationTime.ToString()}
If ($GPO.WmiFilter) {Set-VisioCustomProperty -Shape $shapeGPO -Name "WMIFilterName" -Value $GPO.WMIFilter.Name}
#Create the shape's connections
$con = Connect-VisioShape -From $n0 -To $shapeGPO -Master $connector
#Set the connections custom properties
Expand All @@ -121,7 +129,7 @@ ForEach ($gpolink in $RootGPOs.gPlink -split "\]\[")
$con_cells.LineBeginArrow = "4"
$con_cells.CharColor = "rgb(0,175,240)"
#Set the shape properties
Set-VisioShapeCells -Cells $con_cells -Shapes $con
Set-VisioShapeCells -Cells $con_cells -Shape $con
}


Expand All @@ -146,18 +154,18 @@ ForEach ($ou in $OUs)
#declare what we'll call the shape
$shapename = "n" + $OUConName
#Create the new shape
$shape = New-VisioShape -Masters $MasterOU -Points 1.0,1.0
$shape = New-VisioShape -Master $MasterOU -Position $Point_1_1
#Set the shape details
$Shape.Text = $OUName
$Shape.Name = $shapename

#Set custom properties of the shape
Set-VisioCustomProperty -Shapes $shape -Name "OU_Name" -Value $OU.Name
Set-VisioCustomProperty -Shapes $shape -Name "DistinguishedName" -Value $OU.DistinguishedName
Set-VisioCustomProperty -Shapes $shape -Name "Linked_GPOs" -Value $OU.LinkedGroupPolicyObjects.Count
Set-VisioCustomProperty -Shape $shape -Name "OU_Name" -Value $OU.Name
Set-VisioCustomProperty -Shape $shape -Name "DistinguishedName" -Value $OU.DistinguishedName
Set-VisioCustomProperty -Shape $shape -Name "Linked_GPOs" -Value $OU.LinkedGroupPolicyObjects.Count

#Connect the shape to the root domain shape
Connect-VisioShape -From $n0 -To $shape -Master $connector
Connect-VisioShape -From $n0 -To $shape -Master $connector | Out-Null

}
#If it's not the root domain, then do this..
Expand All @@ -167,23 +175,23 @@ ForEach ($ou in $OUs)
$prevOUName = "n" + $nameRecombined

#Get the previous shape from Visio based on the name
$prevOUshape = Get-VisioShape * | Where {$_.Nameu -eq $prevOUName}
$prevOUshape = Get-VisioShape -Name * | Where-Object {$_.Nameu -eq $prevOUName}

#Set the name of the new shape
$shapename = "n" + $OUConName
#Create the new shape
$shape = New-VisioShape -Masters $MasterOU -Points 1.0,1.0
$shape = New-VisioShape -Master $MasterOU -Position $Point_1_1
#Set the shape properties
$Shape.Text = $OUName
$Shape.Name = $shapename

#Set custom properties of the shape
Set-VisioCustomProperty -Shapes $shape -Name "OU_Name" -Value $OU.Name
Set-VisioCustomProperty -Shapes $shape -Name "DistinguishedName" -Value $OU.DistinguishedName
Set-VisioCustomProperty -Shapes $shape -Name "Linked_GPOs" -Value $OU.LinkedGroupPolicyObjects.Count
Set-VisioCustomProperty -Shape $shape -Name "OU_Name" -Value $OU.Name
Set-VisioCustomProperty -Shape $shape -Name "DistinguishedName" -Value $OU.DistinguishedName
Set-VisioCustomProperty -Shape $shape -Name "Linked_GPOs" -Value $OU.LinkedGroupPolicyObjects.Count

#Connect the shape to the previous shape
Connect-VisioShape -From $prevOUshape -To $shape -Master $connector
Connect-VisioShape -From $prevOUshape -To $shape -Master $connector | Out-Null
}

#If the OU had linked GPOs..
Expand All @@ -198,23 +206,23 @@ ForEach ($ou in $OUs)
#get only the GUID of the gpo
$gpoGUID = ([Regex]::Match($gpoLink,'{[a-zA-Z0-9]{8}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{12}}')).Value
#Create the GPO shape
$gpo = Get-GPO -GUID $gpoGUID
$gpo = Get-GPO -GUID $gpoGUID -Domain $DNSDomain

#declare what we'll call the gpo shape
$shapename = "g" + $gpoCount
#Create the GPO shape
$shapeGPO = New-VisioShape -Masters $MasterGPO -Points 1.0,1.0
$shapeGPO = New-VisioShape -Master $MasterGPO -Position $Point_1_1
#Set the shape properties
$ShapeGPO.Text = $GPO.DisplayName
$ShapeGPO.Name = $shapename
$GUID = "{" + $gpo.id.guid + "}"
If ($GPO.DisplayName) {Set-VisioCustomProperty -Shapes $ShapeGPO -Name "GPOName" -Value $GPO.DisplayName}
If ($GPO.Description) {Set-VisioCustomProperty -Shapes $ShapeGPO -Name "Description" -Value $GPO.Description}
If ($GPO.ID.Guid) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "GUID" -Value $GUID}
If ($GPO.GPOStatus) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "Status" -Value $GPO.GpoStatus.ToString()}
If ($GPO.CreationTime) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "CreationTime" -Value $GPO.CreationTime.ToString()}
If ($GPO.ModificationTime) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "ModifiedTime" -Value $GPO.ModificationTime.ToString()}
If ($GPO.WmiFilter) {Set-VisioCustomProperty -Shapes $shapeGPO -Name "WMIFilterName" -Value $GPO.WMIFilter.Name}
If ($GPO.DisplayName) {Set-VisioCustomProperty -Shape $ShapeGPO -Name "GPOName" -Value $GPO.DisplayName}
If ($GPO.Description) {Set-VisioCustomProperty -Shape $ShapeGPO -Name "Description" -Value $GPO.Description}
If ($GPO.ID.Guid) {Set-VisioCustomProperty -Shape $shapeGPO -Name "GUID" -Value $GUID}
If ($GPO.GPOStatus) {Set-VisioCustomProperty -Shape $shapeGPO -Name "Status" -Value $GPO.GpoStatus.ToString()}
If ($GPO.CreationTime) {Set-VisioCustomProperty -Shape $shapeGPO -Name "CreationTime" -Value $GPO.CreationTime.ToString()}
If ($GPO.ModificationTime) {Set-VisioCustomProperty -Shape $shapeGPO -Name "ModifiedTime" -Value $GPO.ModificationTime.ToString()}
If ($GPO.WmiFilter) {Set-VisioCustomProperty -Shape $shapeGPO -Name "WMIFilterName" -Value $GPO.WMIFilter.Name}

#Create the shape's connections
$con = Connect-VisioShape -From $shape -To $shapeGPO -Master $connector
Expand All @@ -228,7 +236,7 @@ ForEach ($ou in $OUs)
$con_cells.LineBeginArrow = "4"
$con_cells.CharColor = "rgb(0,175,240)"
#Set the shape properties
Set-VisioShapeCells -Cells $con_cells -Shapes $con
Set-VisioShapeCells -Cells $con_cells -Shape $con
}
}
}
Expand Down Expand Up @@ -256,10 +264,10 @@ $con_cells = New-VisioShapeCells
$con_cells.TextFormPinX = "=POINTALONGPATH(Geometry1.Path,1)"
$con_cells.TextFormPinY = "=POINTALONGPATH(Geometry1.Path,.75)"
#Get all gpo connections
$gpoShapes = Get-VisioShape * | Where {$_.Nameu -like "gcon*"}
$gpoShapes = Get-VisioShape -Name * | Where-Object {$_.Nameu -like "gcon*"}
#Loop through each connection
ForEach($shape in $gpoShapes)
{
#Set the shape from the shape cell object
Set-VisioShapeCells -Cells $con_cells -Shapes $shape
Set-VisioShapeCells -Cells $con_cells -Shape $shape
}
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Export-ActiveDirectoryVisioMap
Exports AD OUs and GPOs to a Visio Map

# Version 1.1
Editor : Kyle Schuler

# Requirements
RSAT tools for Active Directory and GPO. </br>
VisioAutomation - https://github.com/saveenr/VisioAutomation (this module is imported in the script but I wanted to give mention to Saveenr and all his hard work). </br>
Expand All @@ -21,3 +24,8 @@ Example OU:

Example GPO:
![Example GPO Details](ExampleImages/ExampleGPOdetails.png?raw=true)


# Change Log:
Ver 1.0 - Initial release</br>
Ver 1.1 - Fixed Visio Cmdlet Parameters, Adjusted for Azure AD joined devices, Fixed issue with importing Visio module, Reduced output to console

0 comments on commit a2f232c

Please sign in to comment.