diff --git a/Examples/Example-29-FindGPO-FromDisk-Notranslation.ps1 b/Examples/Example-29-FindGPO-FromDisk-Notranslation.ps1 index 523826c..bc47f7d 100644 --- a/Examples/Example-29-FindGPO-FromDisk-Notranslation.ps1 +++ b/Examples/Example-29-FindGPO-FromDisk-Notranslation.ps1 @@ -1,22 +1,34 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force # Use Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExport - -$OutputNoTranslation = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -NoTranslation +#$OutputNoTranslation = Invoke-GPOZaurr -GPOPath $Env:UserProfile\Desktop\GPOExport -NoTranslation +#$OutputNoTranslation = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -NoTranslation $OutputNoTranslation | Format-Table * +<# New-HTML { foreach ($GPOCategory in $OutputNoTranslation.Keys) { New-HTMLTab -Name $GPOCategory { - if ($Output["$GPOCategory"] -is [System.Collections.IDictionary]) { + if ($OutputNoTranslation["$GPOCategory"] -is [System.Collections.IDictionary]) { foreach ($GpoSettings in $OutputNoTranslation["$GPOCategory"].Keys) { New-HTMLTab -Name $GpoSettings { - New-HTMLTable -DataTable $OutputNoTranslation[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $OutputNoTranslation[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } else { - New-HTMLTable -DataTable $OutputNoTranslation[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $OutputNoTranslation[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } -} -Online -ShowHTML -FilePath $Env:UserProfile\Desktop\OutputFromFindGPO-NoTranslationFromDisk.html \ No newline at end of file +} -Online -ShowHTML -FilePath $Env:UserProfile\Desktop\OutputFromFindGPO-NoTranslationFromDisk.html + +#> +foreach ($GPOCategory in $OutputNoTranslation.Keys) { + if ($OutputNoTranslation["$GPOCategory"] -is [System.Collections.IDictionary]) { + foreach ($GpoSettings in $OutputNoTranslation["$GPOCategory"].Keys) { + ConvertTo-Excel -DataTable $OutputNoTranslation[$GPOCategory][$GpoSettings] -AllProperties -ExcelWorkSheetName $GpoSettings -FilePath $Env:UserProfile\Desktop\Export\$GpoSettings.xlsx -AutoFilter -AutoFit + } + } else { + ConvertTo-Excel -DataTable $OutputNoTranslation[$GPOCategory][$GpoSettings] -AllProperties -ExcelWorkSheetName $GpoSettings -FilePath $Env:UserProfile\Desktop\Export\$GpoSettings.xlsx -AutoFilter -AutoFit + } +} \ No newline at end of file diff --git a/Examples/Example-29-FindGPO0.ps1 b/Examples/Example-29-FindGPO0.ps1 new file mode 100644 index 0000000..5e90896 --- /dev/null +++ b/Examples/Example-29-FindGPO0.ps1 @@ -0,0 +1,36 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +#Invoke-GPOZaurr -OutputType Excel, Object, HTML -Open | Format-Table +$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport -NoTranslation #| Format-Table +#$Output.Count + + + +<# 4073 files - 212MB / no translation + +Days : 0 +Hours : 0 +Minutes : 0 +Seconds : 51 +Milliseconds : 756 +Ticks : 517566534 +TotalDays : 0,000599035340277778 +TotalHours : 0,0143768481666667 +TotalMinutes : 0,86261089 +TotalSeconds : 51,7566534 +TotalMilliseconds : 51756,6534 +#> + +<# 4073 files - 212MB / no translation / But with 2 diff types ($OutputByCategory / $OutputByGPO) +Days : 0 +Hours : 0 +Minutes : 0 +Seconds : 53 +Milliseconds : 246 +Ticks : 532466109 +TotalDays : 0,00061628021875 +TotalHours : 0,01479072525 +TotalMinutes : 0,887443515 +TotalSeconds : 53,2466109 +TotalMilliseconds : 53246,6109 +#> \ No newline at end of file diff --git a/Examples/Example-29-FindGPO.ps1 b/Examples/Example-29-FindGPO1.ps1 similarity index 88% rename from Examples/Example-29-FindGPO.ps1 rename to Examples/Example-29-FindGPO1.ps1 index fe11500..8851898 100644 --- a/Examples/Example-29-FindGPO.ps1 +++ b/Examples/Example-29-FindGPO1.ps1 @@ -1,6 +1,7 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force $Output = Invoke-GPOZaurr #-NoTranslation +$Output | Format-Table New-HTML { foreach ($GPOCategory in $Output.Keys) { @@ -8,11 +9,11 @@ New-HTML { if ($Output["$GPOCategory"] -is [System.Collections.IDictionary]) { foreach ($GpoSettings in $Output["$GPOCategory"].Keys) { New-HTMLTab -Name $GpoSettings { - New-HTMLTable -DataTable $Output[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $Output[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } else { - New-HTMLTable -DataTable $Output[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $Output[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } diff --git a/Examples/Example-29-FindGPO-NoTranslation.ps1 b/Examples/Example-29-FindGPO2-NoTranslation.ps1 similarity index 88% rename from Examples/Example-29-FindGPO-NoTranslation.ps1 rename to Examples/Example-29-FindGPO2-NoTranslation.ps1 index 3d465a5..6c8d808 100644 --- a/Examples/Example-29-FindGPO-NoTranslation.ps1 +++ b/Examples/Example-29-FindGPO2-NoTranslation.ps1 @@ -1,6 +1,7 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force $Output = Invoke-GPOZaurr -NoTranslation +$Output | Format-Table New-HTML { foreach ($GPOCategory in $Output.Keys) { @@ -8,11 +9,11 @@ New-HTML { if ($Output["$GPOCategory"] -is [System.Collections.IDictionary]) { foreach ($GpoSettings in $Output["$GPOCategory"].Keys) { New-HTMLTab -Name $GpoSettings { - New-HTMLTable -DataTable $Output[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $Output[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } else { - New-HTMLTable -DataTable $Output[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $Output[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } diff --git a/Examples/Example-29-FindGPO-FromDisk.ps1 b/Examples/Example-29-FindGPO3-FromDisk.ps1 similarity index 92% rename from Examples/Example-29-FindGPO-FromDisk.ps1 rename to Examples/Example-29-FindGPO3-FromDisk.ps1 index 2a8485a..d996ff7 100644 --- a/Examples/Example-29-FindGPO-FromDisk.ps1 +++ b/Examples/Example-29-FindGPO3-FromDisk.ps1 @@ -11,11 +11,11 @@ New-HTML { if ($Output["$GPOCategory"] -is [System.Collections.IDictionary]) { foreach ($GpoSettings in $Output["$GPOCategory"].Keys) { New-HTMLTab -Name $GpoSettings { - New-HTMLTable -DataTable $Output[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $Output[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } else { - New-HTMLTable -DataTable $Output[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $Key + New-HTMLTable -DataTable $Output[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings } } } diff --git a/Private/ConvertTo-Audit.ps1 b/Private/ConvertTo-Audit.ps1 new file mode 100644 index 0000000..e2b390a --- /dev/null +++ b/Private/ConvertTo-Audit.ps1 @@ -0,0 +1,35 @@ +function ConvertTo-Audit { + [cmdletBinding()] + param( + [Array] $GPOList + ) + foreach ($GPOEntry in $GPOList) { + $SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null }; + $FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null }; + if ($SuccessAttempts -and $FailureAttempts) { + $Setting = 'Success, Failure' + } elseif ($SuccessAttempts) { + $Setting = 'Success' + } elseif ($FailureAttempts) { + $Setting = 'Failure' + } else { + $Setting = 'No auditing' + } + $CreateGPO = [ordered]@{ + DisplayName = $GPOEntry.DisplayName #: WO_SEC_NTLM_Auth_Level + DomainName = $GPOEntry.DomainName #: area1.local + GUID = $GPOEntry.GUID #: 364B095E-C7BF-4CC1-9BFA-393BD38975E5 + GpoType = $GPOEntry.GpoType #: Computer + GpoCategory = $GPOEntry.GpoCategory #: SecuritySettings + GpoSettings = $GPOEntry.GpoSettings #: SecurityOptions + Policy = $GPOEntry.Name + Setting = $Setting + SuccessAttempts = $SuccessAttempts + FailureAttempts = $FailureAttempts + } + $CreateGPO['Linked'] = $GPOEntry.Linked #: True + $CreateGPO['LinksCount'] = $GPOEntry.LinksCount #: 1 + $CreateGPO['Links'] = $GPOEntry.Links #: area1.local + [PSCustomObject] $CreateGPO + } +} \ No newline at end of file diff --git a/Private/ConvertTo-AuditAlternative.ps1 b/Private/ConvertTo-AuditAlternative.ps1 new file mode 100644 index 0000000..9693c2a --- /dev/null +++ b/Private/ConvertTo-AuditAlternative.ps1 @@ -0,0 +1,37 @@ +function ConvertTo-AuditAlternative { + [cmdletBinding()] + param( + [Array] $GPOList + ) + foreach ($GPOEntry in $GPOList) { + $SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null }; + $FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null }; + if ($SuccessAttempts -and $FailureAttempts) { + $Setting = 'Success, Failure' + } elseif ($SuccessAttempts) { + $Setting = 'Success' + } elseif ($FailureAttempts) { + $Setting = 'Failure' + } else { + $Setting = 'No auditing' + } + $CreateGPO = [ordered]@{ + DisplayName = $GPOEntry.DisplayName #: WO_SEC_NTLM_Auth_Level + DomainName = $GPOEntry.DomainName #: area1.local + GUID = $GPOEntry.GUID #: 364B095E-C7BF-4CC1-9BFA-393BD38975E5 + GpoType = $GPOEntry.GpoType #: Computer + GpoCategory = $GPOEntry.GpoCategory #: SecuritySettings + GpoSettings = $GPOEntry.GpoSettings #: SecurityOptions + Policy = $GPOEntry.Name + Setting = $Setting + #SuccessAttempts = $SuccessAttempts + #FailureAttempts = $FailureAttempts + } + + + $CreateGPO['Linked'] = $GPOEntry.Linked #: True + $CreateGPO['LinksCount'] = $GPOEntry.LinksCount #: 1 + $CreateGPO['Links'] = $GPOEntry.Links #: area1.local + [PSCustomObject] $CreateGPO + } +} \ No newline at end of file diff --git a/Private/Get-XMLStandard.ps1 b/Private/Get-XMLStandard.ps1 index cd6a6e4..f98d478 100644 --- a/Private/Get-XMLStandard.ps1 +++ b/Private/Get-XMLStandard.ps1 @@ -10,26 +10,39 @@ foreach ($GpoType in @('User', 'Computer')) { if ($GPOOutput.$GpoType.ExtensionData.Extension) { foreach ($ExtensionType in $GPOOutput.$GpoType.ExtensionData.Extension) { - $GPOSettingTypeSplit = ($ExtensionType.type -split ':') - $KeysToLoop = $ExtensionType | Get-Member -MemberType Properties | Where-Object { $_.Name -notin 'type', $GPOSettingTypeSplit[0] } - foreach ($GpoSettings in $KeysToLoop.Name) { - foreach ($Key in $ExtensionType.$GpoSettings) { - $Template = [ordered] @{ - DisplayName = $GPO.DisplayName - DomainName = $GPO.DomainName - GUID = $GPO.Guid - GpoType = $GpoType - GpoCategory = $GPOSettingTypeSplit[1] - GpoSettings = $GpoSettings - } - $Properties = ($Key | Get-Member -MemberType Properties).Name - foreach ($Property in $Properties) { - $Template["$Property"] = $Key.$Property + # It's possible that one of the ExtensionType records has value null. Weird but happend. + if ($ExtensionType) { + $GPOSettingTypeSplit = ($ExtensionType.type -split ':') + try { + $KeysToLoop = $ExtensionType | Get-Member -MemberType Properties -ErrorAction Stop | Where-Object { $_.Name -notin 'type', $GPOSettingTypeSplit[0] } + } catch { + Write-Warning "Get-XMLStandard - things went sideways $($_.Exception.Message)" + continue + } + foreach ($GpoSettings in $KeysToLoop.Name) { + foreach ($Key in $ExtensionType.$GpoSettings) { + $Template = [ordered] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + GUID = $GPO.Guid + GpoType = $GpoType + GpoCategory = $GPOSettingTypeSplit[1] + GpoSettings = $GpoSettings + } + try { + $Properties = ($Key | Get-Member -MemberType Properties -ErrorAction Stop).Name + } catch { + Write-Warning "Get-XMLStandard - things went sideways 1 $($_.Exception.Message)" + $Properties = $null + } + foreach ($Property in $Properties) { + $Template["$Property"] = $Key.$Property + } + $Template['Linked'] = $LinksInformation.Linked + $Template['LinksCount'] = $LinksInformation.LinksCount + $Template['Links'] = $LinksInformation.Links + [PSCustomObject] $Template } - $Template['Linked'] = $LinksInformation.Linked - $Template['LinksCount'] = $LinksInformation.LinksCount - $Template['Links'] = $LinksInformation.Links - [PSCustomObject] $Template } } } diff --git a/Private/Script.GPODictionary.ps1 b/Private/Script.GPODictionary.ps1 index fec38e6..e46c0a3 100644 --- a/Private/Script.GPODictionary.ps1 +++ b/Private/Script.GPODictionary.ps1 @@ -7,6 +7,22 @@ ConvertTo-AccountPolicies -GPOList $GPOList } } + Audit = [ordered] @{ + Category = 'SecuritySettings' + Settings = 'Audit' + #GPOPath = 'Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Account Policies' + Code = { + ConvertTo-Audit -GPOList $GPOList + } + } + AuditAlternative = [ordered] @{ + Category = 'SecuritySettings' + Settings = 'Audit' + #GPOPath = 'Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Account Policies' + Code = { + ConvertTo-AuditAlternative -GPOList $GPOList + } + } Autologon = [ordered] @{ Category = 'RegistrySettings' Settings = 'RegistrySettings' diff --git a/Public/Invoke-GPOZaurr.ps1 b/Public/Invoke-GPOZaurr.ps1 index 68405dc..af1ea87 100644 --- a/Public/Invoke-GPOZaurr.ps1 +++ b/Public/Invoke-GPOZaurr.ps1 @@ -19,9 +19,22 @@ [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Local')] [string] $Splitter = [System.Environment]::NewLine, + + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] [switch] $FullObjects, - [ValidateSet('HTML', 'Object')][string] $OutputType = 'Object' + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] + [ValidateSet('HTML', 'Object', 'Excel')][string[]] $OutputType = 'Object', + + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] + [string] $OutputPath, + + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] + [switch] $Open ) if ($Type.Count -eq 0) { $Type = $Script:GPODitionary.Keys @@ -56,6 +69,7 @@ [Array] $GPOs = Get-GPOZaurrAD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation } $Output = [ordered] @{} + $OutputByGPO = [ordered] @{} foreach ($GPO in $GPOs) { if ($GPOPath) { $GPOOutput = $GPO.GPOOutput @@ -71,10 +85,20 @@ $Output["$($D.GpoCategory)"]["$($D.GpoSettings)"] = [System.Collections.Generic.List[PSCustomObject]]::new() } $Output["$($D.GpoCategory)"]["$($D.GpoSettings)"].Add($D) + + if (-not $OutputByGPO["$($D.DomainName)"]) { + $OutputByGPO["$($D.DomainName)"] = [ordered] @{} + } + if (-not $OutputByGPO[$D.DomainName][$D.DisplayName]) { + $OutputByGPO[$D.DomainName][$D.DisplayName] = [System.Collections.Generic.List[PSCustomObject]]::new() + } + $OutputByGPO[$D.DomainName][$D.DisplayName].Add($D) } } if ($NoTranslation) { - $Output + if ($OutputType -contains 'Object') { + $OutputByGPO + } } else { $TranslatedOutput = [ordered] @{} foreach ($Report in $Type) { @@ -91,7 +115,63 @@ $TranslatedOutput[$Report] = Invoke-GPOTranslation -InputData $Output -Category $Category -Settings $Settings -Report $Report #} } - $TranslatedOutput + if ($OutputType -contains 'Object') { + $TranslatedOutput + } + } + if ($NoTranslation) { + $SingleSource = $OutputType + } else { + $SingleSource = $TranslatedOutput + } + + if ($OutputPath) { + $FolderPath = $OutputPath + } else { + $FolderPath = [io.path]::GetTempPath() + } + if ($OutputType -contains 'HTML') { + $FilePathHTML = [io.path]::Combine($FolderPath, "GPOZaurr-Summary-$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss')).html") + Write-Warning "Invoke-GPOZaurr - $FilePathHTML" + New-HTML { + foreach ($GPOCategory in $SingleSource.Keys) { + New-HTMLTab -Name $GPOCategory { + if ($SingleSource["$GPOCategory"] -is [System.Collections.IDictionary]) { + foreach ($GpoSettings in $SingleSource["$GPOCategory"].Keys) { + New-HTMLTab -Name $GpoSettings { + if ($SingleSource[$GPOCategory][$GpoSettings].Count -gt 0) { + New-HTMLTable -DataTable $SingleSource[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings + } + } + } + } else { + if ($SingleSource[$GPOCategory].Count -gt 0) { + New-HTMLTable -DataTable $SingleSource[$GPOCategory] -ScrollX -DisablePaging -AllProperties -Title $GpoSettings + } + } + } + } + } -Online -ShowHTML:$Open.IsPresent -FilePath $FilePathHTML + } + if ($OutputType -contains 'Excel') { + $FilePathExcel = [io.path]::Combine($FolderPath, "GPOZaurr-Summary-$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss')).xlsx") + Write-Warning "Invoke-GPOZaurr - $FilePathExcel" + foreach ($GPOCategory in $SingleSource.Keys) { + if ($SingleSource["$GPOCategory"] -is [System.Collections.IDictionary]) { + foreach ($GpoSettings in $SingleSource["$GPOCategory"].Keys) { + if ($SingleSource[$GPOCategory][$GpoSettings].Count -gt 0) { + ConvertTo-Excel -DataTable $SingleSource[$GPOCategory][$GpoSettings] -AllProperties -ExcelWorkSheetName $GpoSettings -FilePath $FilePathExcel -AutoFilter -AutoFit -Option Rename + } + } + } else { + if ($SingleSource[$GPOCategory].Count -gt 0) { + ConvertTo-Excel -DataTable $SingleSource[$GPOCategory] -AllProperties -ExcelWorkSheetName $GPOCategory -FilePath $FilePathExcel -AutoFilter -AutoFit -Option Rename + } + } + } + if ($Open) { + Invoke-Item -Path $FilePathExcel + } } }