From e5d897d354adde1710fa4d6c21244b0f84a6f046 Mon Sep 17 00:00:00 2001 From: Przemyslaw Klys Date: Wed, 28 Oct 2020 18:25:21 +0100 Subject: [PATCH] Update --- GPOZaurr.psd1 | 4 +- Private/Script.GPOConfiguration.NetLogon.ps1 | 65 ++++++++++++++++++++ Private/Script.GPOConfiguration.ps1 | 1 + Public/Get-GPOZaurrNetlogon.ps1 | 28 +++++---- Public/Invoke-GPOZaurr.ps1 | 22 ++----- Public/Repair-GPOZaurrNetLogonOwner.ps1 | 27 ++++++++ README.md | 2 + 7 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 Private/Script.GPOConfiguration.NetLogon.ps1 create mode 100644 Public/Repair-GPOZaurrNetLogonOwner.ps1 diff --git a/GPOZaurr.psd1 b/GPOZaurr.psd1 index ce3faa6..cc14a03 100644 --- a/GPOZaurr.psd1 +++ b/GPOZaurr.psd1 @@ -6,9 +6,9 @@ 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 fixing issues that you may find in them.' - FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrBroken', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrContent', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner') + FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrBroken', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrContent', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrNetLogonOwner', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner') GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde' - ModuleVersion = '0.0.68' + ModuleVersion = '0.0.69' PowerShellVersion = '5.1' PrivateData = @{ PSData = @{ diff --git a/Private/Script.GPOConfiguration.NetLogon.ps1 b/Private/Script.GPOConfiguration.NetLogon.ps1 new file mode 100644 index 0000000..6c86c46 --- /dev/null +++ b/Private/Script.GPOConfiguration.NetLogon.ps1 @@ -0,0 +1,65 @@ +$ScriptGPOConfigurationNetLogon = [ordered] @{ + List = { + New-HTMLListItem -Text 'NetLogon Files in Total: ', $NetLogonOwners.Count -FontWeight normal, bold + New-HTMLListItem -Text 'NetLogon BUILTIN\Administrators as Owner: ', $NetLogonOwnersAdministrators.Count -FontWeight normal, bold + New-HTMLListItem -Text "NetLogon Owners requiring change: ", $NetLogonOwnersToFix.Count -FontWeight normal, bold { + New-HTMLList -Type Unordered { + New-HTMLListItem -Text 'Not Administrative: ', $NetLogonOwnersNotAdministrative.Count -FontWeight normal, bold + New-HTMLListItem -Text 'Administrative, but not BUILTIN\Administrators: ', $NetLogonOwnersAdministrativeNotAdministrators.Count -FontWeight normal, bold + } + } + } + Wizard = { + New-HTMLWizardStep -Name 'Prepare environment' { + New-HTMLText -Text "To be able to execute actions in automated way please install required modules. Those modules will be installed straight from Microsoft PowerShell Gallery." + New-HTMLCodeBlock -Code { + Install-Module GPOZaurr -Force + Import-Module GPOZaurr -Force + } -Style powershell + New-HTMLText -Text "Using force makes sure newest version is downloaded from PowerShellGallery regardless of what is currently installed. Once installed you're ready for next step." + } + New-HTMLWizardStep -Name 'Prepare report' { + New-HTMLText -Text "Depending when this report was run you may want to prepare new report before proceeding with removal. To generate new report please use:" + New-HTMLCodeBlock -Code { + Invoke-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrNetLogonBefore.html -Verbose -Type NetLogon + } + New-HTMLText -TextBlock { + "When executed it will take a while to generate all data and provide you with new report depending on size of environment." + "Once confirmed that data is still showing issues and requires fixing please proceed with next step." + } + New-HTMLText -Text "Alternatively if you prefer working with console you can run: " + New-HTMLCodeBlock -Code { + $NetLogonOutput = Get-GPOZaurrNetLogon -Verbose + $NetLogonOutput | Format-Table + } + New-HTMLText -Text "It provides same data as you see in table above just doesn't prettify it for you." + } + New-HTMLWizardStep -Name 'Set non-compliant file owners to BUILTIN\Administrators' { + New-HTMLText -Text "Following command when executed runs internally command that lists all file owners and if it doesn't match changes it BUILTIN\Administrators. It doesn't change compliant owners." + New-HTMLText -Text "Make sure when running it for the first time to run it with ", "WhatIf", " parameter as shown below to prevent accidental removal." -FontWeight normal, bold, normal -Color Black, Red, Black + + New-HTMLCodeBlock -Code { + Repair-GPOZaurrNetLogonOwner -Verbose -WhatIf + } + New-HTMLText -TextBlock { + "After execution please make sure there are no errors, make sure to review provided output, and confirm that what is about to be changed matches expected data. Once happy with results please follow with command: " + } + New-HTMLCodeBlock -Code { + Repair-GPOZaurrNetLogonOwner -Verbose -LimitProcessing 2 + } + New-HTMLText -TextBlock { + "This command when executed sets new owner only on first X non-compliant NetLogon files. Use LimitProcessing parameter to prevent mass change and increase the counter when no errors occur." + "Repeat step above as much as needed increasing LimitProcessing count till there's nothing left. In case of any issues please review and action accordingly." + } + } + New-HTMLWizardStep -Name 'Verification report' { + New-HTMLText -TextBlock { + "Once cleanup task was executed properly, we need to verify that report now shows no problems." + } + New-HTMLCodeBlock -Code { + Invoke-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrNetLogonAfter.html -Verbose -Type NetLogon + } + New-HTMLText -Text "If everything is healthy in the report you're done! Enjoy rest of the day!" -Color BlueDiamond + } + } +} \ No newline at end of file diff --git a/Private/Script.GPOConfiguration.ps1 b/Private/Script.GPOConfiguration.ps1 index c0229b7..6531cd6 100644 --- a/Private/Script.GPOConfiguration.ps1 +++ b/Private/Script.GPOConfiguration.ps1 @@ -202,4 +202,5 @@ } } } + NetLogon = $ScriptGPOConfigurationNetLogon } \ No newline at end of file diff --git a/Public/Get-GPOZaurrNetlogon.ps1 b/Public/Get-GPOZaurrNetlogon.ps1 index 8ca9dcc..024774e 100644 --- a/Public/Get-GPOZaurrNetlogon.ps1 +++ b/Public/Get-GPOZaurrNetlogon.ps1 @@ -7,11 +7,12 @@ $ForestInformation = Get-WinADForestDetails -Extended $FilesAll = foreach ($Domain in $ForestInformation.Domains) { $Path = -join ("\\", $Domain, '\Netlogon') + $PathOnSysvol = -join ("\\", $Domain, "\SYSVOL\", $Domain, "\Scripts") $Files = Get-ChildItem -LiteralPath $Path -Recurse -Force foreach ($_ in $Files) { $ACL = Get-Acl -Path $_.FullName if ($ACL.Owner) { - $IdentityOwner = Convert-Identity -Identity $ACL.Owner + $IdentityOwner = Convert-Identity -Identity $ACL.Owner -Verbose:$false } else { $IdentityOwner = [PSCustomObject] @{ SID = ''; Type = 'Uknown' } } @@ -30,12 +31,13 @@ PrincipalType = $IdentityOwner.Type FileSystemRights = 'Owner' # : FullControl IsInherited = $false + FullNameOnSysVol = $_.FullName.Replace($Path, $PathOnSysvol) #Owner = $ACL.Owner } } - $FilePermission = Get-FilePermissions -Path $_.FullName -ACLS $ACL + $FilePermission = Get-FilePermissions -Path $_.FullName -ACLS $ACL -Verbose:$false foreach ($Perm in $FilePermission) { - $Identity = Convert-Identity -Identity $Perm.Principal + $Identity = Convert-Identity -Identity $Perm.Principal -Verbose:$false [PSCustomObject] @{ FullName = $_.FullName Extension = $_.Extension @@ -49,19 +51,21 @@ PrincipalType = $Identity.Type FileSystemRights = $Perm.FileSystemRights # : FullControl IsInherited = $Perm.IsInherited # : True + FullNameOnSysVol = $_.FullName.Replace($Path, $PathOnSysvol) } } } else { [PSCustomObject] @{ - FullName = $_.FullName - Extension = $_.Extension - CreationTime = $_.CreationTime - LastAccessTime = $_.LastAccessTime - LastWriteTime = $_.LastWriteTime - Attributes = $_.Attributes - Owner = $IdentityOwner.Name - OwnerSid = $IdentityOwner.SID - OwnerType = $IdentityOwner.Type + FullName = $_.FullName + Extension = $_.Extension + CreationTime = $_.CreationTime + LastAccessTime = $_.LastAccessTime + LastWriteTime = $_.LastWriteTime + Attributes = $_.Attributes + Owner = $IdentityOwner.Name + OwnerSid = $IdentityOwner.SID + OwnerType = $IdentityOwner.Type + FullNameOnSysVol = $_.FullName.Replace($Path, $PathOnSysvol) } } } diff --git a/Public/Invoke-GPOZaurr.ps1 b/Public/Invoke-GPOZaurr.ps1 index 28a276b..89d10f3 100644 --- a/Public/Invoke-GPOZaurr.ps1 +++ b/Public/Invoke-GPOZaurr.ps1 @@ -278,14 +278,7 @@ New-HTMLPanel { New-HTMLText -Text 'Following chart presents ', 'NetLogon Summary' -FontSize 10pt -FontWeight normal, bold New-HTMLList -Type Unordered { - New-HTMLListItem -Text 'NetLogon Files in Total: ', $NetLogonOwners.Count -FontWeight normal, bold - New-HTMLListItem -Text 'NetLogon BUILTIN\Administrators as Owner: ', $NetLogonOwnersAdministrators.Count -FontWeight normal, bold - New-HTMLListItem -Text "NetLogon Owners requiring change: ", $NetLogonOwnersToFix.Count -FontWeight normal, bold { - New-HTMLList -Type Unordered { - New-HTMLListItem -Text 'Not Administrative: ', $NetLogonOwnersNotAdministrative.Count -FontWeight normal, bold - New-HTMLListItem -Text 'Administrative, but not BUILTIN\Administrators: ', $NetLogonOwnersAdministrativeNotAdministrators.Count -FontWeight normal, bold - } - } + & $Script:GPOConfiguration['NetLogon']['List'] } -FontSize 10pt #New-HTMLText -FontSize 10pt -Text 'Those problems must be resolved before doing other clenaup activities.' New-HTMLChart { @@ -387,14 +380,7 @@ "That's why as a best-practice it's recommended to change any non-administrative owners to BUILTIN\Administrators, and even Administrative accounts should be replaced with it. " } -FontSize 10pt New-HTMLList -Type Unordered { - New-HTMLListItem -Text 'NetLogon Files in Total: ', $NetLogonOwners.Count -FontWeight normal, bold - New-HTMLListItem -Text 'NetLogon BUILTIN\Administrators as Owner: ', $NetLogonOwnersAdministrators.Count -FontWeight normal, bold - New-HTMLListItem -Text "NetLogon Owners requiring change: ", $NetLogonOwnersToFix.Count -FontWeight normal, bold { - New-HTMLList -Type Unordered { - New-HTMLListItem -Text 'Not Administrative: ', $NetLogonOwnersNotAdministrative.Count -FontWeight normal, bold - New-HTMLListItem -Text 'Administrative, but not BUILTIN\Administrators: ', $NetLogonOwnersAdministrativeNotAdministrators.Count -FontWeight normal, bold - } - } + & $Script:GPOConfiguration['NetLogon']['List'] } -FontSize 10pt New-HTMLText -Text "Follow the steps below table to get NetLogon Owners into compliant state." -FontSize 10pt } @@ -405,12 +391,12 @@ New-HTMLTableCondition -Name 'PrincipalType' -Value "WellKnownAdministrative" -BackgroundColor LightGreen -ComparisonType string -Operator eq } } - New-HTMLSection -Name 'Steps to fix - Owners ' { + New-HTMLSection -Name 'Steps to fix NetLogon Owners ' { New-HTMLContainer { New-HTMLSpanStyle -FontSize 10pt { New-HTMLText -Text 'Following steps will guide you how to fix NetLogon Owners and make them compliant.' New-HTMLWizard { - #& $Script:GPOConfiguration['GPOOrphans']['Wizard'] + & $Script:GPOConfiguration['NetLogon']['Wizard'] } -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center } } diff --git a/Public/Repair-GPOZaurrNetLogonOwner.ps1 b/Public/Repair-GPOZaurrNetLogonOwner.ps1 new file mode 100644 index 0000000..09c772e --- /dev/null +++ b/Public/Repair-GPOZaurrNetLogonOwner.ps1 @@ -0,0 +1,27 @@ +function Repair-GPOZaurrNetLogonOwner { + [cmdletBinding(SupportsShouldProcess)] + param( + [alias('ForestName')][string] $Forest, + [string[]] $ExcludeDomains, + [alias('Domain', 'Domains')][string[]] $IncludeDomains, + [System.Collections.IDictionary] $ExtendedForestInformation, + + [string] $Principal = 'S-1-5-32-544', + [int] $LimitProcessing = [int32]::MaxValue + ) + $Identity = Convert-Identity -Identity $Principal -Verbose:$false + if ($Identity.Error) { + Write-Warning "Repair-GPOZaurrNetLogonOwner - couldn't convert Identity $Principal to desired name. Error: $($Identity.Error)" + return + } + $Principal = $Identity.Name + Get-GPOZaurrNetLogon -OwnerOnly | Select-Object -First $LimitProcessing | Where-Object { + if ($_.OwnerSid -ne 'S-1-5-32-544') { + $_ + } + } | ForEach-Object { + if ($PSCmdlet.ShouldProcess($_.FullName, "Setting NetLogon Owner to $($Principal)")) { + Set-FileOwner -JustPath -Path $_.FullName -Owner $Principal -Verbose:$true -WhatIf:$WhatIfPreference + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 96508ae..00d2eb3 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ That's it. Whenever there's a new version, you run the command, and you can enjo ## Changelog +- 0.0.69 - Unreleased + - Added `Repair-GPOZaurrNetLogonOwner` - 0.0.68 - 28.10.2020 - Renamed `Show-GPOZaurr` to `Invoke-GPOZaurr` - Renamed `Invoke-GPOZaurr` to `Invoke-GPOZaurrContent`