diff --git a/Examples/Example-29-FindGPO1.ps1 b/Examples/Example-29-FindGPO1.ps1 index d52d986..0622b56 100644 --- a/Examples/Example-29-FindGPO1.ps1 +++ b/Examples/Example-29-FindGPO1.ps1 @@ -1,5 +1,13 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +#$O = Invoke-GPOZaurrContent -GPOName "Test-RestrictedGroups" -Verbose +#$O + +Invoke-GPOZaurr -Online -Type GPOBroken, GPOBrokenLink -Verbose -SplitReports + +return + #$Output = Invoke-GPOZaurrContent -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPODefender' $Output = Invoke-GPOZaurrContent -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExport' -Type WindowsHelloForBusiness $Output | Format-Table diff --git a/Examples/Example-51-FindEmptyOUsWithGPOLinks.ps1 b/Examples/Example-51-FindEmptyOUsWithGPOLinks.ps1 index 789e418..9fa4ae0 100644 --- a/Examples/Example-51-FindEmptyOUsWithGPOLinks.ps1 +++ b/Examples/Example-51-FindEmptyOUsWithGPOLinks.ps1 @@ -3,6 +3,8 @@ $OUs = Get-GPOZaurrOrganizationalUnit $Ous | Format-Table +return + Get-GPOZaurrOrganizationalUnit -Verbose -Option Unlink -Exclusions @( 'OU=Groups,OU=Production,DC=ad,DC=evotec,DC=pl' ) | Format-Table diff --git a/Examples/Example-59-ADMX.ps1 b/Examples/Example-59-ADMX.ps1 new file mode 100644 index 0000000..2cd6a30 --- /dev/null +++ b/Examples/Example-59-ADMX.ps1 @@ -0,0 +1,19 @@ +Import-Module .\GPOZaurr.psd1 -Force + +$DirectoryPath = "C:\Support\GitHub\GpoZaurr\Data\ADMXTemplates" +$Paths = @( + [PSCustomObject] @{ Name = "Citrix"; Path = "C:\Program Files (x86)\Citrix\ICA Client\Configuration"; ExportFile = "Citrix" } + [PSCustomObject] @{ Name = "Remote Desktop Manager"; Path = "C:\Program Files\Devolutions\Remote Desktop Manager\Policies" ; ExportFile = "Remote Desktop Manager" } + [PSCustomObject] @{ Name = "Microsoft Windows 2022 Security Baseline"; Path = "C:\Users\przemyslaw.klys\Downloads\GPO\Windows Server 2022 Security Baseline\Windows Server-2022-Security-Baseline-FINAL\Templates" ; ExportFile = "Windows Server 2022 Security Baseline" } + [PSCustomObject] @{ Name = "Microsoft OneDrive"; Path = "C:\Program Files\Microsoft OneDrive\24.216.1027.0003\adm" ; ExportFile = "Microsoft OneDrive" } + [PSCustomObject] @{ Name = "Microsoft PowerShell 7 Core"; Path = "C:\Program Files\PowerShell\7" ; ExportFile = "Microsoft PowerShell 7" } + [PSCustomObject] @{ Name = "Microsoft Windows 11 (24H2) September 2024"; Path = "C:\Program Files (x86)\Microsoft Group Policy\Windows 11 Sep 2024 Update (24H2)" ; ExportFile = "Microsoft Windows11 24H2 September 2024" } +) +foreach ($Path in $Paths) { + $InitializeGPOZaurrTemplateSplat = @{ + Path = $Path.Path + Name = $Path.Name + ExportPath = "$DirectoryPath\$($Path.ExportFile).json" + } + $List = Initialize-GPOZaurrTemplate @InitializeGPOZaurrTemplateSplat -Verbose +} \ No newline at end of file diff --git a/GPOZaurr.psd1 b/GPOZaurr.psd1 index c5143eb..4753d0f 100644 --- a/GPOZaurr.psd1 +++ b/GPOZaurr.psd1 @@ -6,9 +6,9 @@ CompatiblePSEditions = @('Desktop') Copyright = '(c) 2011 - 2024 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 fixing issues that you may find in them.' - FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Export-GPOZaurrContent', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrBroken', 'Get-GPOZaurrBrokenLink', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrDuplicateObject', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrMissingFiles', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOrganizationalUnit', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionAnalysis', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionIssue', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrRedirect', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrUpdates', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrContent', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Optimize-GPOZaurr', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrDuplicateObject', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrLinkEmptyOU', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrBrokenLink', 'Repair-GPOZaurrNetLogonOwner', 'Repair-GPOZaurrPermission', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Set-GPOZaurrStatus', 'Skip-GroupPolicy') + FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Export-GPOZaurrContent', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrTemplates', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrBroken', 'Get-GPOZaurrBrokenLink', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrDuplicateObject', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrMissingFiles', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOrganizationalUnit', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionAnalysis', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionIssue', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrRedirect', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrUpdates', 'Get-GPOZaurrWMI', 'Initialize-GPOZaurrTemplate', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrContent', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Optimize-GPOZaurr', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrDuplicateObject', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrLinkEmptyOU', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrBrokenLink', 'Repair-GPOZaurrNetLogonOwner', 'Repair-GPOZaurrPermission', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Set-GPOZaurrStatus', 'Skip-GroupPolicy') GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde' - ModuleVersion = '1.1.8' + ModuleVersion = '1.1.9' PowerShellVersion = '5.1' PrivateData = @{ PSData = @{ diff --git a/Public/Get-GPOZaurrADMX.ps1 b/Public/Get-GPOZaurrADMX.ps1 new file mode 100644 index 0000000..840b1be --- /dev/null +++ b/Public/Get-GPOZaurrADMX.ps1 @@ -0,0 +1,17 @@ +function Get-GPOZaurrTemplates { + [CmdletBinding()] + param( + + ) + + + $SysvolADMXPath = "\\$env:USERDNSDOMAIN\SYSVOL\$env:USERDNSDOMAIN\Policies\PolicyDefinitions" + Get-ChildItem -Path $SysvolADMXPath -Filter "*.admx" -Recurse -File | ForEach-Object { + [PSCustomObject]@{ + Name = $_.Name + Path = $_.FullName + Size = $_.Length + LastWriteTime = $_.LastWriteTime + } + } +} \ No newline at end of file diff --git a/Public/Initialize-GPOZaurrTemplate.ps1 b/Public/Initialize-GPOZaurrTemplate.ps1 new file mode 100644 index 0000000..6471333 --- /dev/null +++ b/Public/Initialize-GPOZaurrTemplate.ps1 @@ -0,0 +1,72 @@ +function Initialize-GPOZaurrTemplate { + [CmdletBinding()] + param( + [Parameter(Mandatory)][string] $Name, + [Parameter(Mandatory)][string] $Path, + [string] $ExportPath + ) + + $Files = Get-ChildItem -Path $Path -Filter "*.admx" -Recurse -File + $TotalFiles = $Files.Count + $ProgressIncrement = [math]::Ceiling($TotalFiles / 10) + $CurrentProgress = 0 + + $FullList = foreach ($File in $Files) { + $CurrentProgress++ + if ($CurrentProgress % $ProgressIncrement -eq 0) { + Write-Verbose ("Initialize-GPOZaurrTemplate - Processing $Name, template file {0} of {1} ({2}%)" -f $CurrentProgress, $TotalFiles, [math]::Round(($CurrentProgress / $TotalFiles) * 100)) + } + $HashInformation = Get-FileHash -LiteralPath $File.FullName + $Directories = Get-ChildItem -Path $File.DirectoryName -Directory + $Languages = [ordered] @{} + foreach ($Directory in $Directories) { + $LanguageFile = [io.path]::Combine($Directory.FullName, $File.BaseName + ".adml") + $Item = Get-Item -Path $LanguageFile -ErrorAction SilentlyContinue + if (Test-Path -Path $LanguageFile) { + $HashInformation = Get-FileHash -LiteralPath $LanguageFile + $Languages[$Directory.Name] = [PSCustomObject]@{ + Name = $Directory.Name + Hash = $HashInformation.Hash + Algorithm = $HashInformation.Algorithm + Size = $Item.Length + CreationTimeUtc = $Item.CreationTimeUtc + LastWriteTimeUtc = $Item.LastWriteTimeUtc + } + } + } + [PSCustomObject] @{ + Name = $File.Name + Hash = $HashInformation.Hash + Algorithm = $HashInformation.Algorithm + Size = $File.Length + LanguagesAvailable = $Languages.Keys + LanguagesCount = $Languages.Keys.Count + CreationTimeUtc = $File.CreationTimeUtc + LastWriteTimeUtc = $File.LastWriteTimeUtc + LanguageFile = $Languages + } + } + + $OutputObject = [PSCustomObject] @{ + Name = $Name + Path = $Path + Templates = $FullList + } + if ($ExportPath) { + if ($ExportPath.EndsWith('.xml')) { + $ExportType = 'XML' + } elseif ($ExportPath.EndsWith('.json')) { + $ExportType = 'JSON' + } else { + $ExportType = 'XML' + } + if ($ExportType -eq 'XML') { + $OutputObject | Export-Clixml -Path $ExportPath -ErrorAction Stop + } elseif ($ExportType -eq 'JSON') { + $OutputObject | ConvertTo-Json -Depth 10 | Set-Content -Path $ExportPath -ErrorAction Stop + } else { + Write-Warning "ExportType $ExportType is not supported. Exporting to XML." + } + } + $OutputObject +} \ No newline at end of file