diff --git a/Examples/Example-27-FindGPO.ps1 b/Examples/Example-27-FindGPO.ps1 deleted file mode 100644 index f84f992..0000000 --- a/Examples/Example-27-FindGPO.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force - -$Output = Find-GPO -Type LocalUsersAndGroups,Autologon -$Output.LocalUsersAndGroups | Out-HtmlView -ScrollX -DisablePaging -AllProperties -$Output.AutoLogon | Out-HtmlView -ScrollX -DisablePaging -AllProperties \ No newline at end of file diff --git a/Examples/Example-29-FindGPO.ps1 b/Examples/Example-29-FindGPO.ps1 new file mode 100644 index 0000000..50ad3e6 --- /dev/null +++ b/Examples/Example-29-FindGPO.ps1 @@ -0,0 +1,15 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +$Output = Find-GPO #-NoTranslation + +New-HTML { + foreach ($GPOCategory in $Output.Keys) { + New-HTMLTab -Name $GPOCategory { + foreach ($GpoSettings in $Output.$GPOCategory.Keys) { + New-HTMLTab -Name $GpoSettings { + New-HTMLTable -DataTable $Output[$GPOCategory][$GpoSettings] -ScrollX -DisablePaging -AllProperties -Title $Key + } + } + } + } +} -Online -ShowHTML -FilePath $Env:UserProfile\Desktop\OutputFromFindGPO.html \ No newline at end of file diff --git a/Examples/Example-29-FindGPOHtmlOutput.ps1 b/Examples/Example-29-FindGPOHtmlOutput.ps1 new file mode 100644 index 0000000..a1b89f4 --- /dev/null +++ b/Examples/Example-29-FindGPOHtmlOutput.ps1 @@ -0,0 +1,6 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +# Use Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExport + +$Output = Find-GPO -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -NoTranslation +$Output | Format-Table * \ No newline at end of file diff --git a/Examples/Example-29-FindGPOTranslationHelp.ps1 b/Examples/Example-29-FindGPOTranslationHelp.ps1 new file mode 100644 index 0000000..69140b9 --- /dev/null +++ b/Examples/Example-29-FindGPOTranslationHelp.ps1 @@ -0,0 +1,11 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +# This is purely for building GPO Dictionary, mostly for development needs to help asses what is there + +$Output = Find-GPO -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -NoTranslation +#$Output | Format-Table * + +$LookingFor = $Output | Select-GPOTranslation -Category 'SecuritySettings' -Settings 'UserRightsAssignment' +$LookingFor | Format-Table +$LookingFor.Types | Format-Table +#$LookingFor.Data | Format-Table \ No newline at end of file diff --git a/Examples/Example-29-FindGPOfromDisk.ps1 b/Examples/Example-29-FindGPOfromDisk.ps1 index f484f6b..8947ce9 100644 --- a/Examples/Example-29-FindGPOfromDisk.ps1 +++ b/Examples/Example-29-FindGPOfromDisk.ps1 @@ -2,8 +2,8 @@ # Use Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExport -$Output = Find-GPO -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -$Output | Format-Table +$Output = Find-GPO -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' #-NoTranslation +$Output | Format-Table * New-HTML { foreach ($GPOCategory in $Output.Keys) { @@ -15,7 +15,4 @@ New-HTML { } } } -} -Online -ShowHTML -FilePath $Env:UserProfile\Desktop\OutputFromFindGPO.html - - -#Select-Properties -AllProperties -Objects $Output.SecuritySettings \ No newline at end of file +} -Online -ShowHTML -FilePath $Env:UserProfile\Desktop\OutputFromFindGPO.html \ No newline at end of file diff --git a/GPOZaurr.psd1 b/GPOZaurr.psd1 index b20973c..48fd107 100644 --- a/GPOZaurr.psd1 +++ b/GPOZaurr.psd1 @@ -5,7 +5,7 @@ CompatiblePSEditions = 'Desktop' Copyright = '(c) 2011 - 2020 Przemyslaw Klys @ Evotec. All rights reserved.' Description = 'Group Policy Eater is a PowerShell module that aims to gather information about Group Policies but also allows easy fixing for issues that you may expect finding in them.' - FunctionsToExport = 'Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Find-GPO', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrFiles', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrSysvol', 'Get-WMIFilter', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurrPermission', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrOrphanedSysvolFolders', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner' + FunctionsToExport = 'Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Find-GPO', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrFiles', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrSysvol', 'Get-WMIFilter', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurrPermission', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrOrphanedSysvolFolders', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Select-GPOTranslation', 'Set-GPOOwner', 'Set-GPOZaurrOwner' GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde' ModuleVersion = '0.0.46' PowerShellVersion = '5.1' diff --git a/Private/Get-XMLStandard.ps1 b/Private/Get-XMLStandard.ps1 index 8c5e45d..cd6a6e4 100644 --- a/Private/Get-XMLStandard.ps1 +++ b/Private/Get-XMLStandard.ps1 @@ -18,9 +18,6 @@ DisplayName = $GPO.DisplayName DomainName = $GPO.DomainName GUID = $GPO.Guid - Linked = $LinksInformation.Linked - LinksCount = $LinksInformation.LinksCount - Links = $LinksInformation.Links GpoType = $GpoType GpoCategory = $GPOSettingTypeSplit[1] GpoSettings = $GpoSettings @@ -29,6 +26,9 @@ foreach ($Property in $Properties) { $Template["$Property"] = $Key.$Property } + $Template['Linked'] = $LinksInformation.Linked + $Template['LinksCount'] = $LinksInformation.LinksCount + $Template['Links'] = $LinksInformation.Links [PSCustomObject] $Template } } diff --git a/Private/GpoTypes/SecuritySettingsSecurityOptions.ps1 b/Private/GpoTypes/SecuritySettingsSecurityOptions.ps1 new file mode 100644 index 0000000..2a5a996 --- /dev/null +++ b/Private/GpoTypes/SecuritySettingsSecurityOptions.ps1 @@ -0,0 +1,24 @@ +$SecuritySettingsSecurityOptions = @{ + # This is to make sure we're not loosing anything + # We will detect this and if something is missing provide details + PossibleProperties = @( + 'KeyName' + 'SettingNumber' + 'Display' + 'SystemAccessPolicyName' + 'SettingString' + ) + Translate = [ordered] @{ + 'KeyName' = 'KeyName' + 'KeyDisplayName' = 'Display', 'Name' + 'KeyDisplayUnits' = 'Display', 'Units' + 'KeyDisplayBoolean' = 'Display', 'DisplayBoolean' + 'KeyDisplayString' = 'Display', 'DisplayString' + 'SystemAccessPolicyName' = 'SystemAccessPolicyName' + 'SettingString' = 'SettingString' + 'SettingNumber' = 'SettingNumber' + } + Types = [ordered] @{ + 'KeyDisplayBoolean' = { try { [bool]::Parse($args) } catch { $null } } + } +} \ No newline at end of file diff --git a/Private/Invoke-GPOTranslation.ps1 b/Private/Invoke-GPOTranslation.ps1 new file mode 100644 index 0000000..e407ea5 --- /dev/null +++ b/Private/Invoke-GPOTranslation.ps1 @@ -0,0 +1,60 @@ +function Invoke-GPOTranslation { + [cmdletBinding()] + param( + [System.Collections.IDictionary] $InputData, + [string] $Category, + [string] $Settings + ) + if ($Category -and $Settings -and $InputData) { + + } else { + return + } + # This section basically makes sure we check for all properties in GPO Types. + # It's possible given small input of GPOs that I work with that this is not all... and needs updates + $AllProperties = Select-Properties -AllProperties -Objects $InputData.$Category.$Settings + $MissingProperties = $AllProperties | Where-Object { $_ -notin 'DisplayName', 'DomainName', 'GUID', 'Linked', 'LinksCount', 'Links', 'GPOType', 'GPOCategory', 'GPOSettings' } + foreach ($Property in $MissingProperties) { + if ($Property -notin $Script:GPODitionary[$Category][$Settings]['PossibleProperties']) { + Write-Warning "Invoke-Translation - We're missing property for $Category / $Settings - $Property" + } + } + # Here we try to translate given GPO entries according to predefined dictionary - so called prettify + # Dictionary will need a lot of work and engine some improvements + foreach ($GPOEntry in $InputData.$Category.$Settings) { + # Create new GPO Entry with minimal required properties + $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 + } + + # Lets loop thru each Translate Property + foreach ($PropertyName in $Script:GPODitionary[$Category][$Settings]['Translate'].Keys) { + # We get property that we expect on our $GPOEntry object + $Property = $Script:GPODitionary[$Category][$Settings]['Translate'][$PropertyName] + + # Since it's possible we may be interested in something that is a nested property we need to do some looping into the object + $Value = $GPOEntry + foreach ($P in $Property) { + $Value = $Value.$P + } + # Now we simply assing that value to new GPO Entry + # But before we do so, we need to check if it has required type + if ($Script:GPODitionary[$Category][$Settings]['Types'][$PropertyName]) { + # This basically checks in dictionary if we want to convert the type from a string to lets say boolean or something else + $CreateGPO["$PropertyName"] = Invoke-Command -Command $Script:GPODitionary[$Category][$Settings]['Types'][$PropertyName] -ArgumentList $Value + } else { + $CreateGPO["$PropertyName"] = $Value + } + } + # return GPO Entry + $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/Script.GPODictionary.ps1 b/Private/Script.GPODictionary.ps1 new file mode 100644 index 0000000..6727711 --- /dev/null +++ b/Private/Script.GPODictionary.ps1 @@ -0,0 +1,5 @@ +$Script:GPODitionary = @{ + SecuritySettings = @{ + SecurityOptions = $SecuritySettingsSecurityOptions + } +} \ No newline at end of file diff --git a/Public/Find-GPO.ps1 b/Public/Find-GPO.ps1 index 0dcd9d7..f03a4ee 100644 --- a/Public/Find-GPO.ps1 +++ b/Public/Find-GPO.ps1 @@ -21,6 +21,11 @@ 'Account' 'SystemServices' ), + + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] + [switch] $NoTranslation, + [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Local')] [string] $Splitter = [System.Environment]::NewLine, @@ -78,16 +83,6 @@ } #> - $GPODitionary = @{ - 'SecuritySettings' = @{ - Name = 'Security Settings' - Translate = [ordered] @{ - - } - } - } - - #$GPOStoredTypes = Get-XMLGPOTypes -GPOOutput $GPOOutput.GPO @@ -101,7 +96,6 @@ } $Output["$($D.GpoCategory)"]["$($D.GpoSettings)"].Add($D) } - <# continue @@ -161,5 +155,23 @@ } #> } - $Output -} \ No newline at end of file + if ($NoTranslation) { + $Output + } else { + $TranslatedOutput = [ordered] @{} + foreach ($Category in $Script:GPODitionary.Keys) { + if (-not $TranslatedOutput[$Category]) { + $TranslatedOutput[$Category] = [ordered] @{} + } + foreach ($Setting in $Script:GPODitionary[$Category].Keys) { + if (-not $TranslatedOutput[$Category][$Setting]) { + $TranslatedOutput[$Category][$Setting] = [ordered] @{} + } + $TranslatedOutput[$Category][$Setting] = Invoke-GPOTranslation -InputData $Output -Category $Category -Settings $Setting + } + } + $TranslatedOutput + } +} + +#Select-Properties -AllProperties -Objects ($Output.SecuritySettings.SecurityOptions | Where-Object { $_.Display -ne $null }) \ No newline at end of file diff --git a/Public/Select-GPOTranslation.ps1 b/Public/Select-GPOTranslation.ps1 new file mode 100644 index 0000000..9920105 --- /dev/null +++ b/Public/Select-GPOTranslation.ps1 @@ -0,0 +1,22 @@ +function Select-GPOTranslation { + [cmdletbInding()] + param( + [Parameter(ValueFromPipeline)][System.Collections.IDictionary] $InputObject, + [string] $Category, + [string] $Settings + ) + + $Important = [ordered] @{} + $AllProperties = Select-Properties -AllProperties -Objects $InputObject.$Category.$Settings + $MissingProperties = $AllProperties | Where-Object { $_ -notin 'DisplayName', 'DomainName', 'GUID', 'Linked', 'LinksCount', 'Links', 'GPOType', 'GPOCategory', 'GPOSettings' } + $Types = foreach ($Property in $MissingProperties) { + ($InputObject.$Category.$Settings | Where-Object { $null -ne $_.$Property }).$Property | ForEach-Object { + ($_ | Get-Member -MemberType Properties) | Where-Object { $_.Name -notin 'Length' } + } + } + $Important['AllProperties'] = $AllProperties + $Important['MissingProperties'] = $MissingProperties + $Important['Types'] = $Types | Select-Object -Unique + $Important['Data'] = $InputObject.$Category.$Settings + $Important +} \ No newline at end of file