From c856484932f63d081a4a273eebb3aa82e50f3320 Mon Sep 17 00:00:00 2001 From: Przemyslaw Klys Date: Tue, 21 Jul 2020 20:31:40 +0200 Subject: [PATCH] Update --- ...Example-20-RemoveOrphanedFoldersSysvol.ps1 | 4 +- Examples/Example-29-FindGPO0.ps1 | 15 +- Examples/Example-30-AssesSyvolFiles.ps1 | 4 + GPOZaurr.psd1 | 2 +- Public/Get-GPOZaurrFiles.ps1 | 160 +++++++++++++----- Public/Invoke-GPOZaurr.ps1 | 2 - .../Remove-GPOZaurrOrphanedSysvolFolders.ps1 | 44 ++++- 7 files changed, 174 insertions(+), 57 deletions(-) create mode 100644 Examples/Example-30-AssesSyvolFiles.ps1 diff --git a/Examples/Example-20-RemoveOrphanedFoldersSysvol.ps1 b/Examples/Example-20-RemoveOrphanedFoldersSysvol.ps1 index 43f5b76..d1f46c6 100644 --- a/Examples/Example-20-RemoveOrphanedFoldersSysvol.ps1 +++ b/Examples/Example-20-RemoveOrphanedFoldersSysvol.ps1 @@ -1,7 +1,7 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force # this allows you to process X amount of orphaned folders/files (good for testing) -Remove-GPOZaurrOrphanedSysvolFolders -Verbose -WhatIf -LimitProcessing 2 +Remove-GPOZaurrOrphanedSysvolFolders -Verbose -WhatIf -LimitProcessing 2 -IncludeDomains 'ad.evotec.xyz' # this runs for whole SYSVOL and checks things against GPOS -Remove-GPOZaurrOrphanedSysvolFolders -Verbose -WhatIf \ No newline at end of file +Remove-GPOZaurrOrphanedSysvolFolders -Verbose -IncludeDomains 'ad.evotec.xyz' -BackupPath $Env:UserProfile\Desktop\MyBackup -WhatIf \ No newline at end of file diff --git a/Examples/Example-29-FindGPO0.ps1 b/Examples/Example-29-FindGPO0.ps1 index 1d4f7a0..3c46065 100644 --- a/Examples/Example-29-FindGPO0.ps1 +++ b/Examples/Example-29-FindGPO0.ps1 @@ -3,7 +3,7 @@ #Invoke-GPOZaurr -OutputType Excel, Object, HTML -Open | Format-Table #$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport -NoTranslation #| Format-Table #$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTestRegistryCheck' -NoTranslation -$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -NoTranslation +$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -NoTranslation -Verbose #$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExport' -NoTranslation #-OutputType HTML, Object -Open #| Format-Table #$Output.Categories | Out-HtmlView #$Output.Categories | Format-Table @@ -23,8 +23,11 @@ $Output.Reports | Format-Table #$Output.Reports.SecurityOptions | Format-Table * #$Output.Reports.SystemServices | Format-Table * #$Output.Reports.SystemServicesNT | Format-Table * -$Output.Reports.LocalUsers | Format-Table * -$Output.Reports.LocalGroups | Format-Table * +#$Output.Reports.LocalUsers | Format-Table * +#$Output.Reports.LocalGroups | Format-Table * +#$Output.Reports.DriveMapping | Format-Table * +#$Output.Reports.Printers | Format-Table * +$Output.Reports.TaskScheduler | Format-Table * return # This is section that treats 1 GPO as single object - if there are 5 scripts in 1 GPO there's only one value @@ -38,5 +41,7 @@ $Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportT #$Output.Reports.SecurityOptions | Format-Table * #$Output.Reports.SystemServices | Format-Table * #$Output.Reports.SystemServicesNT | Format-Table * -$Output.Reports.LocalUsers | Format-Table * -$Output.Reports.LocalGroups | Format-Table * \ No newline at end of file +#$Output.Reports.LocalUsers | Format-Table * +#$Output.Reports.LocalGroups | Format-Table * +#$Output.Reports.DriveMapping | Format-Table * +$Output.Reports.Printers | Format-Table * \ No newline at end of file diff --git a/Examples/Example-30-AssesSyvolFiles.ps1 b/Examples/Example-30-AssesSyvolFiles.ps1 new file mode 100644 index 0000000..72aea58 --- /dev/null +++ b/Examples/Example-30-AssesSyvolFiles.ps1 @@ -0,0 +1,4 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +$Files = Get-GPOZaurrFiles -Limited -Signature +$Files | ConvertTo-Excel -OpenWorkBook -FilePath $Env:USERPROFILE\Desktop\GPOTesting.xlsx -ExcelWorkSheetName 'GPO Output' -AutoFilter -AutoFit -FreezeTopRowFirstColumn \ No newline at end of file diff --git a/GPOZaurr.psd1 b/GPOZaurr.psd1 index 4147fdc..04f53a4 100644 --- a/GPOZaurr.psd1 +++ b/GPOZaurr.psd1 @@ -17,7 +17,7 @@ } } RequiredModules = @{ - ModuleVersion = '0.0.159' + ModuleVersion = '0.0.160' ModuleName = 'PSSharedGoods' Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe' }, @{ diff --git a/Public/Get-GPOZaurrFiles.ps1 b/Public/Get-GPOZaurrFiles.ps1 index de61d13..f4c879e 100644 --- a/Public/Get-GPOZaurrFiles.ps1 +++ b/Public/Get-GPOZaurrFiles.ps1 @@ -3,7 +3,10 @@ param( [ValidateSet('All', 'Netlogon', 'Sysvol')][string[]] $Type = 'All', [ValidateSet('None', 'MACTripleDES', 'MD5', 'RIPEMD160', 'SHA1', 'SHA256', 'SHA384', 'SHA512')][string] $HashAlgorithm = 'None', + [switch] $Signature, [switch] $Limited, + [switch] $AsHashTable, + [switch] $Extended, [alias('ForestName')][string] $Forest, [string[]] $ExcludeDomains, [alias('Domain', 'Domains')][string[]] $IncludeDomains, @@ -48,7 +51,7 @@ Name = 'NETLOGON Scripts' } } - Get-ChildItem -Path $Path -ErrorAction SilentlyContinue -Recurse -ErrorVariable err -File | ForEach-Object { + Get-ChildItem -Path $Path -ErrorAction SilentlyContinue -Recurse -ErrorVariable err -File -Force | ForEach-Object { # Lets reset values just to be sure those are empty $GPO = $null $BelongsToGPO = $false @@ -70,35 +73,89 @@ $GPODisplayName = $GPO.DisplayName } } + $Correct = @( + [System.IO.Path]::Combine($GPO.Path, 'GPT.INI') + [System.IO.Path]::Combine($GPO.Path, 'GPO.cmt') + [System.IO.Path]::Combine($GPO.Path, 'Group Policy', 'GPE.ini') + foreach ($TypeM in @('Machine', 'User')) { + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Registry.pol') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'comment.cmtx') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Registry\Registry.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Printers\Printers.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\ScheduledTasks\ScheduledTasks.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Services\Services.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Groups\Groups.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\RegionalOptions\RegionalOptions.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\FolderOptions\FolderOptions.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Drives\Drives.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\InternetSettings\InternetSettings.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Folders\Folders.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\PowerOptions\PowerOptions.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Shortcuts\Shortcuts.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Files\Files.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\EnvironmentVariables\EnvironmentVariables.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\NetworkOptions\NetworkOptions.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\DataSources\DataSources.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\NetworkShares\NetworkShares.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\StartMenuTaskbar\StartMenuTaskbar.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Applications\Microsoft\TBLayout.xml') + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Applications\Microsoft\DefaultApps.xml') + if ($_.Extension -eq '.aas') { + [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Applications', $_.Name) + } + } + [System.IO.Path]::Combine($GPO.Path, 'Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf') + [System.IO.Path]::Combine($GPO.Path, 'Machine\Microsoft\Windows NT\Audit\audit.csv') + ) if ($GPO) { - $Correct = @( - [System.IO.Path]::Combine($GPO.Path, 'GPT.INI') - [System.IO.Path]::Combine($GPO.Path, 'GPO.cmt') - foreach ($TypeM in @('Machine', 'User')) { - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Registry\Registry.xml') - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Printers\Printers.xml') - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Registry.pol') - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'comment.cmtx') - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\ScheduledTasks\ScheduledTasks.xml') - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Services\Services.xml') - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Preferences\Groups\Groups.xml') - - if ($_.Extension -eq '.aas') { - [System.IO.Path]::Combine($GPO.Path, $TypeM, 'Applications', $_.Name) + if ($_.FullName -in $Correct) { + $SuggestedAction = 'Skip assesment' + $SuggestedActionComment = 'Correctly placed in SYSVOL' + } elseif ($_.Extension -eq '.adm') { + $SuggestedAction = 'Consider deleting' + $SuggestedActionComment = 'Most likely legacy ADM files' + } + if (-not $SuggestedAction) { + foreach ($Ext in @('*old*', '*bak*', '*bck')) { + if ($_.Extension -like $Ext) { + $SuggestedAction = 'Consider deleting' + $SuggestedActionComment = 'Most likely backup files' + break } } - [System.IO.Path]::Combine($GPO.Path, 'Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf') - [System.IO.Path]::Combine($GPO.Path, 'Machine\Microsoft\Windows NT\Audit\audit.csv') - ) + } + if (-not $SuggestedAction) { + <# + $IEAK = @( + 'microsoft\IEAK\install.ins' + 'MICROSOFT\IEAK\BRANDING\cs\connect.ras' + 'microsoft\IEAK\BRANDING\cs\connect.set' + 'microsoft\IEAK\BRANDING\cs\cs.dat' + 'microsoft\IEAK\BRANDING\ADM\inetcorp.iem' + 'microsoft\IEAK\BRANDING\ADM\inetcorp.inf' + 'microsoft\IEAK\install.ins' + 'microsoft\IEAK\BRANDING\favs\Outlook.ico' + 'microsoft\IEAK\BRANDING\favs\Bio.ico' + 'MICROSOFT\IEAK\BRANDING\favs\$fi380.ico' + 'microsoft\IEAK\BRANDING\PROGRAMS\programs.inf' + 'MICROSOFT\IEAK\BRANDING\RATINGS\ratings.inf' + 'MICROSOFT\IEAK\BRANDING\RATINGS\ratrsop.inf' + 'microsoft\IEAK\BRANDING\ZONES\seczones.inf' + 'microsoft\IEAK\BRANDING\ZONES\seczrsop.inf' + 'microsoft\IEAK\BRANDING\ZONES\seczrsop.inf' + ) + #> + if ($_.FullName -like '*microsoft\IEAK*') { + # https://docs.microsoft.com/en-us/internet-explorer/ie11-deploy-guide/missing-internet-explorer-maintenance-settings-for-ie11#:~:text=The%20Internet%20Explorer%20Maintenance%20(IEM,Internet%20Explorer%2010%20or%20newer. + $SuggestedAction = 'Consider deleting whole GPO' + $SuggestedActionComment = 'Internet Explorer Maintenance (IEM) is deprecated for IE 11' + } + } } else { - $Correct = @() - } - if ($_.FullName -in $Correct) { - $SuggestedAction = 'Skip assesment' - $SuggestedActionComment = 'Correctly placed in SYSVOL' - } elseif ($_.Extension -eq '.adm') { - $SuggestedAction = 'Consider deleting' - $SuggestedActionComment = 'Most likely legacy ADM files' + if ($_.FullName -in $Correct) { + $SuggestedAction = 'Consider deleting' + $SuggestedActionComment = 'Most likely orphaned SYSVOL GPO - Investigate' + } } } elseif ($FileType.Name -eq 'NETLOGON Scripts') { foreach ($Ext in @('*old*', '*bak*', '*bck')) { @@ -119,7 +176,7 @@ } } if (-not $SuggestedAction) { - foreach ($Name in @('*old*', '*bak*', '*bck*', '*Copy*')) { + foreach ($Name in @('*old*', '*bak*', '*bck*', '*Copy', '*backup*')) { if ($_.Name -like $Name) { $SuggestedAction = 'Consider deleting' $SuggestedActionComment = 'FileName contains backup related names' @@ -167,26 +224,47 @@ $SuggestedActionComment = 'Not able to auto asses' } if ($Limited) { - $MetaData = $_ + $MetaData = [ordered] @{ + LocationType = $FileType.Name + FullName = $_.FullName + #Name = $_.Name + Extension = $_.Extension + SuggestedAction = $SuggestedAction + SuggestedActionComment = $SuggestedActionComment + BelongsToGPO = $BelongsToGPO + GPODisplayName = $GPODisplayName + Attributes = $_.Attributes + CreationTime = $_.CreationTime + LastAccessTime = $_.LastAccessTime + LastWriteTime = $_.LastWriteTime + } } else { - $MetaData = Get-FileMetaData -File $_ -Signature #-HashAlgorithm $HashAlgorithm + $MetaData = Get-FileMetaData -File $_ -AsHashTable } - Add-Member -InputObject $MetaData -Name 'AssesmentType' -Value $FileType.Name -MemberType NoteProperty - Add-Member -InputObject $MetaData -Name 'BelongsToGPO' -Value $BelongsToGPO -MemberType NoteProperty - Add-Member -InputObject $MetaData -Name 'GPODisplayName' -Value $GPODisplayName -MemberType NoteProperty - Add-Member -InputObject $MetaData -Name 'SuggestedAction' -Value $SuggestedAction -MemberType NoteProperty - Add-Member -InputObject $MetaData -Name 'SuggestedActionComment' -Value $SuggestedActionComment -MemberType NoteProperty - - if ($Limited) { - $MetaData | Select-Object FullName, Name, Extension, SuggestedAction, SuggestedActionComment, AssesmentType, BelongsToGPO, GPODisplayName, IsReadOnly, CreationTime, LastAccessTime, LastWriteTime - } else { + if ($Signature) { + $DigitalSignature = Get-AuthenticodeSignature -FilePath $_.Fullname + $MetaData['SignatureStatus'] = $DigitalSignature.Status + $MetaData['IsOSBinary'] = $DigitalSignature.IsOSBinary + $MetaData['SignatureCertificateSubject'] = $DigitalSignature.SignerCertificate.Subject + if ($Extended) { + $MetaData['SignatureCertificateIssuer'] = $DigitalSignature.SignerCertificate.Issuer + $MetaData['SignatureCertificateSerialNumber'] = $DigitalSignature.SignerCertificate.SerialNumber + $MetaData['SignatureCertificateNotBefore'] = $DigitalSignature.SignerCertificate.NotBefore + $MetaData['SignatureCertificateNotAfter'] = $DigitalSignature.SignerCertificate.NotAfter + $MetaData['SignatureCertificateThumbprint'] = $DigitalSignature.SignerCertificate.Thumbprint + } + } + if ($HashAlgorithm -ne 'None') { + $MetaData['ChecksumSHA256'] = (Get-FileHash -LiteralPath $_.FullName -Algorithm $HashAlgorithm).Hash + } + if ($AsHashTable) { $MetaData + } else { + [PSCustomObject] $MetaData } } foreach ($e in $err) { Write-Warning "Get-GPOZaurrFiles - $($e.Exception.Message) ($($e.CategoryInfo.Reason))" } } -} - -#Get-GPOZaurrFiles -Limited | ConvertTo-Excel -OpenWorkBook -FilePath $Env:USERPROFILE\GPOTesting.xlsx -ExcelWorkSheetName 'GPO Output' -AutoFilter -AutoFit -FreezeTopRowFirstColumn \ No newline at end of file +} \ No newline at end of file diff --git a/Public/Invoke-GPOZaurr.ps1 b/Public/Invoke-GPOZaurr.ps1 index 8c95159..c099a4f 100644 --- a/Public/Invoke-GPOZaurr.ps1 +++ b/Public/Invoke-GPOZaurr.ps1 @@ -144,8 +144,6 @@ } } } - - return $Output <# foreach ($GPO in $GPOs) { diff --git a/Public/Remove-GPOZaurrOrphanedSysvolFolders.ps1 b/Public/Remove-GPOZaurrOrphanedSysvolFolders.ps1 index b767e3f..db74065 100644 --- a/Public/Remove-GPOZaurrOrphanedSysvolFolders.ps1 +++ b/Public/Remove-GPOZaurrOrphanedSysvolFolders.ps1 @@ -1,13 +1,45 @@ function Remove-GPOZaurrOrphanedSysvolFolders { [cmdletBinding(SupportsShouldProcess)] param( - [int] $LimitProcessing = [int32]::MaxValue + [string] $BackupPath, + [switch] $BackupDated, + [int] $LimitProcessing = [int32]::MaxValue, + + [alias('ForestName')][string] $Forest, + [string[]] $ExcludeDomains, + [alias('Domain', 'Domains')][string[]] $IncludeDomains, + [System.Collections.IDictionary] $ExtendedForestInformation ) - Get-GPOZaurrSysvol | Where-Object { - if ($_.Status -eq 'Orphaned GPO') { - $_ + Begin { + if ($BackupPath) { + if ($BackupDated) { + $BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))" + } else { + $BackupFinalPath = $BackupPath + } + } else { + $BackupFinalPath = '' + } + } + Process { + Get-GPOZaurrSysvol -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation | Where-Object { + if ($_.Status -eq 'Orphaned GPO') { + $_ + } + } | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object { + Write-Verbose "Remove-GPOZaurrOrphanedSysvolFolders - Processing $($_.Path)" + if ($BackupFinalPath) { + Try { + Copy-Item -LiteralPath $_.Path -Recurse -Destination $BackupFinalPath -ErrorAction Stop + $BackupWorked = $true + } catch { + Write-Warning "Remove-GPOZaurrOrphanedSysvolFolders - Error backing up error: $($_.Exception.Message)" + $BackupWorked = $false + } + } + if ($BackupWorked) { + Remove-Item -Recurse -Force -LiteralPath $_.Path + } } - } | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object { - Remove-Item -Recurse -Force -LiteralPath $_.Path } } \ No newline at end of file