diff --git a/automatic/ad-acl-scanner/ad-acl-scanner.nuspec b/automatic/ad-acl-scanner/ad-acl-scanner.nuspec index a58b8ecf4..af4e5754d 100644 --- a/automatic/ad-acl-scanner/ad-acl-scanner.nuspec +++ b/automatic/ad-acl-scanner/ad-acl-scanner.nuspec @@ -2,7 +2,7 @@ ad-acl-scanner - 7.8 + 7.9 AD ACL Scanner (Script) Robin Granberg tunisiano diff --git a/automatic/ad-acl-scanner/tools/ADACLScan.ps1 b/automatic/ad-acl-scanner/tools/ADACLScan.ps1 index 76626a717..904283fd7 100644 --- a/automatic/ad-acl-scanner/tools/ADACLScan.ps1 +++ b/automatic/ad-acl-scanner/tools/ADACLScan.ps1 @@ -1,13 +1,13 @@ -<# +<# .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 + + 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 @@ -84,7 +84,7 @@ .EXAMPLE .\ADACLScan.ps1 -Base "ou=mig,dc=contoso,dc=com" -Output CSVTEMPLATE - + This will result in a CSV-file with a format adapted for comparing. .EXAMPLE @@ -118,105 +118,105 @@ Param ( # DistinguishedName to start your search at or type RootDSE for the domain root. Will be included in the result if your filter matches the object. [Alias("b")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ValueFromPipeline=$true, - ValueFromPipelineByPropertyName=$true, - ValueFromRemainingArguments=$false, + ValueFromPipelineByPropertyName=$true, + ValueFromRemainingArguments=$false, Position=0, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Base="", # Targets allows you to use a predefined search for specific objects - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ValueFromPipeline=$true, - ValueFromPipelineByPropertyName=$true, - ValueFromRemainingArguments=$false, + ValueFromPipelineByPropertyName=$true, + ValueFromRemainingArguments=$false, Position=0, ParameterSetName='Default')] [ValidateSet("RiskyTemplates")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Targets, # Filter. Specify your custom filter. Default is OrganizationalUnit. [Alias("filter")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=1, ParameterSetName='Default')] [validatescript({$_ -like "(*=*)"})] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $LDAPFilter, # Scope. Set your scope. Default is base. - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=2, ParameterSetName='Default')] [ValidateSet("base", "onelevel", "subtree")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Scope = "base", # Server. Specify your specific server to target your search at. - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=3, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Server, # Port. Specify your custom port. - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=4, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Port, # Specify the samAccountName of a security principal to check for its effective permissions - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=5, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $EffectiveRightsPrincipal, # Generates a HTML report, default is a CSV. - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=6, ParameterSetName='Default')] [ValidateSet("CSV","CSVTEMPLATE", "HTML", "EXCEL")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Output = "", - # Output folder path for Where-Object results are written. - [Parameter(Mandatory=$false, + # Output folder path for where results are written. + [Parameter(Mandatory=$false, Position=7, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $OutputFolder, # Template to compare with. # This parameter will allow you compare the current state of a security descriptor with a previos created tempate. - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=8, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Template, # Filter what to return when comparing with a template. @@ -225,173 +225,173 @@ Param # Example 2. -Returns "MATCH" # Example 3. -Returns "MISSING" # Example 4. -Returns "NEW" - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, Position=8, ParameterSetName='Default')] [ValidateSet("ALL", "MATCH", "MISSING","NEW")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $TemplateFilter="ALL", # User ExcelFile to defined your own path for the excel output # This parameter will allow you to type the excel file path. # Example 1. -ExcelFile "C:\Temp\ExcelOutput.xlsx" - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $ExcelFile="", # Filter on Criticality. # This parameter will filter the result based on a defined criticality level [Alias("c")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateSet("Critical", "Warning", "Medium","Low","Info")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Criticality="", - + # Show color of criticality # This parameter will add colors to the report if you selected HTML or EXCEL using the -OUTPUT parameter [Alias("color")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $ShowCriticalityColor, # Skip default permissions # This parameter will skip permissions that match the permissions defined in the schema partition for the object [Alias("sd")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $SkipDefaults, # Skip protected permissions # This parameter will skip permissions that match the permissions set when selecting "protect object from accidental deletaion" [Alias("sp")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $SkipProtected, # Skip Built-in security principals # This parameter will skip permissions that match the built in groups [Alias("sb")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $SkipBuiltIn, # Filter the trustees on object type. # This parameter will filter the result on an object type. [Alias("rt")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateSet("user", "computer", "group","msds-groupmanagedserviceaccount","*")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $ReturnObjectType="*", # Expand groups # This parameter will search any nested groups to show all security prinicpals that have access. [Alias("rf")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $RecursiveFind, # Filter on RecursiveObjectType. # This parameter will filter the nested groups to show only users that have access. [Alias("ro")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateSet("User", "Computer", "Group","*")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $RecursiveObjectType="*", # Translate GUIDs # This parameter will translate any GUIDs if necessary [Alias("tr")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $Translate, - # Get Group Policy Objects linked + # Get Group Policy Objects linked # This parameter will let you search permissions on group policy objects that are linked to the path you have selected - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $GPO, - + # Open HTML report # This parameter will open the out report if you selected one using the -OUTPUT parameter [Alias("s")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $Show, # Include Security Descriptor modified date in report # This parameter will include the date when the security descriptor was last changed - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $SDDate, # Include Owner in report # This parameter will make the scan to search the owner section in the security descriptor. [Alias("o")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $Owner, # Include Canonical Names in report [Alias("cn")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $CanonicalNames, # Include if inheritance is disabled in report - # This parameter will add information in the report whether the object have disabled it's inheritnace + # This parameter will add information in the report whether the object have disabled it's inheritnace [Alias("p")] - [Parameter(Mandatory=$false, + [Parameter(Mandatory=$false, ParameterSetName='Default')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $Protected, # Scan Default Security Descriptor @@ -400,7 +400,7 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $DefaultSecurityDescriptor, # Filter Default Security Descriptor on a schema object @@ -411,7 +411,7 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $SchemaObjectName="*", # Filter Default Security Descriptor on modified with version number higher than 1 @@ -420,7 +420,7 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $OnlyModified, # Include inherited permissions @@ -429,7 +429,7 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $IncludeInherited, # Returns ACE's in the format that .Net presents access permissions @@ -437,14 +437,14 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $RAW, # Returns ACE's in the SDDL format [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $SDDL, # Filter ACL for access type @@ -455,7 +455,7 @@ Param [ValidateSet("Allow", "Deny")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $AccessType, # Filter ACL for a specific permission @@ -465,7 +465,7 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Permission, # Filter ACL ObjectName @@ -475,7 +475,7 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $ApplyTo="", # Filter ACL for matching strings in Trustee @@ -485,19 +485,19 @@ Param [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $FilterTrustee="", # Show the progressbar in the CLI [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [switch] + [switch] $ShowProgressBar, # Add Credentials to the command by first creating a pscredential object like for example $CREDS = get-credential [Parameter(Mandatory=$false)] - [PSCredential] + [PSCredential] $Credentials ) @@ -509,15 +509,15 @@ Param [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" +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 @@ -563,7 +563,7 @@ $global:SchemaHashAD = @{ 87="Windows Server 2016"; 88="Windows Server 2019" } - + # List of Exchange Schema versions $global:SchemaHashExchange = @{ 4397="Exchange Server 2000"; @@ -596,7 +596,7 @@ $global:SchemaHashExchange = @{ 17001="Exchange Server 2019 CU2-CU7"; 17002="Exchange Server 2019 CU8" } - + # List of Lync Schema versions $global:SchemaHashLync = @{ 1006="LCS 2005"; @@ -1142,8 +1142,8 @@ $xamlBase = @" "@ [XML] $XAML = $xamlBase -$xaml.Window.RemoveAttribute("x:Class") - +$xaml.Window.RemoveAttribute("x:Class") + $reader=(New-Object System.Xml.XmlNodeReader $XAML) $Window=[Windows.Markup.XamlReader]::Load( $reader ) @@ -1173,7 +1173,7 @@ $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() @@ -1189,7 +1189,7 @@ $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() @@ -1204,7 +1204,7 @@ $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() @@ -1319,7 +1319,7 @@ $Window.Add_Loaded({ $TextBoxStatusMessage.ItemsSource = $Global:observableCollection }) -if ($PSVersionTable.PSVersion -gt "2.0") +if ($PSVersionTable.PSVersion -gt "2.0") { try @@ -1382,7 +1382,7 @@ Add-Type @" [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); } -"@ +"@ } catch {} @@ -1412,7 +1412,7 @@ $txtCustomFilter.IsEnabled = $false $rdbScanContainer.add_Click({ $txtCustomFilter.IsEnabled = $false -}) +}) $rdbScanAll.add_Click({ $txtCustomFilter.IsEnabled = $false @@ -1425,7 +1425,7 @@ $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")) { @@ -1450,7 +1450,7 @@ $btnGetForestInfo.add_Click({ else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) - } + } }) $btnClearExcludedBox.add_Click({ @@ -1474,7 +1474,7 @@ $btnGetSchemaClass.add_Click( 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; @@ -1497,7 +1497,7 @@ $btnGetSchemaClass.add_Click( #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]) @@ -1528,7 +1528,7 @@ $btnGetSchemaClass.add_Click( else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) - } + } }) @@ -1539,14 +1539,14 @@ $btnExportDefSD.add_Click( if ($global:bolConnected -eq $true) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Scanning..." -strType "Info" -DateStamp )) - $strFileCSV = $txtTempFolder.Text + "\" +$global:strDomainShortName + "_DefaultSecDescriptor" + $date + ".csv" + $strFileCSV = $txtTempFolder.Text + "\" +$global:strDomainShortName + "_DefaultSecDescriptor" + $date + ".csv" Write-DefaultSDCSV -fileout $strFileCSV -CREDS $CREDS $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 )) - } + } }) @@ -1555,7 +1555,7 @@ $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 )) @@ -1567,7 +1567,7 @@ $btnCompDefSD.add_Click( $strDefaultSDCompareFile = $txtCompareDefSDTemplate.Text &{#Try $global:bolDefaultSDCSVLoaded = $true - $global:csvdefSDTemplate = import-Csv $strDefaultSDCompareFile + $global:csvdefSDTemplate = import-Csv $strDefaultSDCompareFile } Trap [SystemException] { @@ -1578,7 +1578,7 @@ $btnCompDefSD.add_Click( } if($bolDefaultSDCSVLoaded) { - if(TestCSVColumnsDefaultSD $global:csvdefSDTemplate) + if(TestCSVColumnsDefaultSD $global:csvdefSDTemplate) { $strSelectedItem = $combObjectDefSD.SelectedItem if($strSelectedItem -eq "All Objects") @@ -1592,7 +1592,7 @@ $btnCompDefSD.add_Click( 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 test column names exist } }#end if txtCompareDefSDTemplate.Text is empty @@ -1600,7 +1600,7 @@ $btnCompDefSD.add_Click( else { $global:observableCollection.Insert(0,(LogMessage -strMessage "Connect to your naming context first!" -strType "Error" -DateStamp )) - } + } }) $btnScanDefSD.add_Click( @@ -1608,25 +1608,25 @@ $btnScanDefSD.add_Click( $global:bolProgressBar = $chkBoxSkipProgressBar.IsChecked $bolReplMeta = $true - - $strFileDefSDHTA = $env:temp + "\"+$global:ACLHTMLFileName+".hta" + + $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" + $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" + $strFileDefSDHTM = $CurrentFSPath + "\"+"$global:strDomainShortName-$strSelectedItem-$global:SessionID"+".htm" } } else { - $strFileDefSDHTM = $CurrentFSPath + "\"+"$global:strDomainShortName-$strSelectedItem-$global:SessionID"+".htm" + $strFileDefSDHTM = $CurrentFSPath + "\"+"$global:strDomainShortName-$strSelectedItem-$global:SessionID"+".htm" } if ($global:bolConnected -eq $true) @@ -1656,22 +1656,22 @@ $btnScanDefSD.add_Click( } else { - CreateHTM $strSelectedItem $strFileDefSDHTM + 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 -CREDS $CREDS - + $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 )) - } - + } + }) @@ -1679,15 +1679,15 @@ $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" + + $strFileSPNHTA = $env:temp + "\"+$global:SPNHTMLFileName+".hta" + $strFileSPNHTM = $env:temp + "\"+"$global:strEffectiveRightAccount"+".htm" CreateServicePrincipalReportHTA $global:strEffectiveRightSP $strFileSPNHTA $strFileSPNHTM $CurrentFSPath CreateSPNHTM $global:strEffectiveRightSP $strFileSPNHTM - InitiateSPNHTM $strFileSPNHTA + InitiateSPNHTM $strFileSPNHTA $strColorTemp = 1 WriteSPNHTM $global:strEffectiveRightSP $global:tokens $global:strSPNobjectClass $($global:tokens.count-1) $strColorTemp $strFileSPNHTA $strFileSPNHTM - Invoke-Item $strFileSPNHTA + Invoke-Item $strFileSPNHTA } else { @@ -1698,7 +1698,7 @@ $btnGETSPNReport.add_Click( $btnViewLegend.add_Click( { - + DisplayLegend }) @@ -1756,7 +1756,7 @@ $chkBoxScanUsingUSN.add_Click( { $global:bolTempValue_chkBoxReplMeta = $chkBoxReplMeta.IsChecked $chkBoxReplMeta.IsChecked = $true - + } else { @@ -1764,7 +1764,7 @@ $chkBoxScanUsingUSN.add_Click( { $chkBoxReplMeta.IsChecked = $global:bolTempValue_chkBoxReplMeta } - + } }) @@ -1776,7 +1776,7 @@ $chkBoxCompare.add_Click( { $chkInheritedPerm.IsChecked = $global:bolTempValue_InhertiedChkBox } - + if ($null -ne $global:bolTempValue_chkBoxGetOwner) { $chkBoxGetOwner.IsChecked = $global:bolTempValue_chkBoxGetOwner @@ -1812,7 +1812,7 @@ $chkBoxCompare.add_Click( $txtBoxObjectFilter.IsEnabled = $false $txtFilterTrustee.IsEnabled = $false $combAccessCtrl.IsEnabled = $false - + } else { @@ -1823,7 +1823,7 @@ $chkBoxCompare.add_Click( $chkBoxScanUsingUSN.IsEnabled = $false $btnGetCompareInput.IsEnabled = $false $txtReplaceDN.IsEnabled = $false - $txtReplaceNetbios.IsEnabled = $false + $txtReplaceNetbios.IsEnabled = $false } }) @@ -1831,7 +1831,7 @@ $chkBoxEffectiveRights.add_Click( { If($chkBoxEffectiveRights.IsChecked) { - + $global:bolTempValue_InhertiedChkBox = $chkInheritedPerm.IsChecked $global:bolTempValue_chkBoxGetOwner = $chkBoxGetOwner.IsChecked $chkBoxFilter.IsChecked = $false @@ -1844,7 +1844,7 @@ $chkBoxEffectiveRights.add_Click( $chkBoxScanUsingUSN.IsEnabled = $false $btnGetCompareInput.IsEnabled = $false $txtReplaceDN.IsEnabled = $false - $txtReplaceNetbios.IsEnabled = $false + $txtReplaceNetbios.IsEnabled = $false $txtBoxSelectPrincipal.IsEnabled = $true $btnGetSPAccount.IsEnabled = $true @@ -1854,7 +1854,7 @@ $chkBoxEffectiveRights.add_Click( $chkInheritedPerm.IsChecked = $true $chkBoxGetOwner.IsEnabled = $false $chkBoxGetOwner.IsChecked= $true - + $chkBoxType.IsEnabled = $false $chkBoxObject.IsEnabled = $false $chkBoxTrustee.IsEnabled = $false @@ -1867,7 +1867,7 @@ $chkBoxEffectiveRights.add_Click( $txtBoxObjectFilter.IsEnabled = $false $txtFilterTrustee.IsEnabled = $false $combAccessCtrl.IsEnabled = $false - + } else { @@ -1924,7 +1924,7 @@ $chkBoxFilter.add_Click( $chkBoxScanUsingUSN.IsEnabled = $false $btnGetCompareInput.IsEnabled = $false $txtReplaceDN.IsEnabled = $false - $txtReplaceNetbios.IsEnabled = $false + $txtReplaceNetbios.IsEnabled = $false $chkBoxEffectiveRights.IsChecked = $false $chkBoxType.IsEnabled = $true @@ -1947,7 +1947,7 @@ $chkBoxFilter.add_Click( { $chkBoxGetOwner.IsChecked = $global:bolTempValue_chkBoxGetOwner } - + } else { @@ -1993,7 +1993,7 @@ $rdbDSSchm.add_Click( $txtBoxDomainConnect.Text = "config" $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false - + } If($rdbDSSchm.IsChecked -eq $true) @@ -2037,7 +2037,7 @@ $rdbDSConf.add_Click( $txtBoxDomainConnect.Text = "config" $txtBdoxDSServerPort.IsEnabled = $false $txtBdoxDSServer.IsEnabled = $false - + } If($rdbDSSchm.IsChecked -eq $true) @@ -2083,7 +2083,7 @@ $rdbDSdef.add_Click( If($rdbDSConf.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "config" - + } If($rdbDSSchm.IsChecked -eq $true) @@ -2125,7 +2125,7 @@ $rdbCustomNC.add_Click( If($rdbDSConf.IsChecked -eq $true) { $txtBoxDomainConnect.Text = "config" - + } If($rdbDSSchm.IsChecked -eq $true) @@ -2141,36 +2141,36 @@ $rdbCustomNC.add_Click( }) -$btnGetTemplateFolder.add_Click( +$btnGetTemplateFolder.add_Click( { - -$strFolderPath = Select-Folder + +$strFolderPath = Select-Folder $txtTempFolder.Text = $strFolderPath }) -$btnGetCompareDefSDInput.add_Click( +$btnGetCompareDefSDInput.add_Click( { -$strFilePath = Select-File +$strFilePath = Select-File $txtCompareDefSDTemplate.Text = $strFilePath }) -$btnGetCompareInput.add_Click( +$btnGetCompareInput.add_Click( { -$strFilePath = Select-File +$strFilePath = Select-File $txtCompareTemplate.Text = $strFilePath }) -$btnGetCSVFile.add_Click( +$btnGetCSVFile.add_Click( { -$strFilePath = Select-File +$strFilePath = Select-File $txtCSVImport.Text = $strFilePath @@ -2230,7 +2230,7 @@ $txtrootdomainnamingcontext.text = "" [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") - + try { $response = $LDAPConnection.SendRequest($request) @@ -2286,8 +2286,8 @@ $txtrootdomainnamingcontext.text = "" [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") - - + + try { $response = $LDAPConnection.SendRequest($request) @@ -2367,7 +2367,7 @@ $txtrootdomainnamingcontext.text = "" [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") - + try { $response = $LDAPConnection.SendRequest($request) @@ -2503,7 +2503,7 @@ $txtrootdomainnamingcontext.text = "" [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") - + try { $response = $LDAPConnection.SendRequest($request) @@ -2537,7 +2537,7 @@ $txtrootdomainnamingcontext.text = "" $global:observableCollection.Insert(0,(LogMessage -strMessage "Failed! Domain does not exist or can not be connected" -strType "Error" -DateStamp )) $global:bolConnected = $false } - + } } } @@ -2585,7 +2585,7 @@ $txtrootdomainnamingcontext.text = "" [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") [void]$request.Attributes.Add("isGlobalCatalogReady") - + try { $response = $LDAPConnection.SendRequest($request) @@ -2616,16 +2616,16 @@ $txtrootdomainnamingcontext.text = "" } } } - #Connect to Custom Naming Context + #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 @@ -2637,12 +2637,12 @@ $txtrootdomainnamingcontext.text = "" { $global:strDC = $txtBdoxDSServer.Text +":" +$txtBdoxDSServerPort.text if($txtBdoxDSServerPort.Text -eq "") - { + { $global:strDC = $txtBdoxDSServer.Text } else { - $global:strDC = $txtBdoxDSServer.Text +":" +$txtBdoxDSServerPort.text + $global:strDC = $txtBdoxDSServer.Text +":" +$txtBdoxDSServerPort.text } } $global:bolLDAPConnection = $false @@ -2661,8 +2661,8 @@ $txtrootdomainnamingcontext.text = "" [void]$request.Attributes.Add("schemanamingcontext") [void]$request.Attributes.Add("configurationnamingcontext") [void]$request.Attributes.Add("rootdomainnamingcontext") - [void]$request.Attributes.Add("isGlobalCatalogReady") - + [void]$request.Attributes.Add("isGlobalCatalogReady") + try { $response = $LDAPConnection.SendRequest($request) @@ -2687,7 +2687,7 @@ $txtrootdomainnamingcontext.text = "" $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] @@ -2697,7 +2697,7 @@ $txtrootdomainnamingcontext.text = "" { if(Test-ResolveDNS $response.Entries[0].Attributes.dnshostname[0]) { - $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text + $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text } } @@ -2713,7 +2713,7 @@ $txtrootdomainnamingcontext.text = "" $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] @@ -2723,9 +2723,9 @@ $txtrootdomainnamingcontext.text = "" { if(Test-ResolveDNS $response.Entries[0].Attributes.dnshostname[0]) { - $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text + $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text } - + } $global:strDomainPrinDNName = $global:strDomainDNName $global:strDomainShortName = GetDomainShortName -strDomain $global:strDomainDNName -strConfigDN $global:ConfigDN -CREDS $CREDS @@ -2741,15 +2741,15 @@ $txtrootdomainnamingcontext.text = "" $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 + $global:strDC = $response.Entries[0].Attributes.dnshostname[0] +":" +$txtBdoxDSServerPort.text } } - } + } if($strNamingContextDN -eq "") { $strNamingContextDN = $global:strDomainDNName @@ -2763,28 +2763,28 @@ $txtrootdomainnamingcontext.text = "" $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 + $global:bolConnected = $false } - } - If ($NCSelect -eq $true) + } + If ($NCSelect -eq $true) { If (!($strLastCacheGuidsDom -eq $global:strDomainDNName)) { $global:dicRightsGuids = @{"Seed" = "xxx"} CacheRightsGuids -CREDS $CREDS $strLastCacheGuidsDom = $global:strDomainDNName - - + + } #Check Directory Service type $global:DSType = "" @@ -2809,7 +2809,7 @@ $txtrootdomainnamingcontext.text = "" { $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 @@ -2827,72 +2827,72 @@ $txtrootdomainnamingcontext.text = "" $IconFilePath = $env:temp + "\OU.png" $bytes = [Convert]::FromBase64String($OUpng) - [IO.File]::WriteAllBytes($IconFilePath, $bytes) + [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) + [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) + [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) + [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) + [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) + [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) + [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) + [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) + [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) + [IO.File]::WriteAllBytes($IconFilePath, $bytes) } #Test PS Version DeleteCommand requries PS 3.0 and above - if ($PSVersionTable.PSVersion -gt "2.0") + 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 + else { Write-Error "Requries PS 3.0 and above" break @@ -2905,7 +2905,7 @@ $txtrootdomainnamingcontext.text = "" $txtrootdomainnamingcontext.text = $global:ForestRootDomainDN }#End If NCSelect - + #Get Forest Root Domain ObjectSID if ($global:DSType -eq "AD DS") { @@ -2913,7 +2913,7 @@ if ($global:DSType -eq "AD DS") $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) @@ -2929,18 +2929,18 @@ if ($global:DSType -eq "AD DS") $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($CREDS.UserName) { - $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strForestDomainLongName,$CREDS.UserName,$CREDS.GetNetworkCredential().Password) + $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strForestDomainLongName,$CREDS.UserName,$CREDS.GetNetworkCredential().Password) } else { - $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strForestDomainLongName) + $Context = New-Object DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$global:strForestDomainLongName) } $ojbDomain = [DirectoryServices.ActiveDirectory.Domain]::GetDomain($Context) $global:strForestDC = $($ojbDomain.FindDomainController()).name @@ -2949,7 +2949,7 @@ if ($global:DSType -eq "AD DS") $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) @@ -2972,7 +2972,7 @@ if ($global:DSType -eq "AD DS") $global:ForestRootDomainSID = $global:DomainSID } - + } }) @@ -2981,10 +2981,10 @@ $chkBoxCreds.add_UnChecked({ $script:CREDS = $null }) -$btnScan.add_Click( +$btnScan.add_Click( { - + $UseCanonicalName = $chkBoxUseCanonicalName.IsChecked $Protected = $chkBoxGetOUProtected.IsChecked @@ -3027,7 +3027,7 @@ $btnSupport.add_Click( GenerateSupportStatement }) -$btnExit.add_Click( +$btnExit.add_Click( { #TODO: Place custom script here @@ -3108,22 +3108,22 @@ $treeView1.add_SelectedItemChanged({ $txtBoxSelected.Text = (Get-XMLPath -xmlElement ($this.SelectedItem)) -if ($this.SelectedItem.Tag -eq "NotEnumerated") -{ +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 + + # Initialize and Build Domain OU Tree ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath -CREDS $CREDS - # Set tag to show this node is already enumerated - $this.SelectedItem.Tag = "Enumerated" - + # Set tag to show this node is already enumerated + $this.SelectedItem.Tag = "Enumerated" + } @@ -3137,12 +3137,12 @@ if ($this.SelectedItem.Tag -eq "NotEnumerated") Functions to Build Domains OU Tree XML Document ######################################################################> -#region +#region function RunCompare { param( [Parameter(Mandatory=$false)] - [pscredential] + [pscredential] $CREDS) if($chkBoxSeverity.isChecked -or $chkBoxEffectiveRightsColor.isChecked) @@ -3155,7 +3155,7 @@ else } If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) { - #If the DC string is changed during the compre ti will be restored to it's orgi value + #If the DC string is changed during the compre ti will be restored to it's orgi value $global:ResetDCvalue = "" $global:ResetDCvalue = $global:strDC @@ -3188,7 +3188,7 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) &{#Try $global:bolCSVLoaded = $true - $global:csvHistACLs = import-Csv $strCompareFile + $global:csvHistACLs = import-Csv $strCompareFile } Trap [SystemException] { @@ -3196,14 +3196,14 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) $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 + } + #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 @@ -3241,7 +3241,7 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) { $global:observableCollection.Insert(0,(LogMessage -strMessage "Could not read object $($txtBoxSelected.Text.ToString()). Enough permissions?" -strType "Error" -DateStamp )) } - + } else { @@ -3281,7 +3281,7 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) { $global:strDC = $global:strDC + ":3268" } - + } else { @@ -3297,7 +3297,7 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) } } - + if($txtReplaceDN.text.Length -gt 0) { @@ -3320,7 +3320,7 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) $request.Filter = "(name=*)" $request.Scope = "Base" [void]$request.Attributes.Add("name") - + $response = $LDAPConnection.SendRequest($request) $ADobject = $response.Entries[0] @@ -3338,23 +3338,23 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) $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" + $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 + CreateHTM "$global:strDomainShortName-$strNode Filtered" $strFileHTM } else { CreateHTA "$global:strDomainShortName-$strNode" $strFileHTA $strFileHTM $CurrentFSPath $global:strDomainDNName $global:strDC - CreateHTM "$global:strDomainShortName-$strNode" $strFileHTM + 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 @@ -3407,7 +3407,7 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) { $allSubOU = GetAllChildNodes -firstnode $txtBoxSelected.Text -scope "onelevel" -ExcludedDNs $txtBoxExcluded.text -CREDS $CREDS } - } + } } else { @@ -3415,13 +3415,13 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) } #if any objects found compare ACLs if($allSubOU.count -gt 0) - { + { $TemplateFilter = $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 $TemplateFilter $bolToFile $bolShowCriticalityColor $chkBoxSeverity.IsChecked $combServerity.SelectedItem $chkBoxTranslateGUID.isChecked -CREDS $CREDS - } + } else { $global:observableCollection.Insert(0,(LogMessage -strMessage "No objects returned!" -strType "Error" -DateStamp )) @@ -3437,16 +3437,16 @@ If ($txtBoxSelected.Text -or $chkBoxTemplateNodes.IsChecked ) 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 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 + }# End If #Restore the DC string to its original $global:strDC = $global:ResetDCvalue @@ -3467,7 +3467,7 @@ function RunScan { param( [Parameter(Mandatory=$false)] - [pscredential] + [pscredential] $CREDS) if($rdbGPO.isChecked) @@ -3488,7 +3488,7 @@ 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) -and ($chkBoxPermission.IsChecked -eq $false))) { - + $global:observableCollection.Insert(0,(LogMessage -strMessage "Filter Enabled , but no filter is specified!" -strType "Error" -DateStamp )) $bolPreChecks = $false } @@ -3496,15 +3496,15 @@ If ($txtBoxSelected.Text) { If(($chkBoxFilter.IsChecked -eq $true) -and (($combAccessCtrl.SelectedIndex -eq -1) -and ($txtBoxObjectFilter.Text -eq "") -and ($txtFilterTrustee.Text -eq "") -and ($txtPermission.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 } @@ -3535,7 +3535,7 @@ If ($txtBoxSelected.Text) $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 @@ -3556,27 +3556,27 @@ If ($txtBoxSelected.Text) $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" + $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 + CreateHTM "$global:strDomainShortName-$strNode Filtered" $strFileHTM } else { CreateHTA "$global:strDomainShortName-$strNode" $strFileHTA $strFileHTM $CurrentFSPath $global:strDomainDNName $global:strDC - CreateHTM "$global:strDomainShortName-$strNode" $strFileHTM + 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 $chkBoxSDDLView.isChecked @@ -3601,7 +3601,7 @@ If ($txtBoxSelected.Text) $Format = "CSVTEMPLATE" } $Show = $false - } + } If ($txtBoxSelected.Text.ToString().Length -gt 0) { #Select type of scope @@ -3619,7 +3619,7 @@ If ($txtBoxSelected.Text) } $IncludeInherited = $chkInheritedPerm.IsChecked - + if($rdbScanFilter.IsChecked -eq $true) { $allSubOU = @(GetAllChildNodes -firstnode $txtBoxSelected.Text -scope $Scope -ExcludedDNs $txtBoxExcluded.text -CustomFilter $txtCustomFilter.Text -CREDS $CREDS ) @@ -3631,7 +3631,7 @@ If ($txtBoxSelected.Text) #if any objects found read ACLs if($allSubOU.count -gt 0) - { + { $bolToFile = $true #Used from comand line only $FilterBuiltin = $chkBoxFilterBuiltin.IsChecked @@ -3641,7 +3641,7 @@ If ($txtBoxSelected.Text) else { $global:observableCollection.Insert(0,(LogMessage -strMessage "No objects returned! Does your filter relfect the objects you are searching for?" -strType "Error" -DateStamp )) - } + } } } else @@ -3692,7 +3692,7 @@ function Add-ExcludeChild { if($txtBoxExcluded.Text.Length -gt 0) { - $txtBoxExcluded.Text = $txtBoxExcluded.Text + ";" + $txtBoxSelected.Text + $txtBoxExcluded.Text = $txtBoxExcluded.Text + ";" + $txtBoxSelected.Text } else { @@ -3720,11 +3720,11 @@ function Add-RefreshChild { $Mynodes.IsEmpty = $true $treeNodePath = $NodeDNPath + + # Initialize and Build Domain OU Tree - # Initialize and Build Domain OU Tree - - ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath -CREDS $CREDS - # Set tag to show this node is already enumerated + ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath -CREDS $CREDS + # Set tag to show this node is already enumerated } } @@ -3736,10 +3736,10 @@ function Add-RefreshChild { $Mynodes.IsEmpty = $true $treeNodePath = $NodeDNPath - - # Initialize and Build Domain OU Tree - ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath -CREDS $CREDS - # Set tag to show this node is already enumerated + + # Initialize and Build Domain OU Tree + ProcessOUTree -node $($Mynodes) -ADSObject $treeNodePath -CREDS $CREDS + # Set tag to show this node is already enumerated } } @@ -3756,25 +3756,25 @@ function ProcessOUTree $node, $ADSObject, [Parameter(Mandatory=$false)] - [pscredential] + [pscredential] $CREDS) # 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, $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 - + $request.Controls.Add($pagedRqc) | Out-Null + if($global:bolShowDeleted) { [string] $LDAP_SERVER_SHOW_DELETED_OID = "1.2.840.113556.1.4.417" @@ -3791,7 +3791,7 @@ function ProcessOUTree If ($rdbBrowseAll.IsChecked -eq $true) { $request.Filter = $strFilterAll - + } else { @@ -3802,12 +3802,12 @@ function ProcessOUTree [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; @@ -3830,7 +3830,7 @@ function ProcessOUTree #now process the returned list of distinguishedNames and fetch required properties using ranged retrieval $colResults = $response.Entries foreach ($objResult in $colResults) - { + { $NewOUNode = $global:xmlDoc.createElement("OU"); if ($objResult.attributes.Count -ne 0) { @@ -3897,7 +3897,7 @@ function ProcessOUTree { $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" @@ -3928,13 +3928,13 @@ function ProcessOUTree function ProcessOUTreeStep2OnlyShow { Param( - $node, + $node, [string] $DNName, [Parameter(Mandatory=$false)] - [pscredential] + [pscredential] $CREDS) # Increment the node count to indicate we are done with the domain level @@ -3946,7 +3946,7 @@ function ProcessOUTreeStep2OnlyShow $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 + $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) @@ -3960,7 +3960,7 @@ function ProcessOUTreeStep2OnlyShow If ($rdbBrowseAll.IsChecked -eq $true) { $request.Filter = $strFilterAll - + } else { @@ -3977,9 +3977,9 @@ function ProcessOUTreeStep2OnlyShow 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) + if($global:PageSize -gt 0) { [System.DirectoryServices.Protocols.PageResultResponseControl] $prrc=$null; if ($response.Controls.Length -gt 0) @@ -4001,34 +4001,34 @@ function ProcessOUTreeStep2OnlyShow #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 + $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" @@ -4059,9 +4059,9 @@ function Get-XMLDomainOUTree param ( $szDomainRoot, - + [Parameter(Mandatory=$false)] - [pscredential] + [pscredential] $CREDS ) @@ -4069,9 +4069,9 @@ function Get-XMLDomainOUTree $treeNodePath = $szDomainRoot - - # Initialize and Build Domain OU Tree - + + # Initialize and Build Domain OU Tree + $LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($global:strDC, $CREDS) $LDAPConnection.SessionOptions.ReferralChasing = "None" $request = New-Object System.directoryServices.Protocols.SearchRequest @@ -4081,7 +4081,7 @@ function Get-XMLDomainOUTree [void]$request.Controls.Add((New-Object "System.DirectoryServices.Protocols.DirectoryControl" -ArgumentList "$LDAP_SERVER_SHOW_DELETED_OID",$null,$false,$true )) } - $request.distinguishedName = $treeNodePath + $request.distinguishedName = $treeNodePath $request.filter = "(name=*)" $request.Scope = "base" [void]$request.Attributes.Add("name") @@ -4093,7 +4093,7 @@ function Get-XMLDomainOUTree { $DNName = $DomainRoot.distinguishedname if($null -ne $DomainRoot.Attributes.objectclass) - { + { $strObClass = $DomainRoot.Attributes.objectclass[$DomainRoot.Attributes.objectclass.count-1] } else @@ -4149,7 +4149,7 @@ function Get-XMLDomainOUTree } } [void]$global:xmlDoc.appendChild($RootNode) - + $node = $global:xmlDoc.documentElement; #Process the OU tree @@ -4165,8 +4165,8 @@ function Get-XMLDomainOUTree $global:dicRightsGuids = @{"Seed" = "xxx"} -$global:dicSidToName = @{"Seed" = "xxx"} -$global:dicSidToObject = @{"Seed" = "xxx"} +$global:dicSidToName = @{"Seed" = "xxx"} +$global:dicSidToObject = @{"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";` @@ -4260,7 +4260,7 @@ $global:dicWellKnownSids = @{"S-1-0"="Null Authority";` # Arguments : [string] distinguishedName # Returns : [string] CanonicalName # Description : This function will create a canonical name of a distinguishedName string -# +# #========================================================================== Function Create-CanonicalName { @@ -4292,7 +4292,7 @@ for($i = 0; $i -le $stringSplitted.count; $i++) } $intC++ } - + } $stringReversed = '' @@ -4318,8 +4318,8 @@ return $stringlistReversed # 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 -# +# Description : This function will enumerate large groups and returns direct and recusive members +# #========================================================================== Function Get-LargeNestedADGroup { @@ -4336,18 +4336,18 @@ Param ( [ValidateNotNullOrEmpty()] [string]$GroupDN, - # Returns members of type + # Returns members of type [Parameter(Mandatory=$false)] [ValidateSet("*", "User", "Group", "Computer")] [ValidateNotNull()] [ValidateNotNullOrEmpty()] - [String] + [String] $Output = "*", [System.Collections.ArrayList] $MembersExpanded, [Parameter(Mandatory=$false)] - [pscredential] + [pscredential] $CREDS ) @@ -4365,8 +4365,8 @@ Process # Use ADO to search entire domain. if($CREDS) { - $Root = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$strDC/$GroupDN",$($CREDS.UserName), - $($CREDS.GetNetworkCredential().password ), + $Root = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$strDC/$GroupDN",$($CREDS.UserName), + $($CREDS.GetNetworkCredential().password ), [System.DirectoryServices.AuthenticationTypes]::Secure ) } else @@ -4481,12 +4481,12 @@ Do # Output the distinguished name of each direct member of the group. if (($Output -eq "*") -or ($ObjectClass -eq $Output)) { - if ($MembersExpanded -notcontains $Member) + if ($MembersExpanded -notcontains $Member) { [void]$MembersExpanded.add($Member) } } - + $Count = $Count + 1 } } @@ -4520,11 +4520,11 @@ return $MembersExpanded #========================================================================== -# Function : Test-ResolveDNS +# 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 { @@ -4565,28 +4565,28 @@ $strDNSServer = "" return $bolResolved } #========================================================================== -# Function : LogMessage +# 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( +function LogMessage +{ + param ( + [Parameter( Mandatory = $true )][String[]] $strType , - - [Parameter( - Mandatory = $true + + [Parameter( + Mandatory = $true )][String[]] $strMessage , - [Parameter( + [Parameter( Mandatory = $false )][switch]$DateStamp ) - + process { if ($DateStamp) @@ -4600,43 +4600,43 @@ function LogMessage $newMessageObject = New-Object PSObject -Property @{Type="$strType";Message="$strMessage"} } - + return $newMessageObject } - } + } #========================================================================== -# Function : ConvertTo-ObjectArrayListFromPsCustomObject +# 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 -# +# 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 +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); - } + + 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 @@ -4663,7 +4663,7 @@ $xamlLegend =@" - @@ -4753,8 +4753,8 @@ $xamlLegend =@" [XML] $XAML = $xamlLegend -$xaml.Window.RemoveAttribute("x:Class") - +$xaml.Window.RemoveAttribute("x:Class") + $reader=(New-Object System.Xml.XmlNodeReader $XAML) $WindowLegend=[Windows.Markup.XamlReader]::Load( $reader ) @@ -4785,14 +4785,14 @@ $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() $WindowLegend.Icon = $IconImage -$btnOK.add_Click( +$btnOK.add_Click( { #TODO: Place custom script here @@ -4846,7 +4846,7 @@ Function GenerateTemplateDownloaderSchemaDefSD x:Name="Window" Title="CSV Templates" WindowStartupLocation = "CenterScreen" Width = "380" Height = "250" ShowInTaskbar = "True" ResizeMode="CanResizeWithGrip" WindowState="Normal" Background="#2A3238"> - +