diff --git a/Examples/Example-26-Files.ps1 b/Examples/Example-26-Files.ps1 new file mode 100644 index 0000000..7c91373 --- /dev/null +++ b/Examples/Example-26-Files.ps1 @@ -0,0 +1,10 @@ +Clear-Host +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +$Output = Get-GPOZaurrSysvol | ForEach-Object { + $Path = $_.Path + Get-ChildItem -Path $Path -ErrorAction SilentlyContinue -Recurse -ErrorVariable err -File | ForEach-Object { + Get-FileMetaData -File $_ -Signature -HashAlgorithm 'SHA256' + } +} +$Output | Format-Table \ No newline at end of file diff --git a/Examples/Example-27-FindGPO.ps1 b/Examples/Example-27-FindGPO.ps1 new file mode 100644 index 0000000..f84f992 --- /dev/null +++ b/Examples/Example-27-FindGPO.ps1 @@ -0,0 +1,5 @@ +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-28-SaveGPO.ps1 b/Examples/Example-28-SaveGPO.ps1 new file mode 100644 index 0000000..d0ec303 --- /dev/null +++ b/Examples/Example-28-SaveGPO.ps1 @@ -0,0 +1,3 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExport \ No newline at end of file diff --git a/Examples/Example-29-FindGPOfromDisk.ps1 b/Examples/Example-29-FindGPOfromDisk.ps1 new file mode 100644 index 0000000..d531536 --- /dev/null +++ b/Examples/Example-29-FindGPOfromDisk.ps1 @@ -0,0 +1,14 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +# Use Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExport + +$Output = Find-GPO -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' +$Output | Format-Table * + +New-HTML { + foreach ($Key in $Output.Keys) { + New-HTMLTab -Name $Key { + New-HTMLTable -DataTable $Output[$Key] -ScrollX -DisablePaging -AllProperties -Title $Key + } + } +} -Online -ShowHTML -FilePath $Env:UserProfile\Desktop\OutputFromFindGPO.html \ No newline at end of file diff --git a/Private/Get-LinksFromXML.ps1 b/Private/Get-LinksFromXML.ps1 new file mode 100644 index 0000000..57dbf10 --- /dev/null +++ b/Private/Get-LinksFromXML.ps1 @@ -0,0 +1,38 @@ +function Get-LinksFromXML { + [cmdletBinding()] + param( + [System.Xml.XmlElement[]] $GPOOutput, + [string] $Splitter, + [switch] $FullObjects + ) + $Links = [ordered] @{ + Linked = $null + LinksCount = $null + Links = $null + } + if ($GPOOutput.LinksTo) { + $Links.Linked = $true + $Links.LinksCount = ([Array] $GPOOutput.LinksTo).Count + $Links.Links = foreach ($Link in $GPOOutput.LinksTo) { + if ($FullObjects) { + [PSCustomObject] @{ + Path = $Link.SOMPath + Enabled = if ($Link.Enabled -eq 'true') { $true } else { $false } + NoOverride = if ($Link.NoOverride -eq 'true') { $true } else { $false } + } + } else { + if ($Link.Enabled) { + $Link.SOMPath + } + } + } + if ($Splitter) { + $Links.Links = $Links.Links -join $Splitter + } + } else { + $Links.Linked = $false + $Links.LinksCount = 0 + $Links.Links = $null + } + [PSCustomObject] $Links +} \ No newline at end of file diff --git a/Private/Get-XMLAutologon.ps1 b/Private/Get-XMLAutologon.ps1 index 3e0a2c8..8df4cfe 100644 --- a/Private/Get-XMLAutologon.ps1 +++ b/Private/Get-XMLAutologon.ps1 @@ -2,57 +2,61 @@ [cmdletBinding()] param( [PSCustomObject] $GPO, - [System.Xml.XmlElement[]] $GPOOutput + [System.Xml.XmlElement[]] $GPOOutput, + [string] $Splitter = [System.Environment]::NewLine, + [switch] $FullObjects ) - if ($GPOOutput.LinksTo) { - $Linked = $true - $LinksCount = ([Array] $GPOOutput.LinksTo).Count - } else { - $Linked = $false - $LinksCount = 0 - } + $LinksInformation = Get-LinksFromXML -GPOOutput $GPOOutput -Splitter $Splitter -FullObjects:$FullObjects foreach ($Type in @('User', 'Computer')) { - if ($GPOOutput.$Type.ExtensionData.Extension.RegistrySettings) { - foreach ($Key in $GPOOutput.$Type.ExtensionData.Extension.RegistrySettings.Registry) { - #$Key - <# - clsid : {9CD4B2F4-923D-47f5-A062-E897DD1DAD50} - name : AutoAdminLogon - status : AutoAdminLogon - image : 7 - changed : 2013-02-06 09:57:45 - uid : {23AD1B6F-0D90-49B5-926D-AAA6E1E2F4B3} - GPOSettingOrder : 1 - Properties : Properties - Filters : - #> - - <# $Key.properties - action : U - displayDecimal : 0 - default : 0 - hive : HKEY_LOCAL_MACHINE - key : SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon - name : AutoAdminLogon - type : REG_SZ - value : 1 - Values : - #> - [PSCustomObject] @{ - DisplayName = $GPO.DisplayName - DomainName = $GPO.DomainName - GUID = $GPO.Guid - Linked = $Linked - LinksCount = $LinksCount - Changed = [DateTime] $Key.changed - GPOSettingOrder = $Key.GPOSettingOrder - hive = $Key.Properties.hive #: HKEY_LOCAL_MACHINE - key = $Key.Properties.key #: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon - name = $Key.Properties.name #: AutoAdminLogon - type = $Key.Properties.type #: REG_SZ - value = $Key.Properties.value # - Filters = $Key.Filters + if ($GPOOutput.$Type.ExtensionData.Extension) { + foreach ($ExtensionType in $GPOOutput.$Type.ExtensionData.Extension) { + if ($ExtensionType.RegistrySettings.Registry.Properties.Key -ne 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon') { + continue } + $Autologon = [ordered] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + GUID = $GPO.Guid + Linked = $LinksInformation.Linked + LinksCount = $LinksInformation.LinksCount + Links = $LinksInformation.Links + AutoAdminLogon = $null + DefaultDomainName = $null + DefaultUserName = $null + DefaultPassword = $null + } + foreach ($Key in $ExtensionType.RegistrySettings.Registry) { + if ($Key.Properties.key -eq 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon') { + <# + [PSCustomObject] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + GUID = $GPO.Guid + Linked = $Linked + LinksCount = $LinksCount + GpoType = $Type + Changed = [DateTime] $Key.changed + GPOSettingOrder = $Key.GPOSettingOrder + hive = $Key.Properties.hive #: HKEY_LOCAL_MACHINE + key = $Key.Properties.key #: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon + name = $Key.Properties.name #: AutoAdminLogon + type = $Key.Properties.type #: REG_SZ + value = $Key.Properties.value # + Filters = $Key.Filters + } + #> + if ($Key.Properties.Name -eq 'AutoAdminLogon') { + $Autologon['AutoAdminLogon'] = [bool] $Key.Properties.value + } elseif ($Key.Properties.Name -eq 'DefaultDomainName') { + $Autologon['DefaultDomainName'] = $Key.Properties.value + } elseif ($Key.Properties.Name -eq 'DefaultUserName') { + $Autologon['DefaultUserName'] = $Key.Properties.value + } elseif ($Key.Properties.Name -eq 'DefaultPassword') { + $Autologon['DefaultPassword'] = $Key.Properties.value + } + } + } + [PSCustomObject] $Autologon } } } diff --git a/Private/Get-XMLLocalUserGroups.ps1 b/Private/Get-XMLLocalUserGroups.ps1 index b2081f4..0fdee3c 100644 --- a/Private/Get-XMLLocalUserGroups.ps1 +++ b/Private/Get-XMLLocalUserGroups.ps1 @@ -1,17 +1,12 @@ - -function Get-XMLLocalUserGroups { +function Get-XMLLocalUserGroups { [cmdletBinding()] param( [PSCustomObject] $GPO, - [System.Xml.XmlElement[]] $GPOOutput + [System.Xml.XmlElement[]] $GPOOutput, + [string] $Splitter = [System.Environment]::NewLine, + [switch] $FullObjects ) - if ($GPOOutput.LinksTo) { - $Linked = $true - $LinksCount = ([Array] $GPOOutput.LinksTo).Count - } else { - $Linked = $false - $LinksCount = 0 - } + $LinksInformation = Get-LinksFromXML -GPOOutput $GPOOutput -Splitter $Splitter -FullObjects:$FullObjects foreach ($Type in @('User', 'Computer')) { if ($GPOOutput.$Type.ExtensionData.Extension.LocalUsersAndGroups) { foreach ($NestedType in @('User', 'Group')) { @@ -24,8 +19,9 @@ function Get-XMLLocalUserGroups { DisplayName = $GPO.DisplayName DomainName = $GPO.DomainName GUID = $GPO.Guid - Linked = $Linked - LinksCount = $LinksCount + Linked = $LinksInformation.Linked + LinksCount = $LinksInformation.LinksCount + Links = $LinksInformation.Links GpoType = $Type Name = $Entry.name Changed = [DateTime] $Entry.changed @@ -59,8 +55,9 @@ function Get-XMLLocalUserGroups { DisplayName = $GPO.DisplayName DomainName = $GPO.DomainName GUID = $GPO.Guid - Linked = $Linked - LinksCount = $LinksCount + Linked = $LinksInformation.Linked + LinksCount = $LinksInformation.LinksCount + Links = $LinksInformation.Links GpoType = $Type Name = $Entry.name Changed = [DateTime] $Entry.changed diff --git a/Private/Get-XMLRegistryPolicies.ps1 b/Private/Get-XMLRegistryPolicies.ps1 new file mode 100644 index 0000000..bee0387 --- /dev/null +++ b/Private/Get-XMLRegistryPolicies.ps1 @@ -0,0 +1,41 @@ +function Get-XMLRegistryPolicies { + [cmdletBinding()] + param( + [PSCustomObject] $GPO, + [System.Xml.XmlElement[]] $GPOOutput, + [string] $Splitter = [System.Environment]::NewLine, + [switch] $FullObjects + ) + $LinksInformation = Get-LinksFromXML -GPOOutput $GPOOutput -Splitter $Splitter -FullObjects:$FullObjects + foreach ($Type in @('User', 'Computer')) { + if ($GPOOutput.$Type.ExtensionData.Extension) { + foreach ($ExtensionType in $GPOOutput.$Type.ExtensionData.Extension) { + foreach ($Key in $ExtensionType.Policy) { + [PSCustomObject] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + GUID = $GPO.Guid + Linked = $LinksInformation.Linked + LinksCount = $LinksInformation.LinksCount + Links = $LinksInformation.Links + GpoType = $Type + PolicyName = $Key.Name + PolicyState = $Key.State + PolicyCategory = $Key.Category + PolicySupported = $Key.Supported + PolicyExplain = $Key.Explain + PolicyCheckBox = $Key.CheckBox + PolicyText = $Key.Text + DropDownList = $Key.DropDownList + PolicyEditText = $Key.EditText + <# + Name State Value + ---- ----- ----- + Target group name for this computer Enabled de00_wsus3_measuring_devices + #> + } + } + } + } + } +} \ No newline at end of file diff --git a/Private/Get-XMLRegistrySettings.ps1 b/Private/Get-XMLRegistrySettings.ps1 new file mode 100644 index 0000000..58326fe --- /dev/null +++ b/Private/Get-XMLRegistrySettings.ps1 @@ -0,0 +1,35 @@ +function Get-XMLRegistrySettings { + [cmdletBinding()] + param( + [PSCustomObject] $GPO, + [System.Xml.XmlElement[]] $GPOOutput, + [string] $Splitter = [System.Environment]::NewLine, + [switch] $FullObjects + ) + $LinksInformation = Get-LinksFromXML -GPOOutput $GPOOutput -Splitter $Splitter -FullObjects:$FullObjects + foreach ($Type in @('User', 'Computer')) { + if ($GPOOutput.$Type.ExtensionData.Extension) { + foreach ($ExtensionType in $GPOOutput.$Type.ExtensionData.Extension) { + foreach ($Key in $ExtensionType.RegistrySettings.Registry) { + [PSCustomObject] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + GUID = $GPO.Guid + Linked = $LinksInformation.Linked + LinksCount = $LinksInformation.LinksCount + Links = $LinksInformation.Links + GpoType = $Type + Changed = [DateTime] $Key.changed + GPOSettingOrder = $Key.GPOSettingOrder + Hive = $Key.Properties.hive #: HKEY_LOCAL_MACHINE + Key = $Key.Properties.key #: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon + Name = $Key.Properties.name #: AutoAdminLogon + Type = $Key.Properties.type #: REG_SZ + Value = $Key.Properties.value # + Filters = $Key.Filters + } + } + } + } + } +} \ No newline at end of file diff --git a/Private/Get-XMLScripts.ps1 b/Private/Get-XMLScripts.ps1 new file mode 100644 index 0000000..1c389b9 --- /dev/null +++ b/Private/Get-XMLScripts.ps1 @@ -0,0 +1,49 @@ +function Get-XMLScripts { + [cmdletBinding()] + param( + [PSCustomObject] $GPO, + [System.Xml.XmlElement[]] $GPOOutput, + [string] $Splitter = [System.Environment]::NewLine, + [switch] $FullObjects + ) + $LinksInformation = Get-LinksFromXML -GPOOutput $GPOOutput -Splitter $Splitter -FullObjects:$FullObjects + foreach ($Type in @('User', 'Computer')) { + if ($GPOOutput.$Type.ExtensionData.Extension) { + foreach ($ExtensionType in $GPOOutput.$Type.ExtensionData.Extension) { + foreach ($Key in $ExtensionType.Script) { + if ($FullObjects) { + [PSCustomObject] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + GUID = $GPO.Guid + Linked = $LinksInformation.Linked + LinksCount = $LinksInformation.LinksCount + Links = $LinksInformation.Links + GpoType = $Type + Command = $Key.Command + Parameters = $Key.Parameters + Type = $Key.Type + Order = $Key.Order + RunOrder = $Key.RunOrder + } + } else { + [PSCustomObject] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + GUID = $GPO.Guid + Linked = $LinksInformation.Linked + LinksCount = $LinksInformation.LinksCount + Links = $LinksInformation.Links + GpoType = $Type + Command = $Key.Command + Parameters = $Key.Parameters + type = $Key.Type + Order = $Key.Order + RunOrder = $Key.RunOrder + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Public/Find-GPO.ps1 b/Public/Find-GPO.ps1 new file mode 100644 index 0000000..14ceecd --- /dev/null +++ b/Public/Find-GPO.ps1 @@ -0,0 +1,108 @@ +function Find-GPO { + [cmdletBinding(DefaultParameterSetName = 'Default')] + param( + [Parameter(ParameterSetName = 'Default')][alias('ForestName')][string] $Forest, + [Parameter(ParameterSetName = 'Default')][string[]] $ExcludeDomains, + [Parameter(ParameterSetName = 'Default')][alias('Domain', 'Domains')][string[]] $IncludeDomains, + [Parameter(ParameterSetName = 'Default')][System.Collections.IDictionary] $ExtendedForestInformation, + + [Parameter(ParameterSetName = 'Local')][string] $GPOPath, + + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] + [ValidateSet('LocalUsersAndGroups', 'Autologon', 'RegistrySettings', 'RegistryPolicies', 'Scripts')][string[]] $Type = @( + 'LocalUsersAndGroups' + 'Autologon' + 'RegistrySettings' + 'RegistryPolicies' + 'Scripts' + ), + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] + [string] $Splitter = [System.Environment]::NewLine, + [switch] $FullObjects + ) + if ($GPOPath) { + if (Test-Path -LiteralPath $GPOPath) { + <# + $GPOListPath = [io.path]::Combine($GPOPath, "GPOList.xml") + if ($GPOListPath) { + $GPOs = Import-Clixml -Path $GPOListPath + } else { + + } + #> + $GPOFiles = Get-ChildItem -LiteralPath $GPOPath -Recurse -File + [Array] $GPOs = foreach ($File in $GPOFiles) { + if ($File.Name -ne 'GPOList.xml') { + [xml] $GPORead = Get-Content -LiteralPath $File.FullName + [PSCustomObject] @{ + DisplayName = $GPORead.GPO.Name + DomainName = $GPORead.GPO.Identifier.Domain.'#text' + GUID = $GPORead.GPO.Identifier.Identifier.'#text' -replace '{' -replace '}' + GPOOutput = $GPORead + } + } + } + } else { + Write-Warning "Find-GPO - $GPOPath doesn't exists." + return + } + } else { + [Array] $GPOs = Get-GPOZaurrAD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation + } + $Output = [ordered] @{} + foreach ($T in $Type) { + $Output[$T] = [System.Collections.Generic.List[PSCustomObject]]::new() + } + foreach ($GPO in $GPOs) { + if ($GPOPath) { + $GPOOutput = $GPO.GPOOutput + } else { + [xml] $GPOOutput = Get-GPOReport -Guid $GPO.GUID -Domain $GPO.DomainName -ReportType Xml + } + <# + [PSCustomobject] @{ + DisplayName = $GPO.DisplayName + DomainName = $GPO.DomainName + ComputerEnabled = $GPOOutput.GPO.Computer.Enabled + ComputerEmpty = if ($GPOOutput.GPO.Computer.ExtensionData) { $false } else { $true } + ComputerPolicies = $GPOOutput.GPO.Computer.ExtensionData.Name -join ", " + UserEnabled = $GPOOutput.GPO.User.Enabled + UserEmpty = if ($GPOOutput.GPO.User.ExtensionData) { $false } else { $true } + UserPolicies = $GPOOutput.GPO.User.ExtensionData.Name -join ", " + } + #> + if ($Type -contains 'RegistrySettings') { + [Array] $Data = Get-XMLRegistrySettings -GPO $GPO -GPOOutput $GPOOutput.GPO -Splitter $Splitter -FullObjects:$FullObjects + foreach ($D in $Data) { + $Output['RegistrySettings'].Add($D) + } + } + if ($Type -contains 'RegistryPolicies') { + [Array] $Data = Get-XMLRegistryPolicies -GPO $GPO -GPOOutput $GPOOutput.GPO -Splitter $Splitter -FullObjects:$FullObjects + foreach ($D in $Data) { + $Output['RegistryPolicies'].Add($D) + } + } + if ($Type -contains 'LocalUsersAndGroups') { + [Array] $Data = Get-XMLLocalUserGroups -GPO $GPO -GPOOutput $GPOOutput.GPO -Splitter $Splitter -FullObjects:$FullObjects + foreach ($D in $Data) { + $Output['LocalUsersAndGroups'].Add($D) + } + } + if ($Type -contains 'AutoLogon') { + [Array] $Data = Get-XMLAutologon -GPO $GPO -GPOOutput $GPOOutput.GPO -Splitter $Splitter -FullObjects:$FullObjects + foreach ($D in $Data) { + $Output['AutoLogon'].Add($D) + } + } + if ($Type -contains 'Scripts') { + [Array] $Data = Get-XMLScripts -GPO $GPO -GPOOutput $GPOOutput.GPO -Splitter $Splitter -FullObjects:$FullObjects + foreach ($D in $Data) { + $Output['Scripts'].Add($D) + } + } + } + $Output +} \ No newline at end of file diff --git a/README.md b/README.md index f5f3f9e..4d0cf31 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ That's it. Whenever there's a new version, you run the command, and you can enjo - 0.0.46 - Unreleased - Additional protection for `Get-GPOZaurrAD` for CNF duplicates + - Update to `Save-GPOZaurrFiles` + - Added `Find-GPO` (heavy work in progress) - 0.0.45 - 26.06.2020 - During publishing ADEssentials required functions are now merged to prevent cyclic dependency bug [Using ModuleSpec syntax in RequiredModules causes incorrect "cyclic dependency" failures](https://github.com/PowerShell/PowerShell/issues/2607) - 0.0.44 - 24.06.2020