<# .Synopsis ADACLScan.ps1 AUTHOR: Robin Granberg (robin.granberg@protonmail.com) THIS CODE-SAMPLE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. .DESCRIPTION A tool with GUI or command linte used to create reports of access control lists (DACLs) and system access control lists (SACLs) in Active Directory. See https://github.com/canix1/ADACLScanner .EXAMPLE .\ADACLScan.ps1 Start in GUI mode. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" Create a CSV file with the permissions of the object CORP. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Output HTML Create a HTML file with the permissions of the object CORP. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Output EXCEL Create a Excel file with the permissions of the object CORP. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Output HTML -Show Opens the HTML (HTA) file with the permissions of the object CORP. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Output HTML -Show -SDDate Opens the HTML (HTA) file with the permissions of the object CORP including the modified date of the security descriptor. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -OutputFolder C:\Temp Create a CSV file in the folder C:\Temp, with the permissions of the object CORP. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Scope subtree Create a CSV file with the permissions of the object CORP and all child objects of type OrganizationalUnit. .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Scope subtree -EffectiveRightsPrincipal joe" Create a CSV file with the effective permissions of all the objects in the path for the user "joe". .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Scope subtree -Filter "(objectClass=user)" Create a CSV file with the permissions of all the objects in the path and below that matches the filter (objectClass=user). .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Scope subtree -Filter "(objectClass=user)" -Server DC1 Targeted search against server "DC1" that will create a CSV file with the permissions of all the objects in the path and below that matches the filter (objectClass=user). .EXAMPLE .\ADACLScan.ps1 -Base "OU=CORP,DC=CONTOS,DC=COM" -Scope subtree -Filter "(objectClass=user)" -Server DC1 -Port 389 Targeted search against server "DC1" on port 389 that will create a CSV file with the permissions of all the objects in the path and below that matches the filter (objectClass=user). .OUTPUTS The output is an CSV,HTML or EXCEL report. .LINK https://github.com/canix1/ADACLScanner .NOTES **Version: 6.8** **17 August, 2021** *Fixed issues* * Missing icons in the browsing view from release 6.8 #> Param ( # DistinguishedName to start your search at. Always included as long as your filter matches your object. [Alias("b")] [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false, Position=0, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Base, # Filter. Specify your custom filter. Default is OrganizationalUnit. [Alias("f")] [Parameter(Mandatory=$false, Position=1, ParameterSetName='Default')] [validatescript({$_ -like "(*=*)"})] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Filter, # Scope. Set your scope. Default is base. [Parameter(Mandatory=$false, Position=2, ParameterSetName='Default')] [ValidateSet("base", "onelevel", "subtree")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Scope = "base", # Server. Specify your specific server to target your search at. [Parameter(Mandatory=$false, Position=3, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Server, # Port. Specify your custom port. [Parameter(Mandatory=$false, Position=4, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Port, # EffectiveRightsPrincipal. Specify your security principal to chech for effective permissions [Parameter(Mandatory=$false, Position=5, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $EffectiveRightsPrincipal, # Generates a HTML report, default is a CSV. [Parameter(Mandatory=$false, Position=6, ParameterSetName='Default')] [ValidateSet("CSV", "HTML", "EXCEL")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Output = "", # Output folder path for where results are written. [Parameter(Mandatory=$false, Position=7, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $OutputFolder, # Template to compare with. [Parameter(Mandatory=$false, Position=8, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Template, # Template to compare with. [Parameter(Mandatory=$false, Position=8, ParameterSetName='Default')] [ValidateSet("ALL", "MATCH", "NEW","MISSING")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Returns="ALL", # Template to compare with. [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $ExcelFile="", # Filter on Criticality. [Alias("c")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateSet("Critical", "Warning", "Medium","Low","Info")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Criticality="", # Show color of criticality [Alias("color")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $ShowCriticalityColor, # Skip default permissions [Alias("sd")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $SkipDefaults, # Skip Built-in security principals [Alias("sb")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $SkipBuiltIn, # Expand groups [Alias("rf")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $RecursiveFind, # Filter on Criticality. [Alias("ro")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateSet("User", "Computer", "Group","*")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $RecursiveObjectType="*", # Skip Built-in security principals [Alias("tr")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $Translate, # Get Group Policy Objects linked [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $GPO, # Open HTML report [Alias("s")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $Show, # Include Security Descriptor modified date in report [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $SDDate, # Include Owner in report [Alias("o")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $Owner, # Include Canonical Names in report [Alias("cn")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $CanonicalNames, # Include if inheritance is disabled in report [Alias("p")] [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $Protected, # Data Managment Delegation OU Name [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $help, # Scan Default Security Descriptor [Alias("dsd")] [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $DefaultSecurityDescriptor, # Filter Default Security Descriptor on ObjectName [Alias("on")] [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $ObjectName="*", # Filter Default Security Descriptor on modified with version number higher than 1 [Alias("om")] [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $OnlyModified, # Include inherited permissions [Alias("in")] [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [switch] $IncludeInherited ) [string]$global:SessionID = [GUID]::NewGuid().Guid [string]$global:ACLHTMLFileName = "ACLHTML-$SessionID" [string]$global:SPNHTMLFileName = "SPNHTML-$SessionID" [string]$global:ModifiedDefSDAccessFileName = "ModifiedDefSDAccess-$SessionID" [string]$global:LegendHTMLFileName = "LegendHTML-$SessionID" if([threading.thread]::CurrentThread.ApartmentState.ToString() -eq 'MTA') { write-host -ForegroundColor RED "RUN PowerShell.exe with -STA switch" write-host -ForegroundColor RED "Example:" write-host -ForegroundColor RED " PowerShell -STA $PSCommandPath" Write-Host "Press any key to continue ..." [VOID]$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") Exit } #Set global value for time out in paged searches $global:TimeoutSeconds = 120 #Set global value for page size in paged searches $global:PageSize = 1000 # Hash table for Forest Level $global:ForestFLHashAD = @{ 0="Windows 2000 Server"; 1="Windows Server 2003/Interim"; 2="Windows Server 2003"; 3="Windows Server 2008"; 4="Windows Server 2008 R2"; 5="Windows Server 2012"; 6="Windows Server 2012 R2"; 7="Windows Server 2016"; 8="Windows Server 2019" } #Hash table for Domain Level $global:DomainFLHashAD = @{ 0="Windows 2000 Server"; 1="Windows Server 2003/Interim"; 2="Windows Server 2003"; 3="Windows Server 2008"; 4="Windows Server 2008 R2"; 5="Windows Server 2012"; 6="Windows Server 2012 R2"; 7="Windows Server 2016"; 8="Windows Server 2019" } $global:SchemaHashAD = @{ 13="Windows 2000 Server"; 30="Windows Server 2003"; 31="Windows Server 2003 R2"; 44="Windows Server 2008"; 47="Windows Server 2008 R2"; 56="Windows Server 2012"; 69="Windows Server 2012 R2"; 72="Windows Server 2016 Technical Preview"; 81="Windows Server 2016 Technical Preview 2"; 82="Windows Server 2016 Technical Preview 3"; 85="Windows Server 2016 Technical Preview 4"; 87="Windows Server 2016"; 88="Windows Server 2019" } # List of Exchange Schema versions $global:SchemaHashExchange = @{ 4397="Exchange Server 2000"; 4406="Exchange Server 2000 SP3"; 6870="Exchange Server 2003"; 6936="Exchange Server 2003 SP3"; 10628="Exchange Server 2007"; 10637="Exchange Server 2007"; 11116="Exchange Server 2007 SP1"; 14622="Exchange Server 2007 SP2 or Exchange Server 2010"; 14726="Exchange Server 2010 SP1"; 14732="Exchange Server 2010 SP2"; 14734="Exchange Server 2010 SP3"; 15137="Exchange Server 2013 RTM"; 15254="Exchange Server 2013 CU1"; 15281="Exchange Server 2013 CU2"; 15283="Exchange Server 2013 CU3"; 15292="Exchange Server 2013 SP1/CU4"; 15300="Exchange Server 2013 CU5"; 15303="Exchange Server 2013 CU6"; 15312="Exchange Server 2013 CU7"; 15317="Exchange Server 2016"; 15323="Exchange Server 2016 CU1"; 15325="Exchange Server 2016 CU2"; 15326="Exchange Server 2016 CU3-CU5"; 15330="Exchange Server 2016 CU6"; 15332="Exchange Server 2016 CU7-CU18"; 15333="Exchange Server 2016 CU19"; 17000="Exchange Server 2019"; 17001="Exchange Server 2019 CU2-CU7"; 17002="Exchange Server 2019 CU8" } # List of Lync Schema versions $global:SchemaHashLync = @{ 1006="LCS 2005"; 1007="OCS 2007 R1"; 1008="OCS 2007 R2"; 1100="Lync Server 2010"; 1150="Lync Server 2013/Skype for Business 2015" } Function BuildSchemaDic { $global:dicSchemaIDGUIDs = @{"BF967ABA-0DE6-11D0-A285-00AA003049E2" ="user";` "BF967A86-0DE6-11D0-A285-00AA003049E2" = "computer";` "BF967A9C-0DE6-11D0-A285-00AA003049E2" = "group";` "BF967ABB-0DE6-11D0-A285-00AA003049E2" = "volume";` "F30E3BBE-9FF0-11D1-B603-0000F80367C1" = "gPLink";` "F30E3BBF-9FF0-11D1-B603-0000F80367C1" = "gPOptions";` "BF967AA8-0DE6-11D0-A285-00AA003049E2" = "printQueue";` "4828CC14-1437-45BC-9B07-AD6F015E5F28" = "inetOrgPerson";` "5CB41ED0-0E4C-11D0-A286-00AA003049E2" = "contact";` "BF967AA5-0DE6-11D0-A285-00AA003049E2" = "organizationalUnit";` "BF967A0A-0DE6-11D0-A285-00AA003049E2" = "pwdLastSet"} $global:dicNameToSchemaIDGUIDs = @{"user"="BF967ABA-0DE6-11D0-A285-00AA003049E2";` "computer" = "BF967A86-0DE6-11D0-A285-00AA003049E2";` "group" = "BF967A9C-0DE6-11D0-A285-00AA003049E2";` "volume" = "BF967ABB-0DE6-11D0-A285-00AA003049E2";` "gPLink" = "F30E3BBE-9FF0-11D1-B603-0000F80367C1";` "gPOptions" = "F30E3BBF-9FF0-11D1-B603-0000F80367C1";` "printQueue" = "BF967AA8-0DE6-11D0-A285-00AA003049E2";` "inetOrgPerson" = "4828CC14-1437-45BC-9B07-AD6F015E5F28";` "contact" = "5CB41ED0-0E4C-11D0-A286-00AA003049E2";` "organizationalUnit" = "BF967AA5-0DE6-11D0-A285-00AA003049E2";` "pwdLastSet" = "BF967A0A-0DE6-11D0-A285-00AA003049E2"} } BuildSchemaDic $CurrentFSPath = $PSScriptRoot Add-Type -Assembly PresentationFramework $xamlBase = @" "@ [XML] $XAML = $xamlBase $xaml.Window.RemoveAttribute("x:Class") $reader=(New-Object System.Xml.XmlNodeReader $XAML) $Window=[Windows.Markup.XamlReader]::Load( $reader ) #Replace x:Name to XML variable Name $xamlBase = $xamlBase.Replace("x:Name","Name") [XML] $XAML = $xamlBase #Search the XML data for object and create variables $XAML.SelectNodes("//*[@Name]")| %{set-variable -Name ($_.Name) -Value $Window.FindName($_.Name)} $Icon = @" iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAszD0iAAAAQB0Uk5T//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuNWRHWFIAAAI3SURBVGhD7ZLRluQgCETn/3+6t4WrYoIKmfTM7p7c hwhFQb3k6/UDPCEpnpAUT0iKJyRFLuSrgRAj4eZ8AzlA1MrhAwx3xHzcdMCwJuLi3gRMKwIejilTacXWwqUCCiAWUKasDRwpoAwwKqD4LKasK2gHGCpoDqcRGyPMHDCMMGtEQphMwGRh0tiHoC/A2EFvbEIQt2AHxMYqBCUISwWUxiSEJo2/7YdQX8Bd/8WQyyn+9n 8coj7qPO7yzSH+8r8YItuUnV8MobxANqQUgnRH7EBcfUkKi6NYvyCdBb1g+lrKO+BJdrMgbQdVMQqlPCOOtglBBCNRyjPiaKeQwYNUMZqW8j3giGaxPQ3pDUaU0sUZmcX2VKR9QwueZpmO2JOnm7Q9LrmiYTaqe/VVtDvt+GpnF6KFap8JaUV1aXNXSF/rVWs+G6L1 x0LURn1TiN0617eGWAZdm46vdqIh6rO1wVc77kiXRoaBNB1XNORCTilajNqZcIg9Z/BU0SxeyME7tDQNTxTNkg1xD1JXRLPMQ2jeaO+nOFIo5GQ9CvTCSXgjmuVKSGEQZNxB7Tgh9/OEpPgLQiZ/y0DA8+0Le0cwZGHaGgqb8e7IZgy7+frMctjZGlaHFqOBvWN+aj o4ErDMjk1kh4jHP+eKPiFTPWjMCMF13g2cbG7a6DbvDo7qWcpoRjjEXO4w2RIPOaUgB0hYDymIETJeG4MQI+euMTRRsv4SQxEnv3GBJyTFE5LiCUnxhCR4vf4AzHXw0b9akGYAAAAASUVORK5CYII= "@ $IconImage = New-Object System.Windows.Media.Imaging.BitmapImage $IconImage.BeginInit() $IconImage.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($Icon) $IconImage.EndInit() # Freeze() prevents memory leaks. $IconImage.Freeze() $Window.Icon = $IconImage $twittericon = @" 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 "@ # Create a streaming image by streaming the base64 string to a bitmap streamsource $Twitterbitmap = New-Object System.Windows.Media.Imaging.BitmapImage $Twitterbitmap.BeginInit() $Twitterbitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($twittericon) $Twitterbitmap.EndInit() # Freeze() prevents memory leaks. $Twitterbitmap.Freeze() $imgTwitter.Source = $Twitterbitmap $githubicon = @" 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 "@ # Create a streaming image by streaming the base64 string to a bitmap streamsource $Githubbitmap = New-Object System.Windows.Media.Imaging.BitmapImage $Githubbitmap.BeginInit() $Githubbitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($githubicon) $Githubbitmap.EndInit() # Freeze() prevents memory leaks. $Githubbitmap.Freeze() $imgGithub.Source = $Githubbitmap # Base64 representation of Icon file from mmcndmgr.dll Index 0 $OUpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAUrSURBVFhH7Zd7TJVlHMdtq9ZWIEyBuUAEQYutOhS51tJs2Wazi80uVixzsHVzbi3LodwEBLkGiJqIpBkzScp0ioJFaXEXkIsgcgnkfrgjyOEIv76/533fc14OL8fm/KM/erbP3ud9nt/z/X5/D4dxmPP/uJuj8tRnb7Xl+tO17I9n0JLzCfHehQw/X5TeD+4Rh+7mYIOhq2lWqT0fQih1BBxi+ij65fPA5ryviGn67UtqxFNiKzX9vpWaLwRQy8Xt1JofRO2FodRZHEbdlyJIX7HLBJtYjm1ZRF8cbDQFyNzz3gbY2QDzLbD5QFUI/Zn56R1RfnIztf6xhXoKttBQb/M0YrMaKSC1ROwx1TkBfAsLwH3CnEd/VazomsbOE40yuSCH6MZZkE00wpzRpDZ7E+Uc/NAU4nbIATzBg8KchzA3lhF1JBJ1JYFkGZ6DTswV2lFz/WuiVsBPhOgo2UFHol+lo3FrKTNxHf2c8g6d+3Yj5WV8hBvaRAVZmwWqAF7AVpjz4BugiVKIw6yDDWdBmAM2VwK0g7FfpVvjWxk8TtT/gyb5x/ysBDAUSYJtLAoTgWzAa7x3PQHGQMzV6wryfku8DL/Le6gdrI0SPy5YagQY/0s6oD6k0AoxgWzARoqZMGSw/3ecRDPD7xzCjPUAY3nmYj6oPqwYTYNrJLMpTeIlUMNwndUAU6PnUIQgAqULwAJCUIMm0BhLk40xMjwHTWamFLBuPcDwCSIUMVMNEpMyUxAXCLE4mICGOLp1LQZEmzDK8HyyQQY1CtYDDGZKQvUssMuEsZ6fbASRegQCijHvTVxVE0UTdVFkAEboSPtYk/etB+j/Xhw04ICCEYdEIAt4nQVFPRiHsBoDmKibvn/zSpT1AJO9380Ugoi5O9yGjNLleG2kxBULxPlIYTpWE2nCaoBbPek4gEPVO2UkMQOEuCNmHILMzRoWVomjXlATIRitZnbSjSomwsRtAqTRKIoY5QCLqDsYq+F3CZNBZQSNWKA2Vq8PoqFZAxg796MonIYvh4snI0LIQSRDORybqIQtGRZP1gqjoQoJng/gVjUD6C/HkLF977TikcowmHAQtbgUjEMyQxUKZiOBbDysXitHAITXDNBdFk2Gtt3mYhnFyAy6A5Z1CoMVOwTKfKAclEn0gz6c1QzQUYJfmbYk+aBaVN0lKJcYnAHOqRgAbNh/KZT61EBTM0BrAT7p+AMkEqspgxgji3I4gWKk7Ku6NFEaSr1AXxpC+hKJPqxrBmi8GEGGFgRAgUSooF9GWlMbTkfqFlcMQwV9cbCgB3QXBVNXUZAIpBmgLi8MARJmXhnMGTYwh1N1CVO1cS93C3rQbTeM2bSr0ExvySwBqnNDaRw3oO5AYBnIYr0XRoy+BN0C0a0wBoWB1FkQSB35ZvTFIXR6v+/MALmH/SnnkD++x/nR2fSNdAYpTx/YQKdSP6CT3/jSiX3v00973qXjKevpx+S36Vjim3Q0YR1lxL9BR2LX0uHo1+hQ1CuUHrmG0iJeptTw1bQv9CXaG7yKUoJepN2BL1Dy9pWUtG0lJQY8PzPAUg9HGx+dy1JPdwedp9t8ndcSR28vT+AxD8zH3El+d/Re7rNo2eurHn129Yolzzz9uLPPI4sdnvRwnafzWGinW+xsI3B3ttWt8Fm4zM3Z3tvdxV7n5mwn8bCtztnpoSdguQiYvxVj3At4Ye6/wc72AbvlPq4O69c85vTcU64OLgvm2mvVWYG92POOB/9Xo4Xl0Fr7r4w5c/4B2rPd2qevIDUAAAAASUVORK5CYII= "@ # Base64 representation of Icon file from mmcndmgr.dll Index 60 $Computerpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACqSURBVFhH7Y5BCsMwEAPzdD/NP3Mj1JCQlevQlaEUj5mbV9K26NAm+JhWa7WLXMaPkQFZkcv4MfejhMUxoCV0DWj34Kf+zYCvXQPWgDUgPaCkTQ1wilzGj5EBWZHL+M8cH2faRS53ix7WReSBW/SwLiIP3KKHdZHz0/tdD0fivqf4Jzk/lf3T7vXQJXpYF5EHbtHDuog8cIse1kXkgVv0sE5zfJjp4pfYthfqvQdyNdrtOAAAAABJRU5ErkJggg== "@ # Base64 representation of Icon file from mmcndmgr.dll Index 66 $Containerpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEISURBVFhH1Y4BboQwEAP5/6v42bUOu9U2nQQHaE8daaQ7sL1s/43XRR/htYo6R/U+MemjzlG9T0z6qHNU7xOTPuqEt4lJH3X2fW/qd3iJmPRRJ49X9Ty0iUkfdeh4VZlwSkz6qEMHq8oUh8Skjzp0sKpMJ0LBU+lglTqfIrPCD/tDJPVCxC03a5akThFZGqJsSvlOBMdSva9SRva5gQgO9io3yuY7QwRHRypfO/nfFPl2wFW9CyJ4wFHdRREcd1R3wSE47qiu6RQcd1TX8JQWpANnZnfiEq1Eh0ZmZ+Bl2gAd7M0s+AhtjA6nmel8nDZsfsCv0o5MPuDP+PqQ/K2H7+Ctxx9g2z4AyFihLQt96+cAAAAASUVORK5CYII= "@ # Base64 representation of Icon file from mmcndmgr.dll Index 95 $DomainDNSpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADuSURBVFhH7ZZRDoQgDEQ9OkfzZq6P2tishcJKzJowyQsEpkztl8s/a/uRIdrWde2GuoNbch+PoC6ldLsBfaAbwoc04H1dBHWzgYBmuQE1qAGRv6pnJ5QbUgJ/SvVwXfHhzykVqakZaaAeztrcgPelJfDzsJ2C7rUxvQf8OaUiN6gEfg2ykrNrE/hzSkVuUAn8+rjo3Mt63gP+nFKRG1QCvwZZydlbJ9CLBlnJ2Vsn4AWVwK9BVnI2JzAn8MAEgBrFm4C93wnlhkRQZ/6GvumSGxBB3fwnfLyBPSXDnroR4egS1AJ1B0NkH+zhjVqWDwWbZLRmE0YzAAAAAElFTkSuQmCC "@ # Base64 representation of Icon file from mmcndmgr.dll Index 59 $Grouppng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFWSURBVFhH7ZFRkoMwDEM5OkfjZu0KolQxckiAz9XMG2diWwrt8lCfCV6VCxhlWs7kKUNyi2/SlVt4m1Ru+Dbbtn0gVCA9Kx14jIazll6qxmAUDZCQescqPau6OIMGsOKeZ61lJ1U1nQHSID4ghCqp3HAXSMMh3OsdxlCP876XigOXaAAU+1CcQQVlxqoxcdAoVrQ0wM2wFi8rNk/0DGMFVzvF96QaGOHiaHU7vC9Y6UCDGo1W7PHMWvxS1cAMGmVVQuodq/RS1eUeNMxqb6Z4dFWDHDTKKkN4jhSfrmqYAyYMy6rbE4bkFpuQHphd13Wn7N6WDYe0F+HMKw+AYrgGMMTNvPIAZ6z1F7La3pNH7KbOWOsvAH/LMd/26gPIkP4GYUho1PtKcJ5vfcD1I8JC5DCG2q9UdJbn+guArsrCFS5Qe00gGFZYjOaRe185o2jc4183tCxfI3xJToZZFYUAAAAASUVORK5CYII= "@ # Base64 representation of Icon file from mmcndmgr.dll Index 58 $Userpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAECSURBVFhH7ZFBDsMwCATz9DwtP0tDDNWCwDXY6SkjjahkvGs120uBM+FSvIJRp/FCs5bxwqqm8UJmTOOF/PQ4jpOgScJZCrw4LJbL5LM0KnhUKZX51wdIKU4+K6HCewalaAkvSEnYcpp0RLP9vndLfIusXmk0Sb6XRpWiEj46+V4aVYqOlNrJd1OoUk8JjyYUk2nwcqiURZP3yqgyq5RE8/EH9Mpl8u4UqlTEkp68vwS3nMAzx2XcZbZc5r7vt7TX1tcTluMjaK+tr0WCu4946gFXIH1nkUqa9hFPfIYrCMut7SGE+QfQKa4Ar9iKhe5ZGQlgbbgVd9TdZdjgni8DbNsHGNd/8V9LX0IAAAAASUVORK5CYII= "@ # Base64 representation of Icon file from mmcndmgr.dll Index 126 $Otherpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAErSURBVFhH1ZABjsMwCATzdD8tP2s1GCMUNQY3JFVXQtu7sDvI27/qpfMTvbrsiEcPMbh3/q9zqwR2hHtnR6dcBsk4+zolktII+snJ6nwtK7vi9OgsScJR+YrT2atjWajK6dQJZaEqp7O1ljrAQlVOJ/DWci8gSyN81eka8IUXsEvld9e6k/fw9Avs+y4FOH8zXXknc4QvvYA/YhSOb13nzt4n+FcvcHS+M11rcFzzU0nR7IgBGrtdMRzX3FQh3Dv7YyI4rrtTpeHeyUVwnD2hTJSGeicXwXH2hDJRGuqdXATH2RPKRGmod3IVcJSGeidXAUdpqHdyFXAkgQzUO5kKuJeEM3Cc3Uq4lxRFR7BzB9xLSs+O4NudcC8BnL2Afn9EAvMvoPO4LsK37Q0ZagAN4BkscgAAAABJRU5ErkJggg== "@ # Base64 representation of Icon file from shell32.dll Index 234 $excludepng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANTSURBVFhH7ZZLTxNRGIbnBwBFQcFLjD8B2erCGBUFGveujCuNG68ovwBR8IKgK9yCeElASltughZFRRAXGAKllrZUoPTCRmNsPt93phchpZ0ZcOeXvGkaynme882Zc47yvzLV6qRVVj9bJaamWmITWqLMeDJVEvn0V8a0hMcqJfwxnZUPaiYSQ+srwiX4yGQeiiwwLUizSMSpSiSG1lecOQeLe2oxQN86QLasgy88EAlD4P1JowLV6oDGBDLAAxRwSMiwAJ41B9UvsAE80AQB+78WyAIP3NcERg0KcLVz8NwCOeCBeyIrZgTwmhGQXUAH3E+BHlneegGdcP9dCNhk+d0JowJVKiizgAG4/445Ae5smQUMwrdWwATc1wiBbll6u2kBk3BfAwRemhDAobJGwCzcd3uzAjcSAibh/FsIAiMGBXiksu3xOQr06oLHnDUysHe/xBzXNDgTwP+FumTRdVQWRyrKOPYLpbAM8fBThWUqnuNse3zuOgScuuD9BaXiVbbLG3zGHFe1Lix1yM+5BllyHYFExcTAgX2HnUphZBq/68Tn840kNIGWtECOtnPmhEeVIllGhiERHaiX+GK7hEet8mvqvATarNKfVyw+/G4B+Yo8QycSyLWlCTRDoEY9z3M9c7adMyc8jCwiQ5Y94gf0x5ezEu0+J4MFJSk4Ze3oAAQyd4A3GLY97qaAIys8ueDYds6c8BASBGQwf4d46k8Zg7NUAbQ97saCwnGaC65m/pZEHZdlCBKELyEBxKVsMwZnaQJNaQEdcJmvR25K1H5JXkGC8O8IZZLwXqyBnHAW73Bse9yN1YzzXC9cjbdOvI2n1Zkn4ZQZxvfJ2nJ9+wGvUGy7JtBjCB61X8QzL021nXA/4kGc6MBTPR1QBdD2uPsKBGym4Ww7Z074POJGbFgDHYoluwSvUGx7SsAkvC+/WDx1ldKHt4Dwb8gMhLoVS+RJNglNwHzbCe+37BZva7n8nrogkc4z4izYqcLnkGmkCxLtG0nwDsdLRDI8zVLBwYJ9XYtLi21XCQZNw7naZx8fkuDr4xIcZo7JTOtBsecVqfBZZBxpUyyZd0KjxYOFezu312zvOdvOmROOdRCBQO4Fqbd4sADsyfWes+2cuQZXlD9Le+RDT9WknQAAAABJRU5ErkJggg== "@ # Base64 representation of Icon file from mmcndmgr.dll Index 6 $Expandpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABCSURBVFhH7c6xDQAgFALRv//SusAVxKCN9xJaYCTp0II85YG/DtBYmgoqTlNBxWkqqDhNBRWnuebpGPGABySpZGYDyjh8hAYS3OQAAAAASUVORK5CYII= "@ # Base64 representation of Icon file from shell32.dll Index 238 $refreshpng = @" iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAPkSURBVFhH7Vc7UxNRFOYXKOIDeagQIA9C2M0mAbTiJ/ATQHkEMGHxgcyIEJ8zykjUUUEt0t0iKZzZJiVFipQpaCgyk4bCLj/h+J3lbtwkuyTY6pn5ZvZx7zln755zv+92/LN2YU50ysv2zXdfzIysiszwqij5Hhrk38iTD/A+ztPNuCj1L4lM35KYkcNd7eKcyCCBaXl7to0mRGcgIVKBtWxVeV6gaPqY7vz45YjoxzL5nxWofyVbvb4gUt0LzV/ZeVdkuu8b1FYCY0mhBhOiEn5VpKn9E7r9/VdbmMRYf6pIPcu5yrV5oUp3HZcQPPC6RMPbxdYJhNbE7PiGQbFPZZqC079B+EOZ+pMGXZ0Xs5fvnQbn50OtElAQXHli0AS+ZBIT7OBn4d0jCr0o0phE8HmRlHdHFPvaPJ6f9SEJDm49G3p2RgKqLlSVg2PixDcElGBHoVSBfMlcBUWYHloR0x5gYFlM34qL6Rtxkb65mqvw0kcb5jbC0yKBShTFFMNACxHccxGiC3Q5zNX6FoV+I/GzqqbrfdjhmkBYFykNBRc9QEVLaPiPo3q2ik6oFVMr61kUam88S9qXkzpfFgbdEtAeZqsRLF8Eg0zAQRDB0YptB2dDAmbB1fw0wDEBbV3MaC8KpGGABeUlCizZetnthl9gBrf7acTAlkMCkXWRCe8dU3gf7cP4jKJbz1Xk67aMd0IOXvPhArcEDnnDYaj4cmX7kLARpeXrloYuyAzoBnl3ijTCQK/zhsM9z23HhcdLz+heyzvXwH/7ty22laeJN0WKvcZGJBEBeGNiWMUZeGQQtuKMnNbSQERpz+ahWZxWgUIPHMrXf4yDO3G8HdrbErEgkVPasuvxXGXy4KTmQ3l/zAk0dxcn4MTtFjg4uOBcwaEFdB++2O7H87TACTSrphgSaORzCxzcf87gUENqTzxbjYG+LT983bWYrcoh9cb/3s7jFpj/QUacwHnJqMqCxO6LNyZIspQcVm+cgBN3M5ieRx/8bIuOe0HHfctZk47tPhTcQ5K5b+1c9U7cbYFFxjjUj9cmSAYhRmqCZOlUkHghSplR7XP5vidhUNe9M1bRbD0wFYP/uQI9GHXgc6Zoll8swxijUEABIPT2yHzXOJ41QS+CQxPOylDOxj3PXG0GXxOZUFLMhpAEC5JGPm8X43tlUw9egSiVYdwtwhsOgkOS1aodWkAN6rkKLz1/iRO3O4GpnNkQnVAny880bdMgSDLHVuODiR+aMLhTMIvJieMZY7vHNLJVIC5Ct4OJq7EgkZeu5rWOZiuixMexEWD4UZ486wZBD5wezRZbH83+2x/r6PgNVo1XtD2bLOEAAAAASUVORK5CYII= "@ $txtTempFolder.Text = $CurrentFSPath $global:bolConnected = $false $global:strPinDomDC = "" $global:strPrinDomAttr = "" $global:strPrinDomDir = "" $global:strPrinDomFlat = "" $global:strPrincipalDN ="" $global:strDomainPrinDNName = "" $global:strEffectiveRightSP = "" $global:strEffectiveRightAccount = "" $global:strSPNobjectClass = "" $global:tokens = New-Object System.Collections.ArrayList $global:tokens.Clear() $global:strDommainSelect = "rootDSE" $global:bolTempValue_InhertiedChkBox = $false [void]$combReturns.Items.Add("ALL") [void]$combReturns.Items.Add("NEW") [void]$combReturns.Items.Add("MATCH") [void]$combReturns.Items.Add("MISSING") [void]$combServerity.Items.Add("Critical") [void]$combServerity.Items.Add("Warning") [void]$combServerity.Items.Add("Medium") [void]$combServerity.Items.Add("Low") [void]$combServerity.Items.Add("Info") [void]$combRecursiveFind.Items.Add("*") [void]$combRecursiveFind.Items.Add("User") [void]$combRecursiveFind.Items.Add("Group") [void]$combRecursiveFind.Items.Add("Computer") $combRecursiveFind.SelectedValue="*" [void]$combAccessCtrl.Items.Add("Allow") [void]$combAccessCtrl.Items.Add("Deny") [void]$combObjectDefSD.Items.Add("All Objects") $combObjectDefSD.SelectedValue="All Objects" ################### #TODO: Place custom script here #### Check if UI should be loaded if((!($base) -and (!($GPO)))) { $Window.Add_Loaded({ $Global:observableCollection = New-Object System.Collections.ObjectModel.ObservableCollection[System.Object] $TextBoxStatusMessage.ItemsSource = $Global:observableCollection }) if ($PSVersionTable.PSVersion -gt "2.0") { try { Add-Type @" public class DelegateCommand : System.Windows.Input.ICommand { private System.Action _action; public DelegateCommand(System.Action action) { _action = action; } public bool CanExecute(object parameter) { return true; } public event System.EventHandler CanExecuteChanged = delegate { }; public void Execute(object parameter) { _action(parameter); } } "@ }catch {} } Add-Type @" using System; using System.Runtime.InteropServices; public class SFW { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); } "@ Add-Type -AssemblyName System.Windows.Forms | Out-Null $chkBoxShowDel.add_Checked({ $global:bolShowDeleted= $true }) $chkBoxShowDel.add_UnChecked({ $global:bolShowDeleted= $false }) $btnDownloadCSVDefACLs.add_Click({ GenerateTemplateDownloader }) $btnDownloadCSVDefSD.add_Click({ GenerateTemplateDownloaderSchemaDefSD }) $rdbScanOU.add_Click({ $txtCustomFilter.IsEnabled = $false }) $rdbScanContainer.add_Click({ $txtCustomFilter.IsEnabled = $false }) $rdbScanAll.add_Click({ $txtCustomFilter.IsEnabled = $false }) $rdbScanFilter.add_Click({ $txtCustomFilter.IsEnabled = $true }) $rdbEXcel.add_Click({ if(!$(get-module ImportExcel)) {  $global:observableCollection.Insert(0,(LogMessage -strMessage "Checking for ImportExcel PowerShell Module..."  -strType "Info" -DateStamp )) if(!$(get-module -ListAvailable | Where-Object name -eq "ImportExcel")) { $global:observableCollection.Insert(0,(LogMessage -strMessage "You need to install the PowerShell module ImportExcel found in the PSGallery"  -strType "Error" -DateStamp )) $rdbOnlyHTA.IsChecked = $true } else { Import-Module ImportExcel } } }) $btnGetForestInfo.add_Click({ if ($global:bolConnected -eq $true) { Get-SchemaData $global:CREDS $global:observableCollection.Insert(0,(LogMessage -strMessage "Information collected!" -strType "Info" -DateStamp )) } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) $btnClearExcludedBox.add_Click({ $txtBoxExcluded.text = "" }) $btnGetSchemaClass.add_Click( { if ($global:bolConnected -eq $true) { $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $SearchFilter = "(objectClass=classSchema)" $request = New-Object System.directoryServices.Protocols.SearchRequest("$global:SchemaDN", $SearchFilter, "Subtree") [System.DirectoryServices.Protocols.PageResultRequestControl]$pagedRqc = new-object System.DirectoryServices.Protocols.PageResultRequestControl($global:PageSize) $request.Controls.Add($pagedRqc) | Out-Null [void]$request.Attributes.Add("name") $arrSchemaObjects = New-Object System.Collections.ArrayList while ($true) { $response = $LdapConnection.SendRequest($request, (new-object System.Timespan(0,0,$global:TimeoutSeconds))) -as [System.DirectoryServices.Protocols.SearchResponse]; #for paged search, the response for paged search result control - we will need a cookie from result later if($global:PageSize -gt 0) { [System.DirectoryServices.Protocols.PageResultResponseControl] $prrc=$null; if ($response.Controls.Length -gt 0) { foreach ($ctrl in $response.Controls) { if ($ctrl -is [System.DirectoryServices.Protocols.PageResultResponseControl]) { $prrc = $ctrl; break; } } } if($null -eq $prrc) { #server was unable to process paged search throw "Find-LdapObject: Server failed to return paged response for request $SearchFilter" } } #now process the returned list of distinguishedNames and fetch required properties using ranged retrieval $colResults = $response.Entries foreach ($objResult in $colResults) { [void]$arrSchemaObjects.Add($objResult.attributes.name[0]) } if($global:PageSize -gt 0) { if ($prrc.Cookie.Length -eq 0) { #last page --> we're done break; } #pass the search cookie back to server in next paged request $pagedRqc.Cookie = $prrc.Cookie; } else { #exit the processing for non-paged search break; } }#End While $arrSchemaObjects.Sort() foreach ($object in $arrSchemaObjects) { [void]$combObjectDefSD.Items.Add($object) } $global:observableCollection.Insert(0,(LogMessage -strMessage "All classSchema collected!" -strType "Info" -DateStamp )) $object = $null Remove-Variable object $arrSchemaObjects = $null Remove-Variable arrSchemaObjects } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) $btnExportDefSD.add_Click( { $global:bolProgressBar = $chkBoxSkipProgressBar.IsChecked if ($global:bolConnected -eq $true) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Scanning..." -strType "Info" -DateStamp )) $strFileCSV = $txtTempFolder.Text + "\" +$global:strDomainShortName + "_DefaultSecDescriptor" + $date + ".csv" Write-DefaultSDCSV $strFileCSV $global:observableCollection.Insert(0,(LogMessage -strMessage "Finished" -strType "Info" -DateStamp )) } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) $btnCompDefSD.add_Click( { $global:bolProgressBar = $chkBoxSkipProgressBar.IsChecked if ($global:bolConnected -eq $true) { if ($txtCompareDefSDTemplate.Text -eq "") { $global:observableCollection.Insert(0,(LogMessage -strMessage "No Template CSV file selected!" -strType "Error" -DateStamp )) } else { $global:bolProgressBar = $chkBoxSkipProgressBar.IsChecked $global:bolDefaultSDCSVLoaded = $false $strDefaultSDCompareFile = $txtCompareDefSDTemplate.Text &{#Try $global:bolDefaultSDCSVLoaded = $true $global:csvdefSDTemplate = import-Csv $strDefaultSDCompareFile } Trap [SystemException] { $strCSVErr = $_.Exception.Message $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed to load CSV. $strCSVErr" -strType "Error" -DateStamp )) $global:bolDefaultSDCSVLoaded = $false continue } if($bolDefaultSDCSVLoaded) { if(TestCSVColumnsDefaultSD $global:csvdefSDTemplate) { $strSelectedItem = $combObjectDefSD.SelectedItem if($strSelectedItem -eq "All Objects") { $strSelectedItem = "*" } $global:observableCollection.Insert(0,(LogMessage -strMessage "Scanning..." -strType "Info" -DateStamp )) Get-DefaultSDCompare $strSelectedItem $strDefaultSDCompareFile $global:observableCollection.Insert(0,(LogMessage -strMessage "Finished" -strType "Info" -DateStamp )) } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "CSV file got wrong format! File: $strDefaultSDCompareFile" -strType "Error" -DateStamp )) } #End if test column names exist } }#end if txtCompareDefSDTemplate.Text is empty } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) $btnScanDefSD.add_Click( { $global:bolProgressBar = $chkBoxSkipProgressBar.IsChecked $bolReplMeta = $true $strFileDefSDHTA = $env:temp + "\"+$global:ACLHTMLFileName+".hta" #Set the path for the HTM file name if($OutputFolder -gt "") { #Check if foler exist if not use current folder if(Test-Path $OutputFolder) { $strFileDefSDHTM = $OutputFolder + "\"+"$global:strDomainShortName-$strSelectedItem-$global:SessionID"+".htm" } else { Write-host "Path:$OutputFolder was not found! Writting to current folder." -ForegroundColor red $strFileDefSDHTM = $CurrentFSPath + "\"+"$global:strDomainShortName-$strSelectedItem-$global:SessionID"+".htm" } } else { $strFileDefSDHTM = $CurrentFSPath + "\"+"$global:strDomainShortName-$strSelectedItem-$global:SessionID"+".htm" } if ($global:bolConnected -eq $true) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Scanning..." -strType "Info" -DateStamp )) $strSelectedItem = $combObjectDefSD.SelectedItem if($strSelectedItem -eq "All Objects") { $strSelectedItem = "*" } if($chkBoxSeverity.isChecked -or $chkBoxEffectiveRightsColor.isChecked) { $bolShowCriticalityColor = $true } else { $bolShowCriticalityColor = $false } if($bolSDDL -eq $true) { CreateDefaultSDReportHTA $global:strDomainLongName $strFileDefSDHTA $strFileDefSDHTM $CurrentFSPath CreateDefSDHTM $global:strDomainLongName $strFileDefSDHTM InitiateDefSDHTM $strFileDefSDHTM $strSelectedItem InitiateDefSDHTM $strFileDefSDHTA $strSelectedItem } else { CreateHTM $strSelectedItem $strFileDefSDHTM CreateHTA $strSelectedItem $strFileDefSDHTA $strFileDefSDHTM $CurrentFSPath $global:strDomainDNName $global:strDC InitiateDefSDAccessHTM $strFileDefSDHTA $strSelectedItem $bolReplMeta $false "" $bolShowCriticalityColor InitiateDefSDAccessHTM $strFileDefSDHTM $strSelectedItem $bolReplMeta $false "" $bolShowCriticalityColor } Get-DefaultSD -strObjectClass $strSelectedItem -bolChangedDefSD $chkModifedDefSD.IsChecked -bolSDDL $rdbDefSD_SDDL.IsChecked -Show $true -File $strFileDefSDHTM -OutType "HTML" -bolShowCriticalityColor $bolShowCriticalityColor -Assess $chkBoxSeverity.IsChecked -Criticality $combServerity.SelectedItem -bolReplMeta $bolReplMeta $global:observableCollection.Insert(0,(LogMessage -strMessage "Finished" -strType "Info" -DateStamp )) } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) $btnGETSPNReport.add_Click( { If(($global:strEffectiveRightSP -ne "") -and ($global:tokens.count -gt 0)) { $strFileSPNHTA = $env:temp + "\"+$global:SPNHTMLFileName+".hta" $strFileSPNHTM = $env:temp + "\"+"$global:strEffectiveRightAccount"+".htm" CreateServicePrincipalReportHTA $global:strEffectiveRightSP $strFileSPNHTA $strFileSPNHTM $CurrentFSPath CreateSPNHTM $global:strEffectiveRightSP $strFileSPNHTM InitiateSPNHTM $strFileSPNHTA $strColorTemp = 1 WriteSPNHTM $global:strEffectiveRightSP $global:tokens $global:strSPNobjectClass $($global:tokens.count-1) $strColorTemp $strFileSPNHTA $strFileSPNHTM Invoke-Item $strFileSPNHTA } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "No service principal selected!" -strType "Error" -DateStamp )) } }) $btnViewLegend.add_Click( { DisplayLegend }) $btnGetSPAccount.add_Click( { if ($global:bolConnected -eq $true) { If (!($txtBoxSelectPrincipal.Text -eq "")) { GetEffectiveRightSP $txtBoxSelectPrincipal.Text $global:strDomainPrinDNName } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Enter a principal name!" -strType "Error" -DateStamp )) } } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) $btnListDdomain.add_Click( { GenerateDomainPicker $txtBoxDomainConnect.Text = $global:strDommainSelect }) $btnListLocations.add_Click( { if ($global:bolConnected -eq $true) { GenerateTrustedDomainPicker } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) $chkBoxScanUsingUSN.add_Click( { If($chkBoxScanUsingUSN.IsChecked) { $global:bolTempValue_chkBoxReplMeta = $chkBoxReplMeta.IsChecked $chkBoxReplMeta.IsChecked = $true } else { if ($null -ne $global:bolTempValue_chkBoxReplMeta) { $chkBoxReplMeta.IsChecked = $global:bolTempValue_chkBoxReplMeta } } }) $chkBoxCompare.add_Click( { If($chkBoxCompare.IsChecked) { if ($null -ne $global:bolTempValue_InhertiedChkBox) { $chkInheritedPerm.IsChecked = $global:bolTempValue_InhertiedChkBox } if ($null -ne $global:bolTempValue_chkBoxGetOwner) { $chkBoxGetOwner.IsChecked = $global:bolTempValue_chkBoxGetOwner } $chkInheritedPerm.IsEnabled = $true $chkBoxGetOwner.IsEnabled = $true #Activate Compare Objects $txtCompareTemplate.IsEnabled = $true $combReturns.IsEnabled = $true $chkBoxTemplateNodes.IsEnabled = $true $chkBoxScanUsingUSN.IsEnabled = $true $btnGetCompareInput.IsEnabled = $true $txtReplaceDN.IsEnabled = $true $txtReplaceNetbios.IsEnabled = $true #Deactivate Effective Rights and Filter objects $chkBoxFilter.IsChecked = $false $chkBoxEffectiveRights.IsChecked = $false $txtBoxSelectPrincipal.IsEnabled = $false $btnGetSPAccount.IsEnabled = $false $btnListLocations.IsEnabled = $false $btnGETSPNReport.IsEnabled = $false $chkBoxType.IsEnabled = $false $chkBoxObject.IsEnabled = $false $chkBoxTrustee.IsEnabled = $false $chkBoxFilterBuiltin.IsEnabled = $false $chkBoxType.IsChecked = $false $chkBoxObject.IsChecked = $false $combObjectFilter.IsEnabled = $false $txtFilterTrustee.IsEnabled = $false $combAccessCtrl.IsEnabled = $false $btnGetObjFullFilter.IsEnabled = $false } else { #Deactivate Compare Objects $txtCompareTemplate.IsEnabled = $false $combReturns.IsEnabled = $false $chkBoxTemplateNodes.IsEnabled = $false $chkBoxScanUsingUSN.IsEnabled = $false $btnGetCompareInput.IsEnabled = $false $txtReplaceDN.IsEnabled = $false $txtReplaceNetbios.IsEnabled = $false } }) $chkBoxEffectiveRights.add_Click( { If($chkBoxEffectiveRights.IsChecked) { $global:bolTempValue_InhertiedChkBox = $chkInheritedPerm.IsChecked $global:bolTempValue_chkBoxGetOwner = $chkBoxGetOwner.IsChecked $chkBoxFilter.IsChecked = $false #Deactivate Compare Objects $chkBoxCompare.IsChecked = $false $txtCompareTemplate.IsEnabled = $false $combReturns.IsEnabled = $false $chkBoxTemplateNodes.IsEnabled = $false $chkBoxScanUsingUSN.IsEnabled = $false $btnGetCompareInput.IsEnabled = $false $txtReplaceDN.IsEnabled = $false $txtReplaceNetbios.IsEnabled = $false $txtBoxSelectPrincipal.IsEnabled = $true $btnGetSPAccount.IsEnabled = $true $btnListLocations.IsEnabled = $true $btnGETSPNReport.IsEnabled = $true $chkInheritedPerm.IsEnabled = $false $chkInheritedPerm.IsChecked = $true $chkBoxGetOwner.IsEnabled = $false $chkBoxGetOwner.IsChecked= $true $chkBoxType.IsEnabled = $false $chkBoxObject.IsEnabled = $false $chkBoxTrustee.IsEnabled = $false $chkBoxType.IsChecked = $false $chkBoxObject.IsChecked = $false $chkBoxFilterBuiltin.IsChecked = $false $combObjectFilter.IsEnabled = $false $txtFilterTrustee.IsEnabled = $false $combAccessCtrl.IsEnabled = $false $btnGetObjFullFilter.IsEnabled = $false } else { $txtBoxSelectPrincipal.IsEnabled = $false $btnGetSPAccount.IsEnabled = $false $btnListLocations.IsEnabled = $false $btnGETSPNReport.IsEnabled = $false $chkInheritedPerm.IsEnabled = $true $chkInheritedPerm.IsChecked = $global:bolTempValue_InhertiedChkBox $chkBoxGetOwner.IsEnabled = $true $chkBoxGetOwner.IsChecked = $global:bolTempValue_chkBoxGetOwner } }) $chkBoxSeverity.add_Click( { If($chkBoxSeverity.IsChecked -eq $true) { $combServerity.IsEnabled = $true } else { $combServerity.IsEnabled = $false } }) $chkBoxRecursiveFind.add_Click( { If($chkBoxRecursiveFind.IsChecked -eq $true) { $combRecursiveFind.IsEnabled = $true } else { $combRecursiveFind.IsEnabled = $false } }) $chkBoxFilter.add_Click( { If($chkBoxFilter.IsChecked -eq $true) { #Deactivate Compare Objects $chkBoxCompare.IsChecked = $false $txtCompareTemplate.IsEnabled = $false $combReturns.IsEnabled = $false $chkBoxTemplateNodes.IsEnabled = $false $chkBoxScanUsingUSN.IsEnabled = $false $btnGetCompareInput.IsEnabled = $false $txtReplaceDN.IsEnabled = $false $txtReplaceNetbios.IsEnabled = $false $chkBoxEffectiveRights.IsChecked = $false $chkBoxType.IsEnabled = $true $chkBoxObject.IsEnabled = $true $chkBoxTrustee.IsEnabled = $true $chkBoxFilterBuiltin.IsEnabled = $true $combObjectFilter.IsEnabled = $true $txtFilterTrustee.IsEnabled = $true $combAccessCtrl.IsEnabled = $true $btnGetObjFullFilter.IsEnabled = $true $txtBoxSelectPrincipal.IsEnabled = $false $btnGetSPAccount.IsEnabled = $false $btnListLocations.IsEnabled = $false $btnGETSPNReport.IsEnabled = $false $chkInheritedPerm.IsEnabled = $true $chkInheritedPerm.IsChecked = $global:bolTempValue_InhertiedChkBox $chkBoxGetOwner.IsEnabled = $true if ($null -ne $global:bolTempValue_chkBoxGetOwner) { $chkBoxGetOwner.IsChecked = $global:bolTempValue_chkBoxGetOwner } } else { $chkBoxType.IsEnabled = $false $chkBoxObject.IsEnabled = $false $chkBoxTrustee.IsEnabled = $false $chkBoxFilterBuiltin.IsEnabled = $false $chkBoxType.IsChecked = $false $chkBoxObject.IsChecked = $false $combObjectFilter.IsEnabled = $false $txtFilterTrustee.IsEnabled = $false $combAccessCtrl.IsEnabled = $false $btnGetObjFullFilter.IsEnabled = $false } }) $rdbDSSchm.add_Click( { If($rdbCustomNC.IsChecked -eq $true) { $txtBoxDomainConnect.IsEnabled = $true $btnListDdomain.IsEnabled = $false if (($txtBoxDomainConnect.Text -eq "rootDSE") -or ($txtBoxDomainConnect.Text -eq "config") -or ($txtBoxDomainConnect.Text -eq "schema")) { $txtBoxDomainConnect.Text = "" } } else { $btnListDdomain.IsEnabled = $false If($rdbDSdef.IsChecked -eq $true) { $txtBoxDomainConnect.Text = $global:strDommainSelect $btnListDdomain.IsEnabled = $true $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false } If($rdbDSConf.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "config" $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false } If($rdbDSSchm.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "schema" $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false } $txtBoxDomainConnect.IsEnabled = $false } }) $rdbDSConf.add_Click( { If($rdbCustomNC.IsChecked -eq $true) { $txtBoxDomainConnect.IsEnabled = $true $btnListDdomain.IsEnabled = $false if (($txtBoxDomainConnect.Text -eq "rootDSE") -or ($txtBoxDomainConnect.Text -eq "config") -or ($txtBoxDomainConnect.Text -eq "schema")) { $txtBoxDomainConnect.Text = "" } } else { $btnListDdomain.IsEnabled = $false If($rdbDSdef.IsChecked -eq $true) { $txtBoxDomainConnect.Text = $global:strDommainSelect $btnListDdomain.IsEnabled = $true $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false } If($rdbDSConf.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "config" $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false } If($rdbDSSchm.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "schema" $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false } $txtBoxDomainConnect.IsEnabled = $false } }) $rdbDSdef.add_Click( { If($rdbCustomNC.IsChecked -eq $true) { $txtBoxDomainConnect.IsEnabled = $true $btnListDdomain.IsEnabled = $false if (($txtBoxDomainConnect.Text -eq "rootDSE") -or ($txtBoxDomainConnect.Text -eq "config") -or ($txtBoxDomainConnect.Text -eq "schema")) { $txtBoxDomainConnect.Text = "" } } else { $btnListDdomain.IsEnabled = $false If($rdbDSdef.IsChecked -eq $true) { $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false $txtBoxDomainConnect.Text = $global:strDommainSelect $btnListDdomain.IsEnabled = $true } If($rdbDSConf.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "config" } If($rdbDSSchm.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "schema" } $txtBoxDomainConnect.IsEnabled = $false } }) $rdbCustomNC.add_Click( { If($rdbCustomNC.IsChecked -eq $true) { $txtBdoxDSServerPort.IsEnabled = $true $txtBdoxDSServer.IsEnabled = $true $txtBoxDomainConnect.IsEnabled = $true $btnListDdomain.IsEnabled = $false if (($txtBoxDomainConnect.Text -eq "rootDSE") -or ($txtBoxDomainConnect.Text -eq "config") -or ($txtBoxDomainConnect.Text -eq "schema")) { $txtBoxDomainConnect.Text = "" } } else { $btnListDdomain.IsEnabled = $false If($rdbDSdef.IsChecked -eq $true) { $txtBoxDomainConnect.Text = $global:strDommainSelect $btnListDdomain.IsEnabled = $true } If($rdbDSConf.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "config" } If($rdbDSSchm.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "schema" } $txtBoxDomainConnect.IsEnabled = $false } }) $btnGetTemplateFolder.add_Click( { $strFolderPath = Select-Folder $txtTempFolder.Text = $strFolderPath }) $btnGetCompareDefSDInput.add_Click( { $strFilePath = Select-File $txtCompareDefSDTemplate.Text = $strFilePath }) $btnGetCompareInput.add_Click( { $strFilePath = Select-File $txtCompareTemplate.Text = $strFilePath }) $btnGetCSVFile.add_Click( { $strFilePath = Select-File $txtCSVImport.Text = $strFilePath }) $btnDSConnect.add_Click( { if($chkBoxCreds.IsChecked) { $global:CREDS = Get-Credential -Message "Type User Name and Password" $Window.Activate() } $global:bolRoot = $true $NCSelect = $false $global:DSType = "" $global:strDC = "" $global:strDomainDNName = "" $global:ConfigDN = "" $global:SchemaDN = "" $global:ForestRootDomainDN = "" $global:IS_GC = "" $txtDC.text = "" $txtdefaultnamingcontext.text = "" $txtconfigurationnamingcontext.text = "" $txtschemanamingcontext.text = "" $txtrootdomainnamingcontext.text = "" If ($rdbDSdef.IsChecked) { if (!($txtBoxDomainConnect.Text -eq "rootDSE")) { if ($null -eq $global:TempDC) { $strNamingContextDN = $txtBoxDomainConnect.Text If(CheckDNExist $strNamingContextDN "") { $root = New-Object system.directoryservices.directoryEntry("LDAP://"+$strNamingContextDN) $global:strDomainDNName = $root.distinguishedName.tostring() $global:strDomainPrinDNName = $global:strDomainDNName $global:strDomainLongName = $global:strDomainDNName.Replace("DC=","") $global:strDomainLongName = $global:strDomainLongName.Replace(",",".") $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strDomainLongName ) $ojbDomain = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($Context) $global:strDC = $($ojbDomain.FindDomainController()).name $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("dnshostname") [void]$request.Attributes.Add("supportedcapabilities") [void]$request.Attributes.Add("namingcontexts") [void]$request.Attributes.Add("defaultnamingcontext") [void]$request.Attributes.Add("schemanamingcontext") [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $global:ForestRootDomainDN = $response.Entries[0].attributes.rootdomainnamingcontext[0] $global:SchemaDN = $response.Entries[0].attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].attributes.configurationnamingcontext[0] $global:strDomainDNName = $response.Entries[0].attributes.defaultnamingcontext[0] $global:IS_GC = $response.Entries[0].Attributes.isglobalcatalogready[0] } $global:DirContext = Get-DirContext $global:strDC $global:CREDS $global:strDomainShortName = GetDomainShortName $global:strDomainDNName $global:ConfigDN $global:strRootDomainShortName = GetDomainShortName $global:ForestRootDomainDN $global:ConfigDN $global:DSType = "AD DS" $global:bolADDSType = $true $lblSelectPrincipalDom.Content = $global:strDomainShortName+":" $NCSelect = $true $strNamingContextDN = $global:strDomainDNName } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) $global:bolConnected = $false } } else { $strNamingContextDN = $txtBoxDomainConnect.Text If(CheckDNExist $strNamingContextDN "$global:TempDC") { $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:TempDC ) $global:TempDC = $null $ojbDomain = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($Context) $global:strDC = $($ojbDomain.FindDomainController()).name $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("dnshostname") [void]$request.Attributes.Add("supportedcapabilities") [void]$request.Attributes.Add("namingcontexts") [void]$request.Attributes.Add("defaultnamingcontext") [void]$request.Attributes.Add("schemanamingcontext") [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $global:ForestRootDomainDN = $response.Entries[0].attributes.rootdomainnamingcontext[0] $global:SchemaDN = $response.Entries[0].attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].attributes.configurationnamingcontext[0] $global:strDomainDNName = $response.Entries[0].attributes.defaultnamingcontext[0] $global:IS_GC = $response.Entries[0].Attributes.isglobalcatalogready[0] } $global:DirContext = Get-DirContext $global:strDC $global:CREDS $global:strDomainShortName = GetDomainShortName $global:strDomainDNName $global:ConfigDN $global:strRootDomainShortName = GetDomainShortName $global:ForestRootDomainDN $global:ConfigDN $global:DSType = "AD DS" $global:bolADDSType = $true $lblSelectPrincipalDom.Content = $global:strDomainShortName+":" $NCSelect = $true $strNamingContextDN = $global:strDomainDNName } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) $global:bolConnected = $false } } } else { if ($global:bolRoot -eq $true) { $LDAPConnection = $null $request = $null $response = $null $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection("") $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("defaultnamingcontext") try { $response = $LDAPConnection.SendRequest($request) $global:strDomainDNName = $response.Entries[0].Attributes.defaultnamingcontext[0] $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection) { $global:strDomainPrinDNName = $global:strDomainDNName $global:strDomainLongName = $global:strDomainDNName.Replace("DC=","") $global:strDomainLongName = $global:strDomainLongName.Replace(",",".") $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strDomainLongName ) $ojbDomain = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($Context) $global:strDC = $($ojbDomain.FindDomainController()).name $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("dnshostname") [void]$request.Attributes.Add("supportedcapabilities") [void]$request.Attributes.Add("namingcontexts") [void]$request.Attributes.Add("defaultnamingcontext") [void]$request.Attributes.Add("schemanamingcontext") [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $global:ForestRootDomainDN = $response.Entries[0].attributes.rootdomainnamingcontext[0] $global:SchemaDN = $response.Entries[0].attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].attributes.configurationnamingcontext[0] $global:strDomainDNName = $response.Entries[0].attributes.defaultnamingcontext[0] $global:IS_GC = $response.Entries[0].Attributes.isglobalcatalogready[0] } $global:DirContext = Get-DirContext $global:strDC $global:CREDS $global:strDomainShortName = GetDomainShortName $global:strDomainDNName $global:ConfigDN $global:strRootDomainShortName = GetDomainShortName $global:ForestRootDomainDN $global:ConfigDN $global:DSType = "AD DS" $global:bolADDSType = $true $lblSelectPrincipalDom.Content = $global:strDomainShortName+":" $NCSelect = $true $strNamingContextDN = $global:strDomainDNName } } } } #Connect to Config Naming Context If ($rdbDSConf.IsChecked) { if ($global:bolRoot -eq $true) { $LDAPConnection = $null $request = $null $response = $null $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection("") $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("defaultnamingcontext") try { $response = $LDAPConnection.SendRequest($request) $global:strDomainDNName = $response.Entries[0].attributes.defaultnamingcontext[0] $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection) { $global:strDomainPrinDNName = $global:strDomainDNName $global:strDomainLongName = $global:strDomainDNName.Replace("DC=","") $global:strDomainLongName = $global:strDomainLongName.Replace(",",".") $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strDomainLongName ) $ojbDomain = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($Context) $global:strDC = $($ojbDomain.FindDomainController()).name $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("dnshostname") [void]$request.Attributes.Add("supportedcapabilities") [void]$request.Attributes.Add("namingcontexts") [void]$request.Attributes.Add("defaultnamingcontext") [void]$request.Attributes.Add("schemanamingcontext") [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $global:ForestRootDomainDN = $response.Entries[0].attributes.rootdomainnamingcontext[0] $global:SchemaDN = $response.Entries[0].attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].attributes.configurationnamingcontext[0] $global:strDomainDNName = $response.Entries[0].attributes.defaultnamingcontext[0] $global:IS_GC = $response.Entries[0].Attributes.isglobalcatalogready[0] } $global:DirContext = Get-DirContext $global:strDC $global:CREDS $global:strDomainShortName = GetDomainShortName $global:strDomainDNName $global:ConfigDN $global:strRootDomainShortName = GetDomainShortName $global:ForestRootDomainDN $global:ConfigDN $global:DSType = "AD DS" $global:bolADDSType = $true $lblSelectPrincipalDom.Content = $global:strDomainShortName+":" $NCSelect = $true $strNamingContextDN = $global:ConfigDN } } } #Connect to Schema Naming Context If ($rdbDSSchm.IsChecked) { if ($global:bolRoot -eq $true) { $LDAPConnection = $null $request = $null $response = $null $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection("") $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("defaultnamingcontext") try { $response = $LDAPConnection.SendRequest($request) $global:strDomainDNName = $response.Entries[0].Attributes.defaultnamingcontext[0] $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection) { $global:strDomainPrinDNName = $global:strDomainDNName $global:strDomainLongName = $global:strDomainDNName.Replace("DC=","") $global:strDomainLongName = $global:strDomainLongName.Replace(",",".") $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strDomainLongName ) $ojbDomain = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($Context) $global:strDC = $($ojbDomain.FindDomainController()).name $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($null, "(objectClass=*)", "base") [void]$request.Attributes.Add("dnshostname") [void]$request.Attributes.Add("supportedcapabilities") [void]$request.Attributes.Add("namingcontexts") [void]$request.Attributes.Add("defaultnamingcontext") [void]$request.Attributes.Add("schemanamingcontext") [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $global:ForestRootDomainDN = $response.Entries[0].attributes.rootdomainnamingcontext[0] $global:SchemaDN = $response.Entries[0].attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].attributes.configurationnamingcontext[0] $global:strDomainDNName = $response.Entries[0].attributes.defaultnamingcontext[0] $global:IS_GC = $response.Entries[0].Attributes.isglobalcatalogready[0] } $global:DirContext = Get-DirContext $global:strDC $global:CREDS $global:strDomainShortName = GetDomainShortName $global:strDomainDNName $global:ConfigDN $global:strRootDomainShortName = GetDomainShortName $global:ForestRootDomainDN $global:ConfigDN $global:DSType = "AD DS" $global:bolADDSType = $true $lblSelectPrincipalDom.Content = $global:strDomainShortName+":" $NCSelect = $true $strNamingContextDN = $global:SchemaDN } } } #Connect to Custom Naming Context If ($rdbCustomNC.IsChecked) { if (($txtBoxDomainConnect.Text.Length -gt 0) -or ($txtBdoxDSServer.Text.Length -gt 0) -or ($txtBdoxDSServerPort.Text.Length -gt 0)) { $strNamingContextDN = $txtBoxDomainConnect.Text if($txtBdoxDSServer.Text -eq "") { if($txtBdoxDSServerPort.Text -eq "") { $global:strDC = "" } else { $global:strDC = "localhost:" +$txtBdoxDSServerPort.text } } else { $global:strDC = $txtBdoxDSServer.Text +":" +$txtBdoxDSServerPort.text if($txtBdoxDSServerPort.Text -eq "") { $global:strDC = $txtBdoxDSServer.Text } else { $global:strDC = $txtBdoxDSServer.Text +":" +$txtBdoxDSServerPort.text } } $global:bolLDAPConnection = $false $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest("", "(objectClass=*)", "base") if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } [void]$request.Attributes.Add("dnshostname") [void]$request.Attributes.Add("supportedcapabilities") [void]$request.Attributes.Add("namingcontexts") [void]$request.Attributes.Add("defaultnamingcontext") [void]$request.Attributes.Add("schemanamingcontext") [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $strPrimaryCapability= $response.Entries[0].attributes.supportedcapabilities[0] Switch ($strPrimaryCapability) { "1.2.840.113556.1.4.1851" { $global:DSType = "AD LDS" $global:bolADDSType = $false $global:strDomainDNName = $response.Entries[0].Attributes.namingcontexts[-1] $global:SchemaDN = $response.Entries[0].Attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].Attributes.configurationnamingcontext[0] if($txtBdoxDSServerPort.Text -eq "") { if(Test-ResolveDNS $response.Entries[0].Attributes.dnshostname[0]) { $global:strDC = $response.Entries[0].Attributes.dnshostname[0] } } else { if(Test-ResolveDNS $response.Entries[0].Attributes.dnshostname[0]) { $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text } } } "1.2.840.113556.1.4.800" { $global:DSType = "AD DS" $global:bolADDSType = $true $global:ForestRootDomainDN = $response.Entries[0].Attributes.rootdomainnamingcontext[0] $global:strDomainDNName = $response.Entries[0].Attributes.defaultnamingcontext[0] $global:SchemaDN = $response.Entries[0].Attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].Attributes.configurationnamingcontext[0] $global:IS_GC = $response.Entries[0].Attributes.isglobalcatalogready[0] if($txtBdoxDSServerPort.Text -eq "") { if(Test-ResolveDNS $response.Entries[0].Attributes.dnshostname[0]) { $global:strDC = $response.Entries[0].Attributes.dnshostname[0] } } else { if(Test-ResolveDNS $response.Entries[0].Attributes.dnshostname[0]) { $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text } } $global:strDomainPrinDNName = $global:strDomainDNName $global:strDomainShortName = GetDomainShortName $global:strDomainDNName $global:ConfigDN $global:strRootDomainShortName = GetDomainShortName $global:ForestRootDomainDN $global:ConfigDN $lblSelectPrincipalDom.Content = $global:strDomainShortName+":" } default { $global:ForestRootDomainDN = $response.Entries[0].Attributes.rootdomainnamingcontext[0] $global:strDomainDNName = $response.Entries[0].Attributes.defaultnamingcontext[0] $global:SchemaDN = $response.Entries[0].Attributes.schemanamingcontext[0] $global:ConfigDN = $response.Entries[0].Attributes.configurationnamingcontext[0] $global:IS_GC = $response.Entries[0].Attributes.isglobalcatalogready[0] if($txtBdoxDSServerPort.Text -eq "") { $global:strDC = $response.Entries[0].Attributes.dnshostname[0] } else { $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text } } } if($strNamingContextDN -eq "") { $strNamingContextDN = $global:strDomainDNName } If(CheckDNExist $strNamingContextDN $global:strDC) { $NCSelect = $true } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) $global:bolConnected = $false } }#bolLDAPConnection } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! No naming context or server specified!" -strType "Error" -DateStamp )) $global:bolConnected = $false } } If ($NCSelect -eq $true) { If (!($strLastCacheGuidsDom -eq $global:strDomainDNName)) { $global:dicRightsGuids = @{"Seed" = "xxx"} CacheRightsGuids $strLastCacheGuidsDom = $global:strDomainDNName } #Check Directory Service type $global:DSType = "" $global:bolADDSType = $false $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest("", "(objectClass=*)", "base") $response = $LDAPConnection.SendRequest($request) $strPrimaryCapability= $response.Entries[0].attributes.supportedcapabilities[0] Switch ($strPrimaryCapability) { "1.2.840.113556.1.4.1851" { $global:DSType = "AD LDS" } "1.2.840.113556.1.4.800" { $global:DSType = "AD DS" $global:bolADDSType = $true } default { $global:DSType = "Unknown" } } $global:observableCollection.Insert(0,(LogMessage -strMessage "Connected to directory service $global:DSType" -strType "Info" -DateStamp )) #Plaing with AD LDS Locally $global:TreeViewRootPath = $strNamingContextDN $xml = Get-XMLDomainOUTree $global:TreeViewRootPath # Change XML Document, XPath and Refresh $xmlprov.Document = $xml $xmlProv.XPath = "/DomainRoot" $xmlProv.Refresh() $global:bolConnected = $true If (!(Test-Path ($env:temp + "\OU.png"))) { $IconFilePath = $env:temp + "\OU.png" $bytes = [Convert]::FromBase64String($OUpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\Expand.png"))) { $IconFilePath = $env:temp + "\Expand.png" $bytes = [Convert]::FromBase64String($Expandpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\User.png"))) { $IconFilePath = $env:temp + "\User.png" $bytes = [Convert]::FromBase64String($Userpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\Group.png"))) { $IconFilePath = $env:temp + "\Group.png" $bytes = [Convert]::FromBase64String($Grouppng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\Computer.png"))) { $IconFilePath = $env:temp + "\Computer.png" $bytes = [Convert]::FromBase64String($Computerpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\Container.png"))) { $IconFilePath = $env:temp + "\Container.png" $bytes = [Convert]::FromBase64String($Containerpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\DomainDNS.png"))) { $IconFilePath = $env:temp + "\DomainDNS.png" $bytes = [Convert]::FromBase64String($DomainDNSpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\Other.png"))) { $IconFilePath = $env:temp + "\Other.png" $bytes = [Convert]::FromBase64String($Otherpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\refresh.png"))) { $IconFilePath = $env:temp + "\refresh.png" $bytes = [Convert]::FromBase64String($refreshpng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } If (!(Test-Path ($env:temp + "\exclude.png"))) { $IconFilePath = $env:temp + "\exclude.png" $bytes = [Convert]::FromBase64String($excludepng) [IO.File]::WriteAllBytes($IconFilePath, $bytes) } #Test PS Version DeleteCommand requries PS 3.0 and above if ($PSVersionTable.PSVersion -gt "2.0") { $TreeView1.ContextMenu.Items[0].Command = New-Object DelegateCommand( { Add-RefreshChild } ) $TreeView1.ContextMenu.Items[1].Command = New-Object DelegateCommand( { Add-ExcludeChild } ) } else { Write-Error "Requries PS 3.0 and above" break } #Update Connection Info $txtDC.text = $global:strDC $txtdefaultnamingcontext.text = $global:strDomainDNName $txtconfigurationnamingcontext.text = $global:ConfigDN $txtschemanamingcontext.text = $global:SchemaDN $txtrootdomainnamingcontext.text = $global:ForestRootDomainDN }#End If NCSelect #Get Forest Root Domain ObjectSID if ($global:DSType -eq "AD DS") { $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($global:strDomainDNName, "(objectClass=*)", "base") [void]$request.Attributes.Add("objectsid") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $global:DomainSID = GetSidStringFromSidByte $response.Entries[0].attributes.objectsid.GetValues([byte[]])[0] } if($global:ForestRootDomainDN -ne $global:strDomainDNName) { $global:strForestDomainLongName = $global:ForestRootDomainDN.Replace("DC=","") $global:strForestDomainLongName = $global:strForestDomainLongName.Replace(",",".") if($global:CREDS.UserName) { $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strForestDomainLongName,$global:CREDS.UserName,$global:CREDS.GetNetworkCredential().Password) } else { $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strForestDomainLongName) } $ojbDomain = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($Context) $global:strForestDC = $($ojbDomain.FindDomainController()).name $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strForestDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest($global:ForestRootDomainDN, "(objectClass=*)", "base") [void]$request.Attributes.Add("objectsid") try { $response = $LDAPConnection.SendRequest($request) $global:bolLDAPConnection = $true } catch { $global:bolLDAPConnection = $false $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) } if($global:bolLDAPConnection -eq $true) { $global:ForestRootDomainSID = GetSidStringFromSidByte $response.Entries[0].attributes.objectsid.GetValues([byte[]])[0] } } else { $global:strForestDC = $global:strDC $global:ForestRootDomainSID = $global:DomainSID } } }) $chkBoxCreds.add_UnChecked({ $global:CREDS = $null }) $btnScan.add_Click( { $UseCanonicalName = $chkBoxUseCanonicalName.IsChecked $Protected = $chkBoxGetOUProtected.IsChecked If($chkBoxCompare.IsChecked) { RunCompare } else { RunScan } }) $btnCreateHTML.add_Click( { if ($txtCSVImport.Text -eq "") { $global:observableCollection.Insert(0,(LogMessage -strMessage "No Template CSV file selected!" -strType "Error" -DateStamp )) } else { #if ($global:bolConnected -eq $true) #{ ConvertCSVtoHTM $txtCSVImport.Text $chkBoxTranslateGUIDinCSV.isChecked #} #else #{ #$global:observableCollection.Insert(0,(LogMessage -strMessage "You need to connect to a directory first!" -strType "Error" -DateStamp )) #} } }) $btnSupport.add_Click( { GenerateSupportStatement }) $btnExit.add_Click( { #TODO: Place custom script here #$ErrorActionPreference = "SilentlyContinue" $bolConnected= $null $bolTempValue_InhertiedChkBox= $null $dicDCSpecialSids= $null $dicNameToSchemaIDGUIDs= $null $dicRightsGuids= $null $dicSchemaIDGUIDs= $null $dicSidToName= $null $dicWellKnownSids= $null $myPID= $null $observableCollection= $null $strDomainPrinDNName= $null $strDommainSelect= $null $strEffectiveRightAccount= $null $strEffectiveRightSP= $null $strPinDomDC= $null $strPrincipalDN= $null $strPrinDomAttr= $null $strPrinDomDir= $null $strPrinDomFlat= $null $strSPNobjectClass= $null $tokens= $null $strDC = $null $strDomainDNName = $null $strDomainLongName = $null $strDomainShortName = $null $strOwner = $null remove-variable -name "bolConnected" -Scope Global remove-variable -name "bolTempValue_InhertiedChkBox" -Scope Global remove-variable -name "dicDCSpecialSids" -Scope Global remove-variable -name "dicNameToSchemaIDGUIDs" -Scope Global remove-variable -name "dicRightsGuids" -Scope Global remove-variable -name "dicSchemaIDGUIDs" -Scope Global remove-variable -name "dicSidToName" -Scope Global remove-variable -name "dicWellKnownSids" -Scope Global remove-variable -name "myPID" -Scope Global remove-variable -name "observableCollection" -Scope Global remove-variable -name "strDomainPrinDNName" -Scope Global remove-variable -name "strDommainSelect" -Scope Global remove-variable -name "strEffectiveRightAccount" -Scope Global remove-variable -name "strEffectiveRightSP" -Scope Global remove-variable -name "strPinDomDC" -Scope Global remove-variable -name "strPrincipalDN" -Scope Global remove-variable -name "strPrinDomAttr" -Scope Global remove-variable -name "strPrinDomDir" -Scope Global remove-variable -name "strPrinDomFlat" -Scope Global remove-variable -name "strSPNobjectClass" -Scope Global remove-variable -name "tokens" -Scope Global $ErrorActionPreference = "SilentlyContinue" &{#Try $xmlDoc = $null remove-variable -name "xmlDoc" -Scope Global } Trap [SystemException] { SilentlyContinue } $ErrorActionPreference = "Continue" $Window.close() }) $btnGetObjFullFilter.add_Click( { if ($global:bolConnected -eq $true) { GetSchemaObjectGUID -Domain $global:strDomainDNName $global:observableCollection.Insert(0,(LogMessage -strMessage "All schema objects and attributes listed!" -strType "Info" -DateStamp )) } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) } }) foreach ($ldapDisplayName in $global:dicSchemaIDGUIDs.values) { [void]$combObjectFilter.Items.Add($ldapDisplayName) } $treeView1.add_SelectedItemChanged({ $txtBoxSelected.Text = (Get-XMLPath -xmlElement ($this.SelectedItem)) if ($this.SelectedItem.Tag -eq "NotEnumerated") { $xmlNode = $global:xmlDoc $NodeDNPath = $($this.SelectedItem.ParentNode.Text.toString()) [void]$this.SelectedItem.ParentNode.removeChild($this.SelectedItem); $Mynodes = $xmlNode.SelectNodes("//OU[@Text='$NodeDNPath']") $treeNodePath = $NodeDNPath # Initialize and Build Domain OU Tree ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath #-nodeCount 0 # Set tag to show this node is already enumerated $this.SelectedItem.Tag = "Enumerated" } }) }#### End of if $base , check if UI should be loaded <###################################################################### Functions to Build Domains OU Tree XML Document ######################################################################> #region function RunCompare { if($chkBoxSeverity.isChecked -or $chkBoxEffectiveRightsColor.isChecked) { $bolShowCriticalityColor = $true } else { $bolShowCriticalityColor = $false } If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) { #If the DC string is changed during the compre ti will be restored to it's orgi value $global:ResetDCvalue = "" $global:ResetDCvalue = $global:strDC $allSubOU = New-Object System.Collections.ArrayList $allSubOU.Clear() if ($txtCompareTemplate.Text -eq "") { $global:observableCollection.Insert(0,(LogMessage -strMessage "No Template CSV file selected!" -strType "Error" -DateStamp )) } else { if ($(Test-Path $txtCompareTemplate.Text) -eq $true) { if (($chkBoxEffectiveRights.isChecked -eq $true) -or ($chkBoxFilter.isChecked -eq $true)) { if ($chkBoxEffectiveRights.isChecked) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Can't compare while Effective Rights enabled!" -strType "Error" -DateStamp )) } if ($chkBoxFilter.isChecked) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Can't compare while Filter enabled!" -strType "Error" -DateStamp )) } } else { $global:bolCSVLoaded = $false $strCompareFile = $txtCompareTemplate.Text &{#Try $global:bolCSVLoaded = $true $global:csvHistACLs = import-Csv $strCompareFile } Trap [SystemException] { $strCSVErr = $_.Exception.Message $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed to load CSV. $strCSVErr" -strType "Error" -DateStamp )) $global:bolCSVLoaded = $false continue } #Verify that a successful CSV import is performed before continue if($global:bolCSVLoaded) { #Test CSV file format if(TestCSVColumns $global:csvHistACLs) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Scanning..." -strType "Info" -DateStamp )) $BolSkipDefPerm = $chkBoxDefaultPerm.IsChecked $BolSkipProtectedPerm = $chkBoxSkipProtectedPerm.IsChecked $global:bolProgressBar = $chkBoxSkipProgressBar.IsChecked $bolCSV = $rdbOnlyCSV.IsChecked if ($chkBoxTemplateNodes.IsChecked -eq $false) { $sADobjectName = $txtBoxSelected.Text.ToString() $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC,$global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } $request.DistinguishedName = $sADobjectName $request.Filter = "(name=*)" $request.Scope = "Base" [void]$request.Attributes.Add("name") $response = $LDAPConnection.SendRequest($request) $ADobject = $response.Entries[0] if($null -ne $ADobject.Attributes.name) { $strNode = fixfilename $ADobject.attributes.name[0] } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Could not read object $($txtBoxSelected.Text.ToString()). Enough permissions?" -strType "Error" -DateStamp )) } } else { #Set the bolean to true so connection will be performed unless an error occur $bolContinue = $true if($global:csvHistACLs[0].Object) { $strOUcol = $global:csvHistACLs[0].Object } else { $strOUcol = $global:csvHistACLs[0].OU } if($strOUcol.Contains("") -gt 0) { $strOUcol = ($strOUcol -Replace "",$global:strDomainDNName) } if($strOUcol.Contains("") -gt 0) { $strOUcol = ($strOUcol -Replace "",$global:ForestRootDomainDN) if($global:strDomainDNName -ne $global:ForestRootDomainDN) { if($global:IS_GC -eq "TRUE") { $MsgBox = [System.Windows.Forms.MessageBox]::Show("You are not connected to the forest root domain: $global:ForestRootDomainDN.`n`nYour DC is a Global Catalog.`nDo you want to use Global Catalog and continue?",”Information”,3,"Warning") if($MsgBox -eq "Yes") { if($global:strDC.contains(":")) { $global:strDC = $global:strDC.split(":")[0] + ":3268" } else { $global:strDC = $global:strDC + ":3268" } } else { $bolContinue = $false } } else { $MsgBox = [System.Windows.Forms.MessageBox]::Show("You are not connected to the forest root domain: $global:ForestRootDomainDN.",”Information”,0,"Warning") $bolContinue = $false } } } if($txtReplaceDN.text.Length -gt 0) { $strOUcol = ($strOUcol -Replace $txtReplaceDN.text,$global:strDomainDNName) } $sADobjectName = $strOUcol #Verify if the connection can be done if($bolContinue) { $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC,$global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } $request.DistinguishedName = $sADobjectName $request.Filter = "(name=*)" $request.Scope = "Base" [void]$request.Attributes.Add("name") $response = $LDAPConnection.SendRequest($request) $ADobject = $response.Entries[0] $strNode = fixfilename $ADobject.attributes.name[0] } else { #Set the node to empty , no connection will be done $strNode = "" } } #if not is empty continue if($strNode -ne "") { $bolTranslateGUIDStoObject = $false $date= get-date -uformat %Y%m%d_%H%M%S $strNode = fixfilename $strNode $strFileCSV = $txtTempFolder.Text + "\" +$strNode + "_" + $global:strDomainShortName + "_adAclOutput" + $date +".csv" $strFileEXCEL = $txtTempFolder.Text + "\" +$strNode + "_" + $global:strDomainShortName + "_adAclOutput" + $date +".xlsx" $strFileHTA = $env:temp + "\"+$global:ACLHTMLFileName+".hta" $strFileHTM = $env:temp + "\"+"$global:strDomainShortName-$strNode-$global:SessionID"+".htm" if(!($bolCSV)) { if(!($rdbEXcel.IsChecked)) { if ($chkBoxFilter.IsChecked) { CreateHTA "$global:strDomainShortName-$strNode Filtered" $strFileHTA $strFileHTM $CurrentFSPath $global:strDomainDNName $global:strDC CreateHTM "$global:strDomainShortName-$strNode Filtered" $strFileHTM } else { CreateHTA "$global:strDomainShortName-$strNode" $strFileHTA $strFileHTM $CurrentFSPath $global:strDomainDNName $global:strDC CreateHTM "$global:strDomainShortName-$strNode" $strFileHTM } InitiateHTM $strFileHTA $strNode $txtBoxSelected.Text.ToString() $chkBoxReplMeta.IsChecked $chkBoxACLsize.IsChecked $Protected $bolShowCriticalityColor $true $BolSkipDefPerm $BolSkipProtectedPerm $strCompareFile $chkBoxFilter.isChecked $chkBoxEffectiveRights.isChecked $chkBoxObjType.isChecked -bolCanonical:$UseCanonicalName $GPO InitiateHTM $strFileHTM $strNode $txtBoxSelected.Text.ToString() $chkBoxReplMeta.IsChecked $chkBoxACLsize.IsChecked $Protected $bolShowCriticalityColor $true $BolSkipDefPerm $BolSkipProtectedPerm $strCompareFile $chkBoxFilter.isChecked $chkBoxEffectiveRights.isChecked $chkBoxObjType.isChecked -bolCanonical:$UseCanonicalName $GPO $Format = "HTML" $Show = $true } else { $Format = "EXCEL" $Show = $false } } else { $Format = "CSV" $Show = $false } If (($txtBoxSelected.Text.ToString().Length -gt 0) -or (($chkBoxTemplateNodes.IsChecked -eq $true))) { #Select type of scope If ($rdbBase.IsChecked -eq $False) { If ($rdbSubtree.IsChecked -eq $true) { $allSubOU = GetAllChildNodes $txtBoxSelected.Text "subtree" } else { $allSubOU = GetAllChildNodes $txtBoxSelected.Text "onelevel" } } else { $allSubOU = @($txtBoxSelected.Text) } #if any objects found compare ACLs if($allSubOU.count -gt 0) { $Returns = $combReturns.SelectedItem $bolToFile = $true #Used from comand line only $FilterBuiltin = $false Get-PermCompare $allSubOU $BolSkipDefPerm $BolSkipProtectedPerm $chkBoxReplMeta.IsChecked $chkBoxGetOwner.IsChecked $bolCSV $Protected $chkBoxACLsize.IsChecked $bolTranslateGUIDStoObject $Show $Format $Returns $bolToFile $bolShowCriticalityColor $chkBoxSeverity.IsChecked $combServerity.SelectedItem $FilterBuiltin $chkBoxTranslateGUID.isChecked } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "No objects returned!" -strType "Error" -DateStamp )) } $global:observableCollection.Insert(0,(LogMessage -strMessage "Finished" -strType "Info" -DateStamp )) }# End If txtBoxSelected or chkBoxTemplateNodes } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Could not connect to $sADobjectName" -strType "Error" -DateStamp )) }#End if not is empty }#else if test column names exist else { $global:observableCollection.Insert(0,(LogMessage -strMessage "CSV file got wrong format! File: $strCompareFile" -strType "Error" -DateStamp )) } #End if test column names exist } # End If Verify that a successful CSV import is performed before continue }#End If $chkBoxEffectiveRights.isChecked -or $chkBoxFilter.isChecked }#End If Test-Path else { $global:observableCollection.Insert(0,(LogMessage -strMessage "CSV file not found!" -strType "Error" -DateStamp )) }#End If Test-Path Else }# End If #Restore the DC string to its original $global:strDC = $global:ResetDCvalue } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "No object selected!" -strType "Error" -DateStamp )) } $allSubOU = "" $strFileCSV = "" $strFileHTA = "" $strFileHTM = "" $sADobjectName = "" $date= "" } function RunScan { if($rdbGPO.isChecked) { $GPO = $true } if($chkBoxSeverity.isChecked -or $chkBoxEffectiveRightsColor.isChecked) { $bolShowCriticalityColor = $true } else { $bolShowCriticalityColor = $false } $bolPreChecks = $true If ($txtBoxSelected.Text) { If(($chkBoxFilter.IsChecked -eq $true) -and (($chkBoxType.IsChecked -eq $false) -and ($chkBoxObject.IsChecked -eq $false) -and ($chkBoxTrustee.IsChecked -eq $false) -and ($chkBoxFilterBuiltin.IsChecked -eq $false))) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Filter Enabled , but no filter is specified!" -strType "Error" -DateStamp )) $bolPreChecks = $false } else { If(($chkBoxFilter.IsChecked -eq $true) -and (($combAccessCtrl.SelectedIndex -eq -1) -and ($combObjectFilter.SelectedIndex -eq -1) -and ($txtFilterTrustee.Text -eq "") -and ($chkBoxFilterBuiltin.IsChecked -eq $false))) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Filter Enabled , but no filter is specified!" -strType "Error" -DateStamp )) $bolPreChecks = $false } } If(($chkBoxEffectiveRights.IsChecked -eq $true) -and ($global:tokens.count -eq 0)) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Effective rights enabled , but no service principal selected!" -strType "Error" -DateStamp )) $bolPreChecks = $false } $global:intShowCriticalityLevel = 0 if ($bolPreChecks -eq $true) { $strCompareFile = "" $allSubOU = New-Object System.Collections.ArrayList $allSubOU.Clear() $global:observableCollection.Insert(0,(LogMessage -strMessage "Scanning..." -strType "Info" -DateStamp )) $BolSkipDefPerm = $chkBoxDefaultPerm.IsChecked $BolSkipProtectedPerm = $chkBoxSkipProtectedPerm.IsChecked $global:bolProgressBar = $chkBoxSkipProgressBar.IsChecked $bolCSV = $rdbOnlyCSV.IsChecked $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC,$global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } $request.DistinguishedName = $txtBoxSelected.Text.ToString() $request.Filter = "(name=*)" $request.Scope = "Base" [void]$request.Attributes.Add("name") $response = $LDAPConnection.SendRequest($request) $ADobject = $response.Entries[0] #Verify that attributes can be read if($null -ne $ADobject.distinguishedName) { if($null -ne $ADobject.Attributes.name) { $strNode = $ADobject.Attributes.name[0] } else { $strNode = $ADobject.distinguishedName } if($GPO) { $strNode = $strNode + "_GPOs" } $bolTranslateGUIDStoObject = $false $date= get-date -uformat %Y%m%d_%H%M%S $strNode = fixfilename $strNode $strFileCSV = $txtTempFolder.Text + "\" +$strNode + "_" + $global:strDomainShortName + "_adAclOutput" + $date +".csv" $strFileEXCEL = $txtTempFolder.Text + "\" +$strNode + "_" + $global:strDomainShortName + "_adAclOutput" + $date +".xlsx" $strFileHTA = $env:temp + "\"+$global:ACLHTMLFileName+".hta" $strFileHTM = $env:temp + "\"+"$global:strDomainShortName-$strNode-$global:SessionID"+".htm" if(!($bolCSV)) { if(!($rdbEXcel.IsChecked)) { if ($chkBoxFilter.IsChecked) { CreateHTA "$global:strDomainShortName-$strNode Filtered" $strFileHTA $strFileHTM $CurrentFSPath $global:strDomainDNName $global:strDC CreateHTM "$global:strDomainShortName-$strNode Filtered" $strFileHTM } else { CreateHTA "$global:strDomainShortName-$strNode" $strFileHTA $strFileHTM $CurrentFSPath $global:strDomainDNName $global:strDC CreateHTM "$global:strDomainShortName-$strNode" $strFileHTM } InitiateHTM $strFileHTA $strNode $txtBoxSelected.Text.ToString() $chkBoxReplMeta.IsChecked $chkBoxACLsize.IsChecked $Protected $bolShowCriticalityColor $false $BolSkipDefPerm $BolSkipProtectedPerm $strCompareFile $chkBoxFilter.isChecked $chkBoxEffectiveRights.isChecked $chkBoxObjType.isChecked -bolCanonical:$UseCanonicalName $GPO InitiateHTM $strFileHTM $strNode $txtBoxSelected.Text.ToString() $chkBoxReplMeta.IsChecked $chkBoxACLsize.IsChecked $Protected $bolShowCriticalityColor $false $BolSkipDefPerm $BolSkipProtectedPerm $strCompareFile $chkBoxFilter.isChecked $chkBoxEffectiveRights.isChecked $chkBoxObjType.isChecked -bolCanonical:$UseCanonicalName $GPO $Format = "HTML" $Show = $true } else { $Format = "EXCEL" $Show = $false } } else { $Format = "CSV" $Show = $false } If ($txtBoxSelected.Text.ToString().Length -gt 0) { #Select type of scope If ($rdbBase.IsChecked -eq $true) { $Scope = "base" } If ($rdbOneLevel.IsChecked -eq $true) { $Scope = "onelevel" } If ($rdbSubtree.IsChecked -eq $true) { $Scope = "subtree" } $IncludeInherited = $chkInheritedPerm.IsChecked $allSubOU = GetAllChildNodes $txtBoxSelected.Text $Scope #if any objects found read ACLs if($allSubOU.count -gt 0) { $bolToFile = $true #Used from comand line only $FilterBuiltin = $false Get-Perm $allSubOU $global:strDomainShortName $IncludeInherited $BolSkipDefPerm $BolSkipProtectedPerm $chkBoxFilter.IsChecked $chkBoxGetOwner.IsChecked $chkBoxReplMeta.IsChecked $chkBoxACLsize.IsChecked $chkBoxEffectiveRights.IsChecked $Protected $bolTranslateGUIDStoObject $Show $Format $bolToFile $chkBoxSeverity.IsChecked $combServerity.SelectedItem $bolShowCriticalityColor $GPO $FilterBuiltin $chkBoxTranslateGUID.isChecked $chkBoxRecursiveFind.isChecked $combRecursiveFind.SelectedValue } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "No objects returned! Does your filter relfect the objects you are searching for?" -strType "Error" -DateStamp )) } } } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Could not read object $($txtBoxSelected.Text.ToString()). Enough permissions?" -strType "Error" -DateStamp )) } } } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "No object selected!" -strType "Error" -DateStamp )) } $global:observableCollection.Insert(0,(LogMessage -strMessage "Finished" -strType "Info" -DateStamp )) $allSubOU = "" $strFileCSV = "" $strFileHTA = "" $strFileHTM = "" $sADobjectName = "" $date= "" } function Get-XMLPath { Param($xmlElement) $Path = "" $FQDN = $xmlElement.Text return $FQDN } function AddXMLAttribute { Param([ref]$node, $szName, $value) $attribute = $global:xmlDoc.createAttribute($szName); [void]$node.value.setAttributeNode($attribute); $node.value.setAttribute($szName, $value); #return $node; } function Add-ExcludeChild { # Test if any node is selected if($txtBoxSelected.Text.Length -gt 0) { if($txtBoxExcluded.Text.Length -gt 0) { $txtBoxExcluded.Text = $txtBoxExcluded.Text + ";" + $txtBoxSelected.Text } else { $txtBoxExcluded.Text = $txtBoxSelected.Text } } } function Add-RefreshChild { # Test if any node is selected if($txtBoxSelected.Text.Length -gt 0) { $xmlNode = $global:xmlDoc $NodeDNPath = $txtBoxSelected.Text if($global:TreeViewRootPath -eq $NodeDNPath) { $Mynodes = $xmlNode.SelectSingleNode("//DomainRoot[@Text='$NodeDNPath']") # Make sure a node was found if($Mynodes.Name.Length -gt 0) { $Mynodes.IsEmpty = $true $treeNodePath = $NodeDNPath # Initialize and Build Domain OU Tree ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath #-nodeCount 0 # Set tag to show this node is already enumerated } } else { $Mynodes = $xmlNode.SelectSingleNode("//OU[@Text='$NodeDNPath']") # Make sure a node was found if($Mynodes.Name.Length -gt 0) { $Mynodes.IsEmpty = $true $treeNodePath = $NodeDNPath # Initialize and Build Domain OU Tree ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath #-nodeCount 0 # Set tag to show this node is already enumerated } } } } # Processes an OU tree function ProcessOUTree { Param($node, $ADSObject) # Increment the node count to indicate we are done with the domain level $strFilterOUCont = "(&(|(objectClass=organizationalUnit)(objectClass=container)(objectClass=domainDNS)))" $strFilterAll = "(objectClass=*)" $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest [System.DirectoryServices.Protocols.PageResultRequestControl]$pagedRqc = new-object System.DirectoryServices.Protocols.PageResultRequestControl($global:PageSize) $request.Controls.Add($pagedRqc) | Out-Null if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } $request.DistinguishedName = $ADSObject # Single line Directory searcher # set a filter If ($rdbBrowseAll.IsChecked -eq $true) { $request.Filter = $strFilterAll } else { $request.Filter = $strFilterOUCont } # set search scope $request.Scope = "OneLevel" [void]$request.Attributes.Add("name") [void]$request.Attributes.Add("objectclass") # Now walk the list and recursively process each child while ($true) { $response = $LdapConnection.SendRequest($request, (new-object System.Timespan(0,0,$global:TimeoutSeconds))) -as [System.DirectoryServices.Protocols.SearchResponse]; #for paged search, the response for paged search result control - we will need a cookie from result later if($global:PageSize -gt 0) { [System.DirectoryServices.Protocols.PageResultResponseControl] $prrc=$null; if ($response.Controls.Length -gt 0) { foreach ($ctrl in $response.Controls) { if ($ctrl -is [System.DirectoryServices.Protocols.PageResultResponseControl]) { $prrc = $ctrl; break; } } } if($null -eq $prrc) { #server was unable to process paged search throw "Find-LdapObject: Server failed to return paged response for request $SearchFilter" } } #now process the returned list of distinguishedNames and fetch required properties using ranged retrieval $colResults = $response.Entries foreach ($objResult in $colResults) { if ($objResult.attributes.Count -ne 0) { $NewOUNode = $global:xmlDoc.createElement("OU"); # Add an Attribute for the Name if (($null -ne $($objResult.attributes.name[0]))) { # Add an Attribute for the Name $OUName = "$($objResult.attributes.name[0])" AddXMLAttribute -node ([ref]$NewOUNode) -szName "Name" -value $OUName $DNName = $objResult.distinguishedname AddXMLAttribute -node ([ref]$NewOUNode) -szName "Text" -value $DNName Switch ($objResult.attributes.objectclass[$objResult.attributes.objectclass.count-1]) { "domainDNS" { AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\DomainDNS.png" } "OrganizationalUnit" { AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\OU.png" } "user" { AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\User.png" } "group" { AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\Group.png" } "computer" { AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\Computer.png" } "container" { AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\Container.png" } default { AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\Other.png" } } AddXMLAttribute -node ([ref]$NewOUNode) -szName "Tag" -value "Enumerated" $child = $node.appendChild($NewOUNode); ProcessOUTreeStep2OnlyShow -node $NewOUNode -DNName $DNName } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Could not read object $($objResult.distinguishedname)" -strType "Error" -DateStamp )) } } else { if ($null -ne $objResult.distinguishedname) { # Add an Attribute for the Name $DNName = $objResult.distinguishedname $OUName = $DNName.toString().Split(",")[0] if($OUName -match "=") { $OUName = $OUName.Split("=")[1] } AddXMLAttribute -node ([ref]$NewOUNode) -szName "Name" -value $OUName AddXMLAttribute -node ([ref]$NewOUNode) -szName "Text" -value $DNName AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\Container.png" AddXMLAttribute -node ([ref]$NewOUNode) -szName "Tag" -value "Enumerated" $child = $node.appendChild($NewOUNode); ProcessOUTreeStep2OnlyShow -node $NewOUNode -DNName $DNName } $global:observableCollection.Insert(0,(LogMessage -strMessage "Could not read object $($objResult.distinguishedname). Enough permissions?" -strType "Warning" -DateStamp )) } } if($global:PageSize -gt 0) { if ($prrc.Cookie.Length -eq 0) { #last page --> we're done break; } #pass the search cookie back to server in next paged request $pagedRqc.Cookie = $prrc.Cookie; } else { #exit the processing for non-paged search break; } } } function ProcessOUTreeStep2OnlyShow { Param($node, $DNName) # Increment the node count to indicate we are done with the domain level $strFilterOUCont = "(&(|(objectClass=organizationalUnit)(objectClass=container)(objectClass=domainDNS)))" $strFilterAll = "(&(name=*))" $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" #$request = New-Object System.directoryServices.Protocols.SearchRequest("$global:SchemaDN", "(objectClass=classSchema)", "Subtree") $request = New-Object System.directoryServices.Protocols.SearchRequest $request.distinguishedName = $DNName [System.DirectoryServices.Protocols.PageResultRequestControl]$pagedRqc = new-object System.DirectoryServices.Protocols.PageResultRequestControl($global:PageSize) $request.Controls.Add($pagedRqc) | Out-Null if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } # Single line Directory searcher # set a filter If ($rdbBrowseAll.IsChecked -eq $true) { $request.Filter = $strFilterAll } else { $request.Filter = $strFilterOUCont } # set search scope $request.Scope = "oneLevel" [void]$request.Attributes.Add("name") $arrSchemaObjects = New-Object System.Collections.ArrayList $intStop = 0 while ($true) { $response = $LdapConnection.SendRequest($request, (new-object System.Timespan(0,0,$global:TimeoutSeconds))) -as [System.DirectoryServices.Protocols.SearchResponse]; #for paged search, the response for paged search result control - we will need a cookie from result later if($global:PageSize -gt 0) { [System.DirectoryServices.Protocols.PageResultResponseControl] $prrc=$null; if ($response.Controls.Length -gt 0) { foreach ($ctrl in $response.Controls) { if ($ctrl -is [System.DirectoryServices.Protocols.PageResultResponseControl]) { $prrc = $ctrl; break; } } } if($null -eq $prrc) { #server was unable to process paged search throw "Find-LdapObject: Server failed to return paged response for request $SearchFilter" } } #now process the returned list of distinguishedNames and fetch required properties using ranged retrieval $colResults = $response.Entries foreach ($objResult in $colResults) { if($intStop -eq 0) { $global:DirSrchResults = $objResult if ($null -ne $global:DirSrchResults.attributes) { # Add an Attribute for the Name $NewOUNode = $global:xmlDoc.createElement("OU"); # Add an Attribute for the Name AddXMLAttribute -node ([ref]$NewOUNode) -szName "Name" -value "Click ..." AddXMLAttribute -node ([ref]$NewOUNode) -szName "Text" -value "Click ..." AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\Expand.png" AddXMLAttribute -node ([ref]$NewOUNode) -szName "Tag" -value "NotEnumerated" [void]$node.appendChild($NewOUNode); } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "At least one child object could not be accessed: $DNName" -strType "Warning" -DateStamp )) # Add an Attribute for the Name $NewOUNode = $global:xmlDoc.createElement("OU"); # Add an Attribute for the Name AddXMLAttribute -node ([ref]$NewOUNode) -szName "Name" -value "Click ..." AddXMLAttribute -node ([ref]$NewOUNode) -szName "Text" -value "Click ..." AddXMLAttribute -node ([ref]$NewOUNode) -szName "Img" -value "$env:temp\Expand.png" AddXMLAttribute -node ([ref]$NewOUNode) -szName "Tag" -value "NotEnumerated" [void]$node.appendChild($NewOUNode); } } $intStop++ } if($global:PageSize -gt 0) { if ($prrc.Cookie.Length -eq 0) { #last page --> we're done break; } #pass the search cookie back to server in next paged request $pagedRqc.Cookie = $prrc.Cookie; } else { #exit the processing for non-paged search break; } }#End While } function Get-XMLDomainOUTree { param ( $szDomainRoot ) $treeNodePath = $szDomainRoot # Initialize and Build Domain OU Tree $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $global:CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } $request.distinguishedName = $treeNodePath $request.filter = "(name=*)" $request.Scope = "base" [void]$request.Attributes.Add("name") [void]$request.Attributes.Add("objectclass") $response = $LDAPConnection.SendRequest($request) $DomainRoot = $response.Entries[0] if($DomainRoot.attributes.count -ne 0) { $DNName = $DomainRoot.distinguishedname if($null -ne $DomainRoot.Attributes.objectclass) { $strObClass = $DomainRoot.Attributes.objectclass[$DomainRoot.Attributes.objectclass.count-1] } else { $strObClass = "unknown" } } else { $DNName = $DomainRoot.distinguishedname $strObClass = "container" $global:observableCollection.Insert(0,(LogMessage -strMessage "Could not read object $DNName . Enough permissions?" -strType "Error" -DateStamp )) } $global:xmlDoc = New-Object -TypeName System.Xml.XmlDocument $global:xmlDoc.PreserveWhitespace = $false $RootNode = $global:xmlDoc.createElement("DomainRoot") AddXMLAttribute -Node ([ref]$RootNode) -szName "Name" -value $szDomainRoot AddXMLAttribute -node ([ref]$RootNode) -szName "Text" -value $DNName AddXMLAttribute -node ([ref]$RootNode) -szName "Icon" -value "$env:temp\refresh.png" AddXMLAttribute -node ([ref]$RootNode) -szName "Icon2" -value "$env:temp\exclude.png" Switch ($strObClass) { "domainDNS" { AddXMLAttribute -node ([ref]$RootNode) -szName "Img" -value "$env:temp\DomainDNS.png" } "OrganizationalUnit" { AddXMLAttribute -node ([ref]$RootNode) -szName "Img" -value "$env:temp\OU.png" } "user" { AddXMLAttribute -node ([ref]$RootNode) -szName "Img" -value "$env:temp\User.png" } "group" { AddXMLAttribute -node ([ref]$RootNode) -szName "Img" -value "$env:temp\Group.png" } "computer" { AddXMLAttribute -node ([ref]$RootNode) -szName "Img" -value "$env:temp\Computer.png" } "container" { AddXMLAttribute -node ([ref]$RootNode) -szName "Img" -value "$env:temp\Container.png" } default { AddXMLAttribute -node ([ref]$RootNode) -szName "Img" -value "$env:temp\Other.png" } } [void]$global:xmlDoc.appendChild($RootNode) $node = $global:xmlDoc.documentElement; #Process the OU tree ProcessOUTree -node $node -ADSObject $treeNodePath #-nodeCount 0 return $global:xmlDoc } $global:dicRightsGuids = @{"Seed" = "xxx"} $global:dicSidToName = @{"Seed" = "xxx"} $global:dicDCSpecialSids =@{"BUILTIN\Incoming Forest Trust Builders"="S-1-5-32-557";` "BUILTIN\Account Operators"="S-1-5-32-548";` "BUILTIN\Server Operators"="S-1-5-32-549";` "BUILTIN\Pre-Windows 2000 Compatible Access"="S-1-5-32-554";` "BUILTIN\Terminal Server License Servers"="S-1-5-32-561";` "BUILTIN\Windows Authorization Access Group"="S-1-5-32-560"} $global:dicWellKnownSids = @{"S-1-0"="Null Authority";` "S-1-0-0"="Nobody";` "S-1-1"="World Authority";` "S-1-1-0"="Everyone";` "S-1-2"="Local Authority";` "S-1-2-0"="Local ";` "S-1-2-1"="Console Logon ";` "S-1-3"="Creator Authority";` "S-1-3-0"="Creator Owner";` "S-1-3-1"="Creator Group";` "S-1-3-2"="Creator Owner Server";` "S-1-3-3"="Creator Group Server";` "S-1-3-4"="Owner Rights";` "S-1-4"="Non-unique Authority";` "S-1-5"="NT Authority";` "S-1-5-1"="Dialup";` "S-1-5-2"="Network";` "S-1-5-3"="Batch";` "S-1-5-4"="Interactive";` "S-1-5-6"="Service";` "S-1-5-7"="Anonymous";` "S-1-5-8"="Proxy";` "S-1-5-9"="Enterprise Domain Controllers";` "S-1-5-10"="Principal Self";` "S-1-5-11"="Authenticated Users";` "S-1-5-12"="Restricted Code";` "S-1-5-13"="Terminal Server Users";` "S-1-5-14"="Remote Interactive Logon";` "S-1-5-15"="This Organization";` "S-1-5-17"="IUSR";` "S-1-5-18"="Local System";` "S-1-5-19"="NT Authority";` "S-1-5-20"="NT Authority";` "S-1-5-22"="ENTERPRISE READ-ONLY DOMAIN CONTROLLERS BETA";` "S-1-5-32-544"="Administrators";` "S-1-5-32-545"="Users";` "S-1-5-32-546"="Guests";` "S-1-5-32-547"="Power Users";` "S-1-5-32-548"="BUILTIN\Account Operators";` "S-1-5-32-549"="Server Operators";` "S-1-5-32-550"="Print Operators";` "S-1-5-32-551"="Backup Operators";` "S-1-5-32-552"="Replicator";` "S-1-5-32-554"="BUILTIN\Pre-Windows 2000 Compatible Access";` "S-1-5-32-555"="BUILTIN\Remote Desktop Users";` "S-1-5-32-556"="BUILTIN\Network Configuration Operators";` "S-1-5-32-557"="BUILTIN\Incoming Forest Trust Builders";` "S-1-5-32-558"="BUILTIN\Performance Monitor Users";` "S-1-5-32-559"="BUILTIN\Performance Log Users";` "S-1-5-32-560"="BUILTIN\Windows Authorization Access Group";` "S-1-5-32-561"="BUILTIN\Terminal Server License Servers";` "S-1-5-32-562"="BUILTIN\Distributed COM Users";` "S-1-5-32-568"="BUILTIN\IIS_IUSRS";` "S-1-5-32-569"="BUILTIN\Cryptographic Operators";` "S-1-5-32-573"="BUILTIN\Event Log Readers ";` "S-1-5-32-574"="BUILTIN\Certificate Service DCOM Access";` "S-1-5-32-575"="BUILTIN\RDS Remote Access Servers";` "S-1-5-32-576"="BUILTIN\RDS Endpoint Servers";` "S-1-5-32-577"="BUILTIN\RDS Management Servers";` "S-1-5-32-578"="BUILTIN\Hyper-V Administrators";` "S-1-5-32-579"="BUILTIN\Access Control Assistance Operators";` "S-1-5-32-580"="BUILTIN\Remote Management Users";` "S-1-5-33"="Write Restricted Code";` "S-1-5-64-10"="NTLM Authentication";` "S-1-5-64-14"="SChannel Authentication";` "S-1-5-64-21"="Digest Authentication";` "S-1-5-65-1"="This Organization Certificate";` "S-1-5-80"="NT Service";` "S-1-5-84-0-0-0-0-0"="User Mode Drivers";` "S-1-5-113"="Local Account";` "S-1-5-114"="Local Account And Member Of Administrators Group";` "S-1-5-1000"="Other Organization";` "S-1-15-2-1"="All App Packages";` "S-1-16-0"="Untrusted Mandatory Level";` "S-1-16-4096"="Low Mandatory Level";` "S-1-16-8192"="Medium Mandatory Level";` "S-1-16-8448"="Medium Plus Mandatory Level";` "S-1-16-12288"="High Mandatory Level";` "S-1-16-16384"="System Mandatory Level";` "S-1-16-20480"="Protected Process Mandatory Level";` "S-1-16-28672"="Secure Process Mandatory Level";` "S-1-18-1"="Authentication Authority Asserted Identityl";` "S-1-18-2"="Service Asserted Identity"} #========================================================================== # Function : Get-LargeNestedADGroup # Arguments : DC name, DN of Group, Object type, Array of Members # Returns : Array of Members # Description : This function will enumerate large groups and returns direct and recusive members # #========================================================================== Function Get-LargeNestedADGroup { Param ( # Domain Controller [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [string]$strDC, # DistinguishedName of the group [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [string]$GroupDN, # Returns members of type [Parameter(Mandatory=$false)] [ValidateSet("*", "User", "Group", "Computer")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [String] $Output = "*", [System.Collections.ArrayList] $MembersExpanded ) begin { $null = Add-Type -AssemblyName System.DirectoryServices.Protocols if(-not($MembersExpanded)) { $MembersExpanded = New-Object System.Collections.ArrayList } } Process { # Use ADO to search entire domain. $Root = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$strDC/$GroupDN") $adoConnection = New-Object -comObject "ADODB.Connection" $adoCommand = New-Object -comObject "ADODB.Command" $adoConnection.Open("Provider=ADsDSOObject;") $adoCommand.ActiveConnection = $adoConnection $adoCommand.Properties.Item("Page Size") = 200 $adoCommand.Properties.Item("Timeout") = 30 $adoCommand.Properties.Item("Cache Results") = $False $Base = $Root.distinguishedName $Scope = "base" $Filter = "(objectCategory=group)" # Setup range limits. $Last = $False $RangeStep = 1499 $LowRange = 0 $HighRange = $LowRange + $RangeStep $Total = 0 $ExitFlag = $False Do { If ($Last -eq $True) { # Retrieve remaining members (less than 1000). $Attributes = "member;range=$LowRange-*" } Else { # Retrieve 1000 members. $Attributes = "member;range=$LowRange-$HighRange" } $Query = ";$Filter;$Attributes;$Scope" $adoCommand.CommandText = $Query $adoRecordset = $adoCommand.Execute() $Count = 0 $Members = $adoRecordset.Fields.Item("$Attributes").Value If ($Members -eq $Null) { $Last = $True } Else { # If $Members is not an array, no members were retrieved. If ($Members.GetType().Name -eq "Object[]") { ForEach ($Member In $Members) { $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($strDC, $CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest $request.DistinguishedName = $Member $request.Filter = "(name=*)" $request.Scope = "Base" [void]$request.Attributes.Add("objectclass") [void]$request.Attributes.Add("member") $response = $LDAPConnection.SendRequest($request) $ADObject = $response.Entries[0] Try{ $ObjectClass =$ADObject.attributes.objectclass[$ADObject.attributes.objectclass.count-1] } catch { Write-Verbose "Error - Could not read objectClass $Member"; continue; } if ($ObjectClass -eq "Group") { if(($ADObject.Attributes.AttributeNames -contains "member;range=0-1499") -or ($ADObject.Attributes.AttributeNames -contains "member")) { if (($global:colOfGroupMembersExpanded -notcontains $Member) -and ($GroupDN -ne $Member)) { $MembersExpanded = @(Get-LargeNestedADGroup $strDC $Member $Output $MembersExpanded) [void]$global:GroupMembersExpanded.insert(0, $Member) } } } # Output the distinguished name of each direct member of the group. if (($Output -eq "*") -or ($ObjectClass -eq $Output)) { if ($MembersExpanded -notcontains $Member) { [void]$MembersExpanded.add($Member) } } $Count = $Count + 1 } } } $adoRecordset.Close() $Total = $Total + $Count # If this is the last query, exit the Do loop. If ($Last -eq $True) {$ExitFlag = $True} Else { # If the previous query returned no members, the query failed. # Perform one more query to retrieve remaining members (less than 1000). If ($Count -eq 0) {$Last = $True} Else { # Retrieve the next 1000 members. $LowRange = $HighRange + 1 $HighRange = $LowRange + $RangeStep } } } Until ($ExitFlag -eq $True) } End { $adoConnection.Close() return $MembersExpanded } } #========================================================================== # Function : Test-ResolveDNS # Arguments : DNS Name, DNS Server # Returns : boolean # Description : This function try to resolve a dns record and retruns true or false # #========================================================================== Function Test-ResolveDNS { param ( $strDNS, $strDNSServer = "" ) $bolResolved = $false $global:bolDNSSuccess = $true $global:DNSrslt = $null try { if($strDNSServer-eq "") { $global:DNSrslt = Resolve-DnsName -Type ALL -Name $strDNS -ErrorAction Stop } else { $global:DNSrslt = Resolve-DnsName -Type ALL -Name $strDNS -ErrorAction Stop -Server $strDNSServer } } catch { $global:bolDNSSuccess = $false } if($global:bolDNSSuccess) { if(($global:DNSrslt)[0].IPAddress -ne $null) { $bolResolved = $true } } Remove-Variable bolDNSSuccess -Scope global Remove-Variable DNSrslt -Scope global return $bolResolved } #========================================================================== # Function : LogMessage # Arguments : Type of message, message, date stamping # Returns : Custom psObject with two properties, type and message # Description : This function creates a custom object that is used as input to an ListBox for logging purposes # #========================================================================== function LogMessage { param ( [Parameter( Mandatory = $true )][String[]] $strType , [Parameter( Mandatory = $true )][String[]] $strMessage , [Parameter( Mandatory = $false )][switch]$DateStamp ) process { if ($DateStamp) { $newMessageObject = New-Object PSObject -Property @{Type="$strType";Message="[$(get-date)] $strMessage"} } else { $newMessageObject = New-Object PSObject -Property @{Type="$strType";Message="$strMessage"} } return $newMessageObject } } #========================================================================== # Function : ConvertTo-ObjectArrayListFromPsCustomObject # Arguments : Defined Object # Returns : Custom Object List # Description : Convert a defined object to a custom, this will help you if you got a read-only object # #========================================================================== function ConvertTo-ObjectArrayListFromPsCustomObject { param ( [Parameter( Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] $psCustomObject ); process { $myCustomArray = New-Object System.Collections.ArrayList foreach ($myPsObject in $psCustomObject) { $hashTable = @{}; $myPsObject | Get-Member -MemberType *Property | ForEach-Object { $hashTable.($_.name) = $myPsObject.($_.name); } $Newobject = new-object psobject -Property $hashTable [void]$myCustomArray.add($Newobject) } return $myCustomArray } } #========================================================================== # Function : DisplayLegend # Arguments : - # Returns : - # Description : Show color legend #========================================================================== Function DisplayLegend { $xamlLegend =@"