Compare commits

...

61 Commits

Author SHA1 Message Date
Przemyslaw Klys f5cf5dac4d Update 2020-10-22 14:00:46 +02:00
Przemyslaw Klys 5ffe89dec3 Update 2020-10-22 14:00:15 +02:00
Przemyslaw Klys 191b709ccf Update 2020-10-22 13:42:27 +02:00
Przemyslaw Klys b3e15d66ea Update 2020-10-22 10:51:37 +02:00
Przemyslaw Klys b3751d1dcc Update 2020-10-22 09:17:01 +02:00
Przemyslaw Klys 928d66eb9d Update 2020-10-22 09:16:07 +02:00
Przemyslaw Klys 72ecf97497 new release 2020-10-21 13:17:37 +02:00
Przemyslaw Klys aa8773ce73 Update 2020-10-21 12:48:37 +02:00
Przemyslaw Klys 6f11155914 Update 2020-10-20 22:49:22 +02:00
Przemyslaw Klys fd5413164a Update 2020-10-20 21:02:54 +02:00
Przemyslaw Klys 295f2e0a48 Update 2020-10-19 10:41:39 +02:00
Przemyslaw Klys 13e5672b3f Update 2020-10-19 10:38:55 +02:00
Przemyslaw Klys a0723227c0 Update share permissions 2020-10-19 00:06:02 +02:00
Przemyslaw Klys 72b2d2482b update functions 2020-10-19 00:05:50 +02:00
Przemyslaw Klys 0c12761601 Update 2020-10-18 20:17:06 +02:00
Przemyslaw Klys 4ca5c8f1e7 Update 2020-10-17 09:28:58 +02:00
Przemyslaw Klys 53cdbdded7 Update 2020-10-14 13:23:29 +02:00
Przemyslaw Klys bed9da4367 Update 2020-10-14 09:53:01 +02:00
Przemyslaw Klys 1226c2758d Update 2020-10-13 15:29:55 +02:00
Przemyslaw Klys 8b2e655723 Update Invoke-GPOZaurr 2020-10-13 15:29:38 +02:00
Przemyslaw Klys 1061484247 Update 2020-10-13 00:14:14 +02:00
Przemyslaw Klys b4f014855b Update 2020-10-13 00:13:57 +02:00
Przemyslaw Klys 8b1bdfd39b update 2020-10-09 11:26:31 +02:00
Przemyslaw Klys 1f43ec4d66 Updated Get-GPOZaurrFiles for lack of access 2020-10-08 20:16:30 +02:00
Przemyslaw Klys f3f5b22090 Update 2020-10-04 21:30:27 +02:00
Przemyslaw Klys eb47bcd4b0 Update 2020-10-04 21:20:23 +02:00
Przemyslaw Klys 87a91bd632 Update 2020-10-04 20:58:58 +02:00
Przemyslaw Klys d0bd7b1cdc Update 2020-10-01 22:52:28 +02:00
Przemyslaw Klys dfff00d4cf Update 2020-10-01 21:35:10 +02:00
Przemyslaw Klys ba5a7e1549 Update 2020-10-01 21:35:00 +02:00
Przemyslaw Klys b126f397f7 Update 2020-10-01 21:34:42 +02:00
Przemyslaw Klys afd8e052de Update 2020-09-29 12:17:59 +02:00
Przemyslaw Klys 52edd47532 Update 2020-09-29 12:13:14 +02:00
Przemyslaw Klys da5fbf8341 Update 2020-09-29 09:47:02 +02:00
Przemyslaw Klys 6129aa6818 Update 2020-09-20 19:45:45 +02:00
Przemyslaw Klys 041639f430 Update 2020-09-20 19:45:33 +02:00
Przemyslaw Klys 12f79247dd Improvement to PSD1 2020-09-20 19:16:11 +02:00
Przemyslaw Klys a957bc6450 Update 2020-09-20 17:05:11 +02:00
Przemyslaw Klys fb5b9c5024 Update 2020-09-20 17:03:59 +02:00
Przemyslaw Klys cb2dfe0a0f Adresses issue with Get-GPOZaurrPermissionConsistency
if sysvol doesn't exists
2020-09-20 17:01:50 +02:00
Przemyslaw Klys e2950af1b6 Update 2020-08-31 08:33:53 +02:00
Przemyslaw Klys 1b70d39984 Update 2020-08-28 09:49:26 +02:00
Przemyslaw Klys 91d3776403 Update to Find-CSExtension 2020-08-28 09:30:09 +02:00
Przemyslaw Klys b4748918f5 Update to ConvertFrom-CSExtension 2020-08-28 09:29:42 +02:00
Przemyslaw Klys a1d8393060 Updated examples 2020-08-28 08:28:53 +02:00
Przemyslaw Klys 4a519004f5 Update 2020-08-26 13:24:00 +02:00
Przemyslaw Klys 8234c6cf50 Update 2020-08-26 13:22:23 +02:00
Przemyslaw Klys f50a495690 Update 2020-08-26 12:55:56 +02:00
Przemyslaw Klys 6c2e29122e Update 2020-08-26 12:55:06 +02:00
Przemyslaw Klys 250683e830 Update 2020-08-26 09:55:43 +02:00
Przemyslaw Klys 0f04582b42 Improvement to Get-GPOZaurrPermissionSummary 2020-08-26 09:55:16 +02:00
Przemyslaw Klys d9de90718d update readme 2020-08-26 08:41:12 +02:00
Przemyslaw Klys e8651b71fd PSD1 update 2020-08-26 08:40:52 +02:00
Przemyslaw Klys ecdd6fb8ec Update Summary 2020-08-26 08:40:13 +02:00
Przemyslaw Klys 945e993843 Update 2020-08-25 12:37:40 +02:00
Przemyslaw Klys fdf78ecadb Added Get-GPOZaurrPermissionSummary report 2020-08-25 12:37:03 +02:00
Przemyslaw Klys fc9b191578 Update 2020-08-17 13:12:00 +02:00
Przemyslaw Klys 04e5eaf63c Fix for Inheritance 2020-08-17 13:11:18 +02:00
Przemyslaw Klys 494b1582ca Update 2020-08-17 10:00:47 +02:00
Przemyslaw Klys c33b820e36 Update 2020-08-16 22:28:08 +02:00
Przemyslaw Klys cfeb0098a6 Update 2020-08-16 22:17:08 +02:00
54 changed files with 2821 additions and 853 deletions
@@ -1,4 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$T = Get-GPOZaurrPermission -GPOName 'Default Domain Policy' -Type 'All'
$T = Get-GPOZaurrPermission -GPOName 'Default Domain Policy' -Type 'All' -IncludeOwner
$T | Format-Table *
@@ -1,4 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$T = Get-GPOZaurrPermission -Type Unknown -Verbose
$T | Format-Table *
$T | Out-HtmlView -ScrollX -Filtering -DisablePaging -ScrollY -Online
@@ -1,14 +1,14 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
# This Example shows how to deal with GPOs that have owner that doesn't exists anymore (deleted userr or diff domain) - EmptyOrUnknown
# This Example shows how to deal with GPOs that have owner that doesn't exists anymore (deleted userr or diff domain) - Unknown
# And also can fix at the same time NotAdministrative - this basically looks for users/groups that are not Domain Admins or Enterprise Admins
# regardless if current user is still Domain Admin or not
$GPOs = Get-GPOZaurrOwner -IncludeSysvol #-GPOName
$GPOs | Format-Table DisplayName, Owner, OwnerSID, OwnerType, SysvolOwner, SysvolSID, SysvolType
$GPOs | Format-Table DisplayName, Owner, OwnerSID, OwnerType, SysvolOwner, SysvolSID, SysvolType
#Set-GPOZaurrOwner -Type Unknown -Verbose #-LimitProcessing 2 -WhatIf
Set-GPOZaurrOwner -Type NotAdministrative -Verbose -LimitProcessing 2 -WhatIf
Set-GPOZaurrOwner -Type NotAdministrative -Verbose -LimitProcessing 2 -WhatIf
#Set-GPOZaurrOwner -Type NotMatching -Verbose -LimitProcessing 2 -WhatIf
#Set-GPOZaurrOwner -GPOName 'COMPUTERS | Enable Sets' -Verbose -Principal 'przemyslaw.klys' -WhatIf #-SkipSysvol
@@ -2,4 +2,4 @@
Get-GPOZaurrPermissionConsistency -GPOName 'Default Domain Controllers Policy' -IncludeDomains 'ad.evotec.xyz'
Repair-GPOZaurrPermissionConsistency -GPOName 'Default Domain Controllers Policy' -IncludeDomains 'ad.evotec.xyz' -Verbose #-WhatIf -Verbose
Repair-GPOZaurrPermissionConsistency -GPOName 'Default Domain Controllers Policy' -IncludeDomains 'ad.evotec.xyz' -Verbose -WhatIf
@@ -1,5 +1,5 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrPermissionConsistency -Type All | Format-Table
Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance | Format-Table
Repair-GPOZaurrPermissionConsistency -LimitProcessing 2 -WhatIf -Verbose
+2 -1
View File
@@ -1,3 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrSysvol -Verbose | Format-Table
Get-GPOZaurrSysvol -Verbose | Format-Table
#Get-GPOZaurrSysvol | Out-HtmlView -ScrollX
@@ -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 -IncludeDomains 'ad.evotec.xyz'
Remove-GPOZaurrOrphaned -Verbose -WhatIf -IncludeDomains 'ad.evotec.xyz' #-LimitProcessing 2
# this runs for whole SYSVOL and checks things against GPOS
Remove-GPOZaurrOrphanedSysvolFolders -Verbose -IncludeDomains 'ad.evotec.xyz' -BackupPath $Env:UserProfile\Desktop\MyBackup1 #-WhatIf
Remove-GPOZaurrOrphaned -Verbose -IncludeDomains 'ad.evotec.xyz' -BackupPath $Env:UserProfile\Desktop\MyBackup1 -WhatIf
+1 -2
View File
@@ -1,4 +1,3 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
#Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExport -DeleteExisting
Save-GPOZaurrFiles -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportEvotec' #-DeleteExisting
Save-GPOZaurrFiles -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportEvotec' -DeleteExisting -Verbose
-12
View File
@@ -1,12 +0,0 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
# Asses GPO based on exported data
$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport -Verbose
#$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -Verbose
$Output | Format-Table *
# Export to Excel
foreach ($Key in $Output.Reports.Keys) {
$Output.Reports[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
}
Start-Process "$Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx"
+9 -7
View File
@@ -1,20 +1,22 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportEvotec1'
#$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPODefender'
$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExport' -Type WindowsHelloForBusiness
$Output | Format-Table
$Output.Reports.RegistrySettings | Format-Table *
$Output.Reports.InternetExplorerZones | Format-Table *
$Output.WindowsDefenderExploitGuard | Format-Table
$Output.Reports.RegistrySetting | Format-Table
# Report to Excel of translated reports
foreach ($Key in $Output.Reports.Keys) {
$Output.Reports[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\GPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
foreach ($Key in $Output.Keys) {
$Output[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\GPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
}
# Report to HTML of translated reports
New-HTML {
foreach ($Key in $Output.Reports.Keys) {
New-HTMLTableOption -DataStore JavaScript
foreach ($Key in $Output.Keys) {
New-HTMLTab -Name $Key {
New-HTMLTable -DataTable $Output.Reports[$Key] -Filtering
New-HTMLTable -DataTable $Output[$Key] -Filtering -Title $Key
}
}
} -FilePath $Env:USERPROFILE\Desktop\GPOAnalysis.html -ShowHTML -Online
+1 -1
View File
@@ -2,7 +2,7 @@
# This gets the same thing as earlier examples
# with a difference where one entry per gpo and all settings for that GPO is stored under settings property.
$Output = Invoke-GPOZaurr -SingleObject
$Output = Invoke-GPOZaurr -SingleObject -Verbose
$Output | Format-Table
$Output.Reports.RegistrySettings | Format-Table *
$Output.Reports.RegistrySettings[0].Settings | Format-Table *
+4 -2
View File
@@ -1,9 +1,11 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
# Use Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExportAudit
$Output = Invoke-GPOZaurr -GPOPath $ENV:USERPROFILE\Desktop\GPOExportAudit -Verbose #-SkipCleanup #-Type PoliciesPrinters, Policies
$Output | Format-Table *
# This will allow you to process offline data more than once
# It's useful for when you want to request different types
$Output = Invoke-GPOZaurr -GPOPath $ENV:USERPROFILE\Desktop\GPOExportAudit -Extended -Verbose
$Output | Format-Table *
$Output.Reports | Format-Table
# Export to Excel
+4
View File
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$Output = Invoke-GPOZaurr -Verbose -OutputType HTML, Object -Open
$Output | Format-Table
+23
View File
@@ -0,0 +1,23 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
# Asses GPO based on exported data
$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport_2020.10.12 -Verbose -Type RegistrySetting
$Output | Format-Table *
# Export to Excel
foreach ($Key in $Output.Keys) {
$Output[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
}
# Show the Excel
Start-Process "$Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx"
# Show HTML
New-HTML {
New-HTMLTableOption -DataStore JavaScript
foreach ($Key in $Output.Keys) {
New-HTMLTab -Name $Key {
New-HTMLTable -DataTable $Output[$Key] -Filtering -Title $Key
}
}
} -FilePath $Env:USERPROFILE\Desktop\EFGPOAnalysis.html -ShowHTML -Online
+4
View File
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$Output = Invoke-GPOZaurr -GPOPath $ENV:USERPROFILE\Desktop\GPOTestingUserAccess -Verbose
$Output | Format-Table *
+79 -3
View File
@@ -1,5 +1,81 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Invoke-GPOZaurrSupport -ComputerName 'AD1' -UserName 'przemyslaw.klys' -Type HTML
#$Support
# $Support.ComputerResults.GPO | select name, @{LABEL=”LinkOrder“;EXPRESSION={$_.link.linkorder}} | sort linkorder
Invoke-GPOZaurrSupport -ComputerName 'ad1.ad.evotec.xyz' -UserName 'EVOTEC\przemyslaw.klys' -Type NativeHTML -ForceGPResult -Verbose
return
#$Support1 = Invoke-GPOZaurrSupport -ComputerName 'AD1' -UserName 'przemyslaw.klys' -Type Object
#$Support = Invoke-GPOZaurrSupport -ComputerName 'AD1' -UserName 'EVOTEC\Administrator' -Type Object
#$Support.ComputerResults.ExtensionData
foreach ($GpoType in @('UserResults', 'ComputerResults')) {
if ($Support.$GpoType.ExtensionData) {
foreach ($Extension in $Support.$GpoType.ExtensionData) {
$GPOSettingTypeSplit = ($Extension.type -split ':')
#$Extension
#$Extension | Get-Member -MemberType Properties -ErrorAction Stop
$KeysToLoop = $Extension | Get-Member -MemberType Properties -ErrorAction Stop | Where-Object { $_.Name -notin @($GPOSettingTypeSplit[0], 'xmlns', 'blocked', 'type') }
foreach ($GpoSettings in $KeysToLoop.Name) {
$Extension.$GpoSettings | Format-Table
}
}
}
}
# $env:LOGONSERVER
# if($env:LOGONSERVER -match "MicrosoftAccount") {"Logged on with Windows account"}
# If it reports \\MicrosoftAccount, they are using their Windows account to sign in instead of domain credentials.
#You can check this by using the IF statement as shown here:
#[System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
#[System.DirectoryServices.ActiveDirectory.DomainController]::
# https://concurrency.com/blog/may-2018/domain-controller-selection
#echo %logonserver% - This shows the DC that was used to authenticate and log in the current user
#nltest /dsgetsite - This shows the AD site that the current server has detected that it's in
#nltest /dclist: (include the colon at the end) - This shows the list of DCs in the current domain, including which site each is in.
# nslookup -type=srv _ldap._tcp.mydomain.local. - This will query the primary DNS server for all domain controller SRV records. This should return all of the DCs in the domain. In this example, MGLABDC4 and MGLABDC5 are returned.
# nslookup -type=srv _ldap._tcp.mysitename._sites.dc._msdcs.mydomain.local. - This will query the primary DNS server for domain controllers that are registered in "mysitename". In this example, only MGLABDC4 is in the site that was queried, which matches the information we found with nltest /dclist: previously.
# Windows 10
#Add-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'
#Add-WindowsCapability -Online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0'
#Remove-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'
Write-Output %logonserver%
nltest /dsgetsite
nltest /dclist:
$env:LOGONSERVER
[System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
nslookup -type=srv _ldap._tcp.ad.colmore.com.
nslookup -type=srv _ldap._tcp.birmingham._sites.dc._msdcs.ad.colmore.com.
function Get-PreData {
param(
)
[PSCustomObject] @{
Site = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
}
}
function Get-ComputerDataInformation {
[cmdletBinding()]
param(
[string] $ComputerName = $Env:COMPUTERNAME
)
[PSCustomObject] @{
Bios = Get-ComputerBios -ComputerName $ComputerName
Network = Get-ComputerNetwork -ComputerName $ComputerName
NetworkCard = Get-ComputerNetworkCard -ComputerName $ComputerName
}
}
Get-ComputerDataInformation -ComputerName 'AD1.AD.EVOTEC.XYZ'
#Get-ComputerNetwork -ComputerName 'AD1.AD.EVOTEC.XYZ' #| Format-Table
+4
View File
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
ConvertFrom-CSExtension -CSE '{FC715823-C5FB-11D1-9EEF-00A0C90347FF}'
ConvertFrom-CSExtension -CSE '{A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B}'
@@ -0,0 +1,10 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
# Default Permissions:
# 'GpoApply', 'GpoEdit', 'GPOCustom', 'GpoEditDeleteModifySecurity', 'GPORead'
# If you want to see also owners
# 'GpoOwner'
# If you want to include Root Level Permissions
# 'GpoRootCreate', 'GpoRootOwner'
$SummaryPermission = Get-GPOZaurrPermissionSummary -IncludePermissionType 'GpoCustom', 'GpoEdit', 'GpoEditDeleteModifySecurity', 'GpoOwner', 'GpoRootCreate', 'GpoRootOwner'
$SummaryPermission | Sort-Object -Property Permission | Format-Table
@@ -0,0 +1,3 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrPermissionRoot -Verbose | Format-Table *
+4
View File
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$FilesAll = Get-GPOZaurrNetlogon
$FilesAll | Format-Table -a *
+20 -15
View File
@@ -1,29 +1,34 @@
@{
AliasesToExport = 'Get-GPOZaurrFilesPolicyDefinitions', 'Find-GPO'
AliasesToExport = @('Get-GPOZaurrSysvol', 'Get-GPOZaurrFilesPolicyDefinitions', 'Find-GPO', 'Remove-GPOZaurrOrphaned')
Author = 'Przemyslaw Klys'
CmdletsToExport = @()
CompanyName = 'Evotec'
CompatiblePSEditions = 'Desktop'
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-GPOZaurrDictionary', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrSysvol', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrFolders', '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', '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-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', 'Show-GPOZaurr')
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
ModuleVersion = '0.0.52'
ModuleVersion = '0.0.66'
PowerShellVersion = '5.1'
PrivateData = @{
PSData = @{
Tags = 'Windows', 'ActiveDirectory', 'GPO', 'GroupPolicy'
Tags = @('Windows', 'ActiveDirectory', 'GPO', 'GroupPolicy')
ProjectUri = 'https://github.com/EvotecIT/GPOZaurr'
ExternalModuleDependencies = 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility'
ExternalModuleDependencies = @('CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility')
}
}
RequiredModules = @{
ModuleVersion = '0.0.166'
ModuleName = 'PSSharedGoods'
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
}, @{
ModuleVersion = '0.0.66'
ModuleName = 'ADEssentials'
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
}, 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility'
RequiredModules = @(@{
ModuleVersion = '0.0.186'
ModuleName = 'PSSharedGoods'
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
}, @{
ModuleVersion = '0.0.99'
ModuleName = 'ADEssentials'
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
}, @{
ModuleVersion = '0.0.116'
ModuleName = 'PSWriteHTML'
Guid = 'a7bdf640-f5cb-4acf-9de0-365b322d245c'
}, 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility')
RootModule = 'GPOZaurr.psm1'
}
+88 -32
View File
@@ -1,39 +1,95 @@
function ConvertTo-XMLAccountPolicy {
[cmdletBinding()]
param(
[PSCustomObject] $GPO
[PSCustomObject] $GPO,
[switch] $SingleObject
)
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
ClearTextPassword = 'Not Set'
LockoutBadCount = 'Not Set'
LockoutDuration = 'Not Set'
MaximumPasswordAge = 'Not Set'
MinimumPasswordAge = 'Not Set'
MinimumPasswordLength = 'Not Set'
PasswordComplexity = 'Not Set'
PasswordHistorySize = 'Not Set'
ResetLockoutCount = 'Not Set'
MaxClockSkew = 'Not Set'
MaxRenewAge = 'Not Set'
MaxServiceAge = 'Not Set'
MaxTicketAge = 'Not Set'
TicketValidateClient = 'Not Set'
}
foreach ($GPOEntry in $GPO.DataSet) {
if ($GPOEntry.SettingBoolean) {
$CreateGPO[$($GPOEntry.Name)] = if ($GPOEntry.SettingBoolean -eq 'true') { 'Enabled' } elseif ($GPOEntry.SettingBoolean -eq 'false') { 'Disabled' } else { 'Not set' };
} elseif ($GPOEntry.SettingNumber) {
$CreateGPO[$($GPOEntry.Name)] = [int] $GPOEntry.SettingNumber
if ($SingleObject) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
Count = 0
Settings = $null
}
[Array] $CreateGPO['Settings'] = @(
$Settings = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
ClearTextPassword = 'Not Set'
LockoutBadCount = 'Not Set'
LockoutDuration = 'Not Set'
MaximumPasswordAge = 'Not Set'
MinimumPasswordAge = 'Not Set'
MinimumPasswordLength = 'Not Set'
PasswordComplexity = 'Not Set'
PasswordHistorySize = 'Not Set'
ResetLockoutCount = 'Not Set'
MaxClockSkew = 'Not Set'
MaxRenewAge = 'Not Set'
MaxServiceAge = 'Not Set'
MaxTicketAge = 'Not Set'
TicketValidateClient = 'Not Set'
}
foreach ($GPOEntry in $GPO.DataSet) {
if ($GPOEntry.SettingBoolean) {
$Settings[$($GPOEntry.Name)] = if ($GPOEntry.SettingBoolean -eq 'true') { 'Enabled' } elseif ($GPOEntry.SettingBoolean -eq 'false') { 'Disabled' } else { 'Not set' };
} elseif ($GPOEntry.SettingNumber) {
$Settings[$($GPOEntry.Name)] = [int] $GPOEntry.SettingNumber
}
}
[PSCustomObject] $Settings
)
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
} else {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
ClearTextPassword = 'Not Set'
LockoutBadCount = 'Not Set'
LockoutDuration = 'Not Set'
MaximumPasswordAge = 'Not Set'
MinimumPasswordAge = 'Not Set'
MinimumPasswordLength = 'Not Set'
PasswordComplexity = 'Not Set'
PasswordHistorySize = 'Not Set'
ResetLockoutCount = 'Not Set'
MaxClockSkew = 'Not Set'
MaxRenewAge = 'Not Set'
MaxServiceAge = 'Not Set'
MaxTicketAge = 'Not Set'
TicketValidateClient = 'Not Set'
}
foreach ($GPOEntry in $GPO.DataSet) {
if ($GPOEntry.SettingBoolean) {
$CreateGPO[$($GPOEntry.Name)] = if ($GPOEntry.SettingBoolean -eq 'true') { 'Enabled' } elseif ($GPOEntry.SettingBoolean -eq 'false') { 'Disabled' } else { 'Not set' };
} elseif ($GPOEntry.SettingNumber) {
$CreateGPO[$($GPOEntry.Name)] = [int] $GPOEntry.SettingNumber
}
}
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
}
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
}
+217 -102
View File
@@ -2,7 +2,7 @@
[cmdletBinding()]
param(
[PSCustomObject] $GPO,
[switch] $FullObject
[switch] $SingleObject
)
$SettingType = @{
'0' = 'No Auditing'
@@ -10,107 +10,222 @@
'2' = 'Failure'
'3' = 'Success, Failure'
}
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
AuditAccountLogon = 'Not configured'
AuditAccountManage = 'Not configured'
AuditDSAccess = 'Not configured'
AuditLogonEvents = 'Not configured'
AuditObjectAccess = 'Not configured'
AuditPolicyChange = 'Not configured'
AuditPrivilegeUse = 'Not configured'
AuditProcessTracking = 'Not configured'
AuditSystemEvents = 'Not configured'
# Advanced Policies
AuditAccountLockout = 'Not configured'
AuditApplicationGenerated = 'Not configured'
AuditApplicationGroupManagement = 'Not configured'
AuditAuditPolicyChange = 'Not configured'
AuditAuthenticationPolicyChange = 'Not configured'
AuditAuthorizationPolicyChange = 'Not configured'
AuditCentralAccessPolicyStaging = 'Not configured'
AuditCertificationServices = 'Not configured'
AuditComputerAccountManagement = 'Not configured'
AuditCredentialValidation = 'Not configured'
AuditDetailedDirectoryServiceReplication = 'Not configured'
AuditDetailedFileShare = 'Not configured'
AuditDirectoryServiceAccess = 'Not configured'
AuditDirectoryServiceChanges = 'Not configured'
AuditDirectoryServiceReplication = 'Not configured'
AuditDistributionGroupManagement = 'Not configured'
AuditDPAPIActivity = 'Not configured'
AuditFileShare = 'Not configured'
AuditFileSystem = 'Not configured'
AuditFilteringPlatformConnection = 'Not configured'
AuditFilteringPlatformPacketDrop = 'Not configured'
AuditFilteringPlatformPolicyChange = 'Not configured'
AuditGroupMembership = 'Not configured'
AuditHandleManipulation = 'Not configured'
AuditIPsecDriver = 'Not configured'
AuditIPsecExtendedMode = 'Not configured'
AuditIPsecMainMode = 'Not configured'
AuditIPsecQuickMode = 'Not configured'
AuditKerberosAuthenticationService = 'Not configured'
AuditKerberosServiceTicketOperations = 'Not configured'
AuditKernelObject = 'Not configured'
AuditLogoff = 'Not configured'
AuditLogon = 'Not configured'
AuditMPSSVCRuleLevelPolicyChange = 'Not configured'
AuditNetworkPolicyServer = 'Not configured'
AuditNonSensitivePrivilegeUse = 'Not configured'
AuditOtherAccountLogonEvents = 'Not configured'
AuditOtherAccountManagementEvents = 'Not configured'
AuditOtherLogonLogoffEvents = 'Not configured'
AuditOtherObjectAccessEvents = 'Not configured'
AuditOtherPolicyChangeEvents = 'Not configured'
AuditOtherPrivilegeUseEvents = 'Not configured'
AuditOtherSystemEvents = 'Not configured'
AuditPNPActivity = 'Not configured'
AuditProcessCreation = 'Not configured'
AuditProcessTermination = 'Not configured'
AuditRegistry = 'Not configured'
AuditRemovableStorage = 'Not configured'
AuditRPCEvents = 'Not configured'
AuditSAM = 'Not configured'
AuditSecurityGroupManagement = 'Not configured'
AuditSecurityStateChange = 'Not configured'
AuditSecuritySystemExtension = 'Not configured'
AuditSensitivePrivilegeUse = 'Not configured'
AuditSpecialLogon = 'Not configured'
AuditSystemIntegrity = 'Not configured'
AuditUserDeviceClaims = 'Not configured'
AuditUserAccountManagement = 'Not configured'
}
foreach ($GPOEntry in $GPO.DataSet) {
if ($GPOEntry.PolicyTarget) {
# Category = 'AuditSettings', Settings = 'AuditSetting'
$Category = $GPOEntry.SubcategoryName -replace ' ', '' -replace '-', '' -replace '/', ''
if ($CreateGPO["$($Category)"]) {
$CreateGPO["$($Category)"] = $SettingType["$($GPOEntry.SettingValue)"]
}
} else {
# Category = 'SecuritySettings', Settings = 'Audit'
$SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null };
$FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null };
if ($SuccessAttempts -and $FailureAttempts) {
$Setting = 'Success, Failure'
} elseif ($SuccessAttempts) {
$Setting = 'Success'
} elseif ($FailureAttempts) {
$Setting = 'Failure'
} else {
$Setting = 'Not configured'
}
$CreateGPO["$($GPOEntry.Name)"] = $Setting
if ($SingleObject) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
Count = 0
Settings = $null
}
[Array] $CreateGPO['Settings'] = @(
$Settings = [ordered]@{
AuditAccountLogon = 'Not configured'
AuditAccountManage = 'Not configured'
AuditDSAccess = 'Not configured'
AuditLogonEvents = 'Not configured'
AuditObjectAccess = 'Not configured'
AuditPolicyChange = 'Not configured'
AuditPrivilegeUse = 'Not configured'
AuditProcessTracking = 'Not configured'
AuditSystemEvents = 'Not configured'
# Advanced Policies
AuditAccountLockout = 'Not configured'
AuditApplicationGenerated = 'Not configured'
AuditApplicationGroupManagement = 'Not configured'
AuditAuditPolicyChange = 'Not configured'
AuditAuthenticationPolicyChange = 'Not configured'
AuditAuthorizationPolicyChange = 'Not configured'
AuditCentralAccessPolicyStaging = 'Not configured'
AuditCertificationServices = 'Not configured'
AuditComputerAccountManagement = 'Not configured'
AuditCredentialValidation = 'Not configured'
AuditDetailedDirectoryServiceReplication = 'Not configured'
AuditDetailedFileShare = 'Not configured'
AuditDirectoryServiceAccess = 'Not configured'
AuditDirectoryServiceChanges = 'Not configured'
AuditDirectoryServiceReplication = 'Not configured'
AuditDistributionGroupManagement = 'Not configured'
AuditDPAPIActivity = 'Not configured'
AuditFileShare = 'Not configured'
AuditFileSystem = 'Not configured'
AuditFilteringPlatformConnection = 'Not configured'
AuditFilteringPlatformPacketDrop = 'Not configured'
AuditFilteringPlatformPolicyChange = 'Not configured'
AuditGroupMembership = 'Not configured'
AuditHandleManipulation = 'Not configured'
AuditIPsecDriver = 'Not configured'
AuditIPsecExtendedMode = 'Not configured'
AuditIPsecMainMode = 'Not configured'
AuditIPsecQuickMode = 'Not configured'
AuditKerberosAuthenticationService = 'Not configured'
AuditKerberosServiceTicketOperations = 'Not configured'
AuditKernelObject = 'Not configured'
AuditLogoff = 'Not configured'
AuditLogon = 'Not configured'
AuditMPSSVCRuleLevelPolicyChange = 'Not configured'
AuditNetworkPolicyServer = 'Not configured'
AuditNonSensitivePrivilegeUse = 'Not configured'
AuditOtherAccountLogonEvents = 'Not configured'
AuditOtherAccountManagementEvents = 'Not configured'
AuditOtherLogonLogoffEvents = 'Not configured'
AuditOtherObjectAccessEvents = 'Not configured'
AuditOtherPolicyChangeEvents = 'Not configured'
AuditOtherPrivilegeUseEvents = 'Not configured'
AuditOtherSystemEvents = 'Not configured'
AuditPNPActivity = 'Not configured'
AuditProcessCreation = 'Not configured'
AuditProcessTermination = 'Not configured'
AuditRegistry = 'Not configured'
AuditRemovableStorage = 'Not configured'
AuditRPCEvents = 'Not configured'
AuditSAM = 'Not configured'
AuditSecurityGroupManagement = 'Not configured'
AuditSecurityStateChange = 'Not configured'
AuditSecuritySystemExtension = 'Not configured'
AuditSensitivePrivilegeUse = 'Not configured'
AuditSpecialLogon = 'Not configured'
AuditSystemIntegrity = 'Not configured'
AuditUserDeviceClaims = 'Not configured'
AuditUserAccountManagement = 'Not configured'
}
foreach ($GPOEntry in $GPO.DataSet) {
if ($GPOEntry.PolicyTarget) {
# Category = 'AuditSettings', Settings = 'AuditSetting'
$Category = $GPOEntry.SubcategoryName -replace ' ', '' -replace '-', '' -replace '/', ''
if ($Settings["$($Category)"]) {
$Settings["$($Category)"] = $SettingType["$($GPOEntry.SettingValue)"]
}
} else {
# Category = 'SecuritySettings', Settings = 'Audit'
$SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null };
$FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null };
if ($SuccessAttempts -and $FailureAttempts) {
$Setting = 'Success, Failure'
} elseif ($SuccessAttempts) {
$Setting = 'Success'
} elseif ($FailureAttempts) {
$Setting = 'Failure'
} else {
$Setting = 'Not configured'
}
$Settings["$($GPOEntry.Name)"] = $Setting
}
}
[PSCustomObject] $Settings
)
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
} else {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
AuditAccountLogon = 'Not configured'
AuditAccountManage = 'Not configured'
AuditDSAccess = 'Not configured'
AuditLogonEvents = 'Not configured'
AuditObjectAccess = 'Not configured'
AuditPolicyChange = 'Not configured'
AuditPrivilegeUse = 'Not configured'
AuditProcessTracking = 'Not configured'
AuditSystemEvents = 'Not configured'
# Advanced Policies
AuditAccountLockout = 'Not configured'
AuditApplicationGenerated = 'Not configured'
AuditApplicationGroupManagement = 'Not configured'
AuditAuditPolicyChange = 'Not configured'
AuditAuthenticationPolicyChange = 'Not configured'
AuditAuthorizationPolicyChange = 'Not configured'
AuditCentralAccessPolicyStaging = 'Not configured'
AuditCertificationServices = 'Not configured'
AuditComputerAccountManagement = 'Not configured'
AuditCredentialValidation = 'Not configured'
AuditDetailedDirectoryServiceReplication = 'Not configured'
AuditDetailedFileShare = 'Not configured'
AuditDirectoryServiceAccess = 'Not configured'
AuditDirectoryServiceChanges = 'Not configured'
AuditDirectoryServiceReplication = 'Not configured'
AuditDistributionGroupManagement = 'Not configured'
AuditDPAPIActivity = 'Not configured'
AuditFileShare = 'Not configured'
AuditFileSystem = 'Not configured'
AuditFilteringPlatformConnection = 'Not configured'
AuditFilteringPlatformPacketDrop = 'Not configured'
AuditFilteringPlatformPolicyChange = 'Not configured'
AuditGroupMembership = 'Not configured'
AuditHandleManipulation = 'Not configured'
AuditIPsecDriver = 'Not configured'
AuditIPsecExtendedMode = 'Not configured'
AuditIPsecMainMode = 'Not configured'
AuditIPsecQuickMode = 'Not configured'
AuditKerberosAuthenticationService = 'Not configured'
AuditKerberosServiceTicketOperations = 'Not configured'
AuditKernelObject = 'Not configured'
AuditLogoff = 'Not configured'
AuditLogon = 'Not configured'
AuditMPSSVCRuleLevelPolicyChange = 'Not configured'
AuditNetworkPolicyServer = 'Not configured'
AuditNonSensitivePrivilegeUse = 'Not configured'
AuditOtherAccountLogonEvents = 'Not configured'
AuditOtherAccountManagementEvents = 'Not configured'
AuditOtherLogonLogoffEvents = 'Not configured'
AuditOtherObjectAccessEvents = 'Not configured'
AuditOtherPolicyChangeEvents = 'Not configured'
AuditOtherPrivilegeUseEvents = 'Not configured'
AuditOtherSystemEvents = 'Not configured'
AuditPNPActivity = 'Not configured'
AuditProcessCreation = 'Not configured'
AuditProcessTermination = 'Not configured'
AuditRegistry = 'Not configured'
AuditRemovableStorage = 'Not configured'
AuditRPCEvents = 'Not configured'
AuditSAM = 'Not configured'
AuditSecurityGroupManagement = 'Not configured'
AuditSecurityStateChange = 'Not configured'
AuditSecuritySystemExtension = 'Not configured'
AuditSensitivePrivilegeUse = 'Not configured'
AuditSpecialLogon = 'Not configured'
AuditSystemIntegrity = 'Not configured'
AuditUserDeviceClaims = 'Not configured'
AuditUserAccountManagement = 'Not configured'
}
foreach ($GPOEntry in $GPO.DataSet) {
if ($GPOEntry.PolicyTarget) {
# Category = 'AuditSettings', Settings = 'AuditSetting'
$Category = $GPOEntry.SubcategoryName -replace ' ', '' -replace '-', '' -replace '/', ''
if ($CreateGPO["$($Category)"]) {
$CreateGPO["$($Category)"] = $SettingType["$($GPOEntry.SettingValue)"]
}
} else {
# Category = 'SecuritySettings', Settings = 'Audit'
$SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null };
$FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null };
if ($SuccessAttempts -and $FailureAttempts) {
$Setting = 'Success, Failure'
} elseif ($SuccessAttempts) {
$Setting = 'Success'
} elseif ($FailureAttempts) {
$Setting = 'Failure'
} else {
$Setting = 'Not configured'
}
$CreateGPO["$($GPOEntry.Name)"] = $Setting
}
}
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
}
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
}
+148 -58
View File
@@ -2,52 +2,141 @@ function ConvertTo-XMLGenericPolicy {
[cmdletBinding()]
param(
[PSCustomObject] $GPO,
[string[]] $Category
[string[]] $Category,
[switch] $SingleObject
)
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
}
$UsedNames = [System.Collections.Generic.List[string]]::new()
[Array] $Policies = foreach ($Cat in $Category) {
$GPO.DataSet | Where-Object { $_.Category -like $Cat }
}
if ($Policies.Count -gt 0) {
foreach ($Policy in $Policies) {
#if ($Policy.Category -notlike $Category) {
# We check again for Category because one GPO can have multiple categories
# First check checks GPO globally,
# continue
#}
$Name = Format-ToTitleCase -Text $Policy.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$CreateGPO[$Name] = $Policy.State
if ($SingleObject) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
Count = 0
Settings = $null
}
foreach ($Setting in @('DropDownList', 'Numeric', 'EditText', 'Text', 'CheckBox', 'ListBox')) {
if ($Policy.$Setting) {
foreach ($Value in $Policy.$Setting) {
if ($Value.Name) {
$SubName = Format-ToTitleCase -Text $Value.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$SubName = -join ($Name, $SubName)
if ($SubName -notin $UsedNames) {
$UsedNames.Add($SubName)
[Array] $CreateGPO['Settings'] = @(
$Settings = [ordered] @{}
foreach ($Policy in $Policies) {
#if ($Policy.Category -notlike $Category) {
# We check again for Category because one GPO can have multiple categories
# First check checks GPO globally,
# continue
#}
$Name = Format-ToTitleCase -Text $Policy.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$Settings[$Name] = $Policy.State
foreach ($Setting in @('DropDownList', 'Numeric', 'EditText', 'Text', 'CheckBox', 'ListBox')) {
if ($Policy.$Setting) {
foreach ($Value in $Policy.$Setting) {
if ($Value.Name) {
$SubName = Format-ToTitleCase -Text $Value.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$SubName = -join ($Name, $SubName)
if ($SubName -notin $UsedNames) {
$UsedNames.Add($SubName)
} else {
$TimesUsed = $UsedNames | Group-Object | Where-Object { $_.Name -eq $SubName }
$NumberToUse = $TimesUsed.Count + 1
# We add same name 2nd and 3rd time to make sure we count properly
$UsedNames.Add($SubName)
# We now build property name based on amnount of times
$SubName = -join ($SubName, "$NumberToUse")
}
if ($Value.Value -is [string]) {
$Settings["$SubName"] = $Value.Value
} elseif ($Value.Value -is [System.Xml.XmlElement]) {
<#
if ($null -eq $Value.Value.Name) {
# Shouldn't happen but lets see
Write-Verbose $Value
} else {
$TimesUsed = $UsedNames | Group-Object | Where-Object { $_.Name -eq $SubName }
$NumberToUse = $TimesUsed.Count + 1
# We add same name 2nd and 3rd time to make sure we count properly
$UsedNames.Add($SubName)
# We now build property name based on amnount of times
$SubName = -join ($SubName, "$NumberToUse")
$CreateGPO["$SubName"] = $Value.Value.Name
}
if ($Value.Value -is [string]) {
$CreateGPO["$SubName"] = $Value.Value
} elseif ($Value.Value -is [System.Xml.XmlElement]) {
<#
#>
if ($Value.Value.Element) {
$Settings["$SubName"] = $Value.Value.Element.Data -join '; '
} elseif ($null -eq $Value.Value.Name) {
# Shouldn't happen but lets see
Write-Verbose "Tracking $Value"
} else {
$Settings["$SubName"] = $Value.Value.Name
}
} elseif ($Value.State) {
$Settings["$SubName"] = $Value.State
} elseif ($null -eq $Value.Value) {
# This is most likely Setting 'Text
# Do nothing, usually it's just a text to display
#Write-Verbose "Skipping value for display because it's empty. Name: $($Value.Name)"
} else {
# shouldn't happen
Write-Verbose $Value
}
}
}
}
}
}
[PSCustomObject] $Settings
)
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
} else {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
}
foreach ($Policy in $Policies) {
#if ($Policy.Category -notlike $Category) {
# We check again for Category because one GPO can have multiple categories
# First check checks GPO globally,
# continue
#}
$Name = Format-ToTitleCase -Text $Policy.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$CreateGPO[$Name] = $Policy.State
foreach ($Setting in @('DropDownList', 'Numeric', 'EditText', 'Text', 'CheckBox', 'ListBox')) {
if ($Policy.$Setting) {
foreach ($Value in $Policy.$Setting) {
if ($Value.Name) {
$SubName = Format-ToTitleCase -Text $Value.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$SubName = -join ($Name, $SubName)
if ($SubName -notin $UsedNames) {
$UsedNames.Add($SubName)
} else {
$TimesUsed = $UsedNames | Group-Object | Where-Object { $_.Name -eq $SubName }
$NumberToUse = $TimesUsed.Count + 1
# We add same name 2nd and 3rd time to make sure we count properly
$UsedNames.Add($SubName)
# We now build property name based on amnount of times
$SubName = -join ($SubName, "$NumberToUse")
}
if ($Value.Value -is [string]) {
$CreateGPO["$SubName"] = $Value.Value
} elseif ($Value.Value -is [System.Xml.XmlElement]) {
<#
if ($null -eq $Value.Value.Name) {
# Shouldn't happen but lets see
Write-Verbose $Value
@@ -56,34 +145,35 @@ function ConvertTo-XMLGenericPolicy {
}
#>
if ($Value.Value.Element) {
$CreateGPO["$SubName"] = $Value.Value.Element.Data -join '; '
} elseif ($null -eq $Value.Value.Name) {
# Shouldn't happen but lets see
Write-Verbose "Tracking $Value"
} else {
$CreateGPO["$SubName"] = $Value.Value.Name
}
if ($Value.Value.Element) {
$CreateGPO["$SubName"] = $Value.Value.Element.Data -join '; '
} elseif ($null -eq $Value.Value.Name) {
# Shouldn't happen but lets see
Write-Verbose "Tracking $Value"
} else {
$CreateGPO["$SubName"] = $Value.Value.Name
}
} elseif ($Value.State) {
$CreateGPO["$SubName"] = $Value.State
} elseif ($null -eq $Value.Value) {
# This is most likely Setting 'Text
# Do nothing, usually it's just a text to display
#Write-Verbose "Skipping value for display because it's empty. Name: $($Value.Name)"
} else {
# shouldn't happen
Write-Verbose $Value
} elseif ($Value.State) {
$CreateGPO["$SubName"] = $Value.State
} elseif ($null -eq $Value.Value) {
# This is most likely Setting 'Text
# Do nothing, usually it's just a text to display
#Write-Verbose "Skipping value for display because it's empty. Name: $($Value.Name)"
} else {
# shouldn't happen
Write-Verbose $Value
}
}
}
}
}
}
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
#}
}
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
#}
}
}
+64 -44
View File
@@ -2,17 +2,11 @@ function ConvertTo-XMLGenericPublicKey {
[cmdletBinding()]
param(
[PSCustomObject] $GPO,
[string[]] $Category
[string[]] $Category,
[switch] $SingleObject
)
$SkipNames = ('Name', 'LocalName', 'NamespaceURI', 'Prefix', 'NodeType', 'ParentNode', 'OwnerDocument', 'IsEmpty', 'Attributes', 'HasAttributes', 'SchemaInfo', 'InnerXml', 'InnerText', 'NextSibling', 'PreviousSibling', 'ChildNodes', 'FirstChild', 'LastChild', 'HasChildNodes', 'IsReadOnly', 'OuterXml', 'BaseURI', 'PreviousText')
<#
$UsedNames = [System.Collections.Generic.List[string]]::new()
[Array] $Settings = foreach ($Cat in $Category) {
$GPO.DataSet | Where-Object { $null -ne $_.$Cat }
}
#>
foreach ($Setting in $GPO.DataSet) {
if ($SingleObject) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
@@ -20,23 +14,57 @@ function ConvertTo-XMLGenericPublicKey {
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
Count = 0
Settings = $null
}
$SettingName = $Setting.Name -split ":"
$CreateGPO['CreatedTime'] = $GPO.CreatedTime # : 06.06.2020 18:03:36
$CreateGPO['ModifiedTime'] = $GPO.ModifiedTime # : 17.06.2020 16:08:10
$CreateGPO['ReadTime'] = $GPO.ReadTime # : 13.08.2020 10:15:37
$CreateGPO['SecurityDescriptor'] = $GPO.SecurityDescriptor # : SecurityDescriptor
$CreateGPO['FilterDataAvailable'] = $GPO.FilterDataAvailable # : True
[Array] $CreateGPO['Settings'] = foreach ($Setting in $GPO.DataSet) {
$SettingName = $Setting.Name -split ":"
$MySettings = [ordered] @{
CreatedTime = $GPO.CreatedTime # : 06.06.2020 18:03:36
ModifiedTime = $GPO.ModifiedTime # : 17.06.2020 16:08:10
ReadTime = $GPO.ReadTime # : 13.08.2020 10:15:37
SecurityDescriptor = $GPO.SecurityDescriptor # : SecurityDescriptor
FilterDataAvailable = $GPO.FilterDataAvailable # : True
}
$Name = $SettingName[1]
#$Name = Format-ToTitleCase -Text $Setting.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$MySettings['Name'] = $Name # $Setting.Name
ConvertTo-XMLNested -CreateGPO $MySettings -Setting $Setting -SkipNames $SkipNames #-Name $Name
[PSCustomObject] $MySettings
}
#$Divider = $SettingName[0]
$Name = $SettingName[1]
#$Name = Format-ToTitleCase -Text $Setting.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$CreateGPO['Name'] = $Name # $Setting.Name
#$CreateGPO['GPOSettingOrder'] = $Setting.GPOSettingOrder
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
} else {
foreach ($Setting in $GPO.DataSet) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
}
$SettingName = $Setting.Name -split ":"
$CreateGPO['CreatedTime'] = $GPO.CreatedTime # : 06.06.2020 18:03:36
$CreateGPO['ModifiedTime'] = $GPO.ModifiedTime # : 17.06.2020 16:08:10
$CreateGPO['ReadTime'] = $GPO.ReadTime # : 13.08.2020 10:15:37
$CreateGPO['SecurityDescriptor'] = $GPO.SecurityDescriptor # : SecurityDescriptor
$CreateGPO['FilterDataAvailable'] = $GPO.FilterDataAvailable # : True
#foreach ($Property in ($Setting.Properties | Get-Member -MemberType Properties).Name) {
$Name = $SettingName[1]
#$Name = Format-ToTitleCase -Text $Setting.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$CreateGPO['Name'] = $Name # $Setting.Name
#$CreateGPO['GPOSettingOrder'] = $Setting.GPOSettingOrder
#foreach ($Property in ($Setting.Properties | Get-Member -MemberType Properties).Name) {
ConvertTo-XMLNested -CreateGPO $CreateGPO -Setting $Setting -SkipNames $SkipNames #-Name $Name
<#
$Properties = $Setting.PSObject.Properties.Name | Where-Object { $_ -notin $SkipNames }
foreach ($Property in $Properties) {
If ($Property -eq 'Value') {
@@ -54,33 +82,25 @@ function ConvertTo-XMLGenericPublicKey {
} else {
throw
}
<#
foreach ($SubProperty in $SubProperties) {
if ($SubProperty -eq 'Name') {
} elseif ($SubProperty -eq 'String') {
} elseif ($SubProperty -eq 'Number') {
}
#$Name = Format-CamelCaseToDisplayName -Text $SubProperty #-RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
#$CreateGPO[$Name] = $Setting.$Property.$SubProperty
}
#>
}
} else {
$Name = Format-CamelCaseToDisplayName -Text $Property #-RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
$CreateGPO[$Name] = $Setting.$Property
if ($Setting.$Property -is [System.Xml.XmlElement]) {
$SubPropeties = $Setting.$Property.PSObject.Properties.Name | Where-Object { $_ -notin $SkipNames }
} else {
$CreateGPO[$Name] = $Setting.$Property
}
}
}
$CreateGPO['Filters'] = $Setting.Filters
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
#>
$CreateGPO['Filters'] = $Setting.Filters
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
}
}
}
@@ -5,7 +5,7 @@ function ConvertTo-XMLGenericSecuritySettings {
[string[]] $Category
)
$SkipNames = ('Name', 'LocalName', 'NamespaceURI', 'Prefix', 'NodeType', 'ParentNode', 'OwnerDocument', 'IsEmpty', 'Attributes', 'HasAttributes', 'SchemaInfo', 'InnerXml', 'InnerText', 'NextSibling', 'PreviousSibling', 'Value', 'ChildNodes', 'FirstChild', 'LastChild', 'HasChildNodes', 'IsReadOnly', 'OuterXml', 'BaseURI', 'PreviousText')
$UsedNames = [System.Collections.Generic.List[string]]::new()
#$UsedNames = [System.Collections.Generic.List[string]]::new()
[Array] $Settings = foreach ($Cat in $Category) {
$GPO.DataSet | Where-Object { $null -ne $_.$Cat }
}
+49
View File
@@ -0,0 +1,49 @@
function ConvertTo-XMLNested {
[cmdletBinding()]
param(
[System.Collections.IDictionary] $CreateGPO,
[System.Xml.XmlElement] $Setting,
[string[]] $SkipNames,
[string] $Name
)
$Properties = $Setting.PSObject.Properties.Name | Where-Object { $_ -notin $SkipNames }
$TempName = $Name
foreach ($Property in $Properties) {
If ($Property -eq 'Value') {
if ($Setting.$Property) {
#$SubProperties = $Setting.$Property.PSObject.Properties.Name
if ($Setting.$Property.Name) {
$Name = $Setting.$Property.Name
} else {
if (-not $Name) {
$Name = 'Value'
}
}
if ($Setting.$Property.Number) {
$CreateGPO[$Name] = $Setting.$Property.Number
} elseif ($Setting.$Property.String) {
$CreateGPO[$Name] = $Setting.$Property.String
} else {
$CreateGPO[$Name] = $Setting.$Property
#throw
}
}
} else {
$Name = -join ($Name, $Property)
$Name = Format-CamelCaseToDisplayName -Text $Name #-RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
if ($Setting.$Property -is [System.Xml.XmlElement]) {
#$SubPropeties = $Setting.$Property.PSObject.Properties.Name | Where-Object { $_ -notin $SkipNames }
ConvertTo-XMLNested -Setting $Setting.$Property -CreateGPO $CreateGPO -Name $Name -SkipNames $SkipNames
} else {
$CreateGPO[$Name] = $Setting.$Property
}
}
$Name = $TempName
}
}
@@ -0,0 +1,86 @@
function ConvertTo-XMLUserRightsAssignment {
[cmdletBinding()]
param(
[PSCustomObject] $GPO,
[switch] $SingleObject
)
$UserRightsTranslation = @{
SeNetworkLogonRight = 'Access this computer from the network'
SeMachineAccountPrivilege = 'Add workstations to domain'
SeIncreaseQuotaPrivilege = 'Adjust memory quotas for a process'
SeInteractiveLogonRight = 'Allow log on locally'
SeBackupPrivilege = 'Back up files and directories'
SeChangeNotifyPrivilege = 'Bypass traverse checking Everyone'
SeSystemTimePrivilege = 'Change the system time'
SeCreatePagefilePrivilege = 'Create a pagefile'
SeDebugPrivilege = 'Debug programs'
SeEnableDelegationPrivilege = 'Enable computer and user accounts to be trusted for delegation'
SeRemoteShutdownPrivilege = 'Force shutdown from a remote system'
SeAuditPrivilege = 'Generate security audits'
SeIncreaseBasePriorityPrivilege = 'Increase scheduling priority'
SeLoadDriverPrivilege = 'Load and unload device drivers'
SeBatchLogonRight = 'Log on as a batch job'
SeSecurityPrivilege = 'Manage auditing and security log'
SeSystemEnvironmentPrivilege = 'Modify firmware environment values'
SeProfileSingleProcessPrivilege = 'Profile single process'
SeSystemProfilePrivilege = 'Profile system performance'
SeUndockPrivilege = 'Remove computer from docking station'
SeAssignPrimaryTokenPrivilege = 'Replace a process level token'
SeRestorePrivilege = 'Restore files and directories'
SeShutdownPrivilege = 'Shut down the system'
SeTakeOwnershipPrivilege = 'Take ownership of files or other objects'
}
if ($SingleObject) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
Count = 0
Settings = $null
}
[Array] $CreateGPO['Settings'] = foreach ($Entry in $GPO.DataSet) {
foreach ($Member in $Entry.Member) {
[PSCustomObject]@{
'UserRightsAssignment' = $Entry.Name
'UserRightsAssignmentDescription' = $UserRightsTranslation[$Entry.Name]
'Name' = $Member.Name.'#text'
'Sid' = $Member.SID.'#text'
}
}
}
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
} else {
foreach ($Entry in $GPO.DataSet) {
foreach ($Member in $Entry.Member) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
#GpoCategory = $GPOEntry.GpoCategory
#GpoSettings = $GPOEntry.GpoSettings
}
$CreateGPO['UserRightsAssignment'] = $Entry.Name
$CreateGPO['UserRightsAssignmentDescription'] = $UserRightsTranslation[$Entry.Name]
$CreateGPO['Name'] = $Member.Name.'#text'
$CreateGPO['Sid'] = $Member.SID.'#text'
#$CreateGPO['CreatedTime'] = $GPO.CreatedTime # : 06.06.2020 18:03:36
#$CreateGPO['ModifiedTime'] = $GPO.ModifiedTime # : 17.06.2020 16:08:10
#$CreateGPO['ReadTime'] = $GPO.ReadTime # : 13.08.2020 10:15:37
$CreateGPO['Linked'] = $GPO.Linked
$CreateGPO['LinksCount'] = $GPO.LinksCount
$CreateGPO['Links'] = $GPO.Links
[PSCustomObject] $CreateGPO
}
}
}
}
+196 -98
View File
@@ -5,7 +5,7 @@
[Object] $SecurityRights,
[string[]] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
[validateset('DistinguishedName', 'Name', 'NetbiosName', 'Sid')][string] $PrincipalType = 'Sid',
[switch] $SkipWellKnown,
[switch] $SkipAdministrative,
@@ -20,7 +20,7 @@
[switch] $IncludeGPOObject,
[System.Collections.IDictionary] $ADAdministrativeGroups,
[validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All',
[System.Collections.IDictionary] $Accounts,
#[System.Collections.IDictionary] $Accounts,
[System.Collections.IDictionary] $ExtendedForestInformation
)
Begin {
@@ -100,6 +100,11 @@
return
}
}
if ($GPOPermission.Trustee.Domain) {
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
} else {
$UserMerge = $null
}
if ($Principal) {
if ($PrincipalType -eq 'Sid') {
if ($Principal -notcontains $GPOPermission.Trustee.Sid.Value) {
@@ -110,8 +115,11 @@
return
}
} elseif ($PrincipalType -eq 'Name') {
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
if ($Principal -notcontains $UserMerge -and $Principal -notcontains $GPOPermission.Trustee.Name) {
if ($Principal -notcontains $GPOPermission.Trustee.Name) {
return
}
} elseif ($PrincipalType -eq 'NetbiosName') {
if ($Principal -notcontains $UserMerge) {
return
}
}
@@ -126,56 +134,76 @@
return
}
} elseif ($ExcludePrincipalType -eq 'Name') {
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
if ($ExcludePrincipal -contains $UserMerge -or $ExcludePrincipal -contains $GPOPermission.Trustee.Name) {
if ($ExcludePrincipal -contains $GPOPermission.Trustee.Name) {
return
}
} elseif ($ExcludePrincipalType -eq 'NetbiosName') {
if ($ExcludePrincipal -contains $UserMerge) {
return
}
}
}
$ReturnObject = [ordered] @{
DisplayName = $GPO.DisplayName # : ALL | Enable RDP
GUID = $GPO.ID
DomainName = $GPO.DomainName # : ad.evotec.xyz
Enabled = $GPO.GpoStatus
Description = $GPO.Description
CreationDate = $GPO.CreationTime
ModificationTime = $GPO.ModificationTime
PermissionType = if ($GPOPermission.Denied -eq $true) { 'Deny' } else { 'Allow' }
Permission = $GPOPermission.Permission # : GpoEditDeleteModifySecurity
Inherited = $GPOPermission.Inherited # : False
Domain = $GPOPermission.Trustee.Domain #: EVOTEC
DistinguishedName = $GPOPermission.Trustee.DSPath #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
Name = $GPOPermission.Trustee.Name #: Domain Admins
Sid = $GPOPermission.Trustee.Sid.Value #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
SidType = $GPOPermission.Trustee.SidType #: Group
}
if ($Accounts) {
$A = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
if ($A -and $Accounts[$A]) {
$ReturnObject['UserPrincipalName'] = $Accounts[$A].UserPrincipalName
$ReturnObject['AccountEnabled'] = $Accounts[$A].Enabled
$ReturnObject['DistinguishedName'] = $Accounts[$A].DistinguishedName
$ReturnObject['PasswordLastSet'] = if ($Accounts[$A].PasswordLastSet) { $Accounts[$A].PasswordLastSet } else { '' }
$ReturnObject['LastLogonDate'] = if ($Accounts[$A].LastLogonDate ) { $Accounts[$A].LastLogonDate } else { '' }
if (-not $ReturnObject['Sid']) {
$ReturnObject['Sid'] = $Accounts[$A].Sid.Value
}
if ($Accounts[$A].ObjectClass -eq 'group') {
$ReturnObject['SidType'] = 'Group'
} elseif ($Accounts[$A].ObjectClass -eq 'user') {
$ReturnObject['SidType'] = 'User'
} elseif ($Accounts[$A].ObjectClass -eq 'computer') {
$ReturnObject['SidType'] = 'Computer'
} else {
$ReturnObject['SidType'] = 'EmptyOrUnknown'
<#
# Sets permissions name, domain, distinguishedname to proper values
if ($GPOPermission.Trustee.Name) {
$DomainPlusName = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
if ($GPOPermission.Trustee.DSPath) {
$NetbiosConversion = ConvertFrom-NetbiosName -Identity $DomainPlusName
if ($NetbiosConversion.DomainName) {
$UserNameDomain = $NetbiosConversion.DomainName
$UserName = $NetbiosConversion.Name
}
} else {
$ReturnObject['UserPrincipalName'] = ''
$ReturnObject['AccountEnabled'] = ''
$ReturnObject['PasswordLastSet'] = ''
$ReturnObject['LastLogonDate'] = ''
$UserNameDomain = ''
$Username = $DomainPlusName
}
} else {
$DomainPlusName = ''
$UserNameDomain = ''
$Username = ''
}
#>
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
$PermissionAccount = Get-WinADObject -Identity $GPOPermission.Trustee.Sid.Value -AddType -Cache
if ($PermissionAccount) {
$UserNameDomain = $PermissionAccount.DomainName
$UserName = $PermissionAccount.Name
$SidType = $PermissionAccount.Type
$ObjectClass = $PermissionAccount.ObjectClass
} else {
$ConvertFromSID = ConvertFrom-SID -SID $GPOPermission.Trustee.Sid.Value
$UserNameDomain = ''
$Username = $ConvertFromSID.Name
$SidType = $ConvertFromSID.Type
if ($SidType -eq 'Unknown') {
$ObjectClass = 'unknown'
} else {
$ObjectClass = 'foreignSecurityPrincipal'
}
}
$ReturnObject = [ordered] @{
DisplayName = $GPO.DisplayName # : ALL | Enable RDP
GUID = $GPO.ID
DomainName = $GPO.DomainName # : ad.evotec.xyz
Enabled = $GPO.GpoStatus
Description = $GPO.Description
CreationDate = $GPO.CreationTime
ModificationTime = $GPO.ModificationTime
PermissionType = if ($GPOPermission.Denied -eq $true) { 'Deny' } else { 'Allow' }
Permission = $GPOPermission.Permission # : GpoEditDeleteModifySecurity
Inherited = $GPOPermission.Inherited # : False
PrincipalNetBiosName = $UserMerge
PrincipalDistinguishedName = $GPOPermission.Trustee.DSPath #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
PrincipalDomainName = $UserNameDomain #: EVOTEC
PrincipalName = $UserName #: Domain Admins
PrincipalSid = $GPOPermission.Trustee.Sid.Value #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
PrincipalSidType = $SidType #$GPOPermission.Trustee.SidType #: Group
PrincipalObjectClass = $ObjectClass
}
if ($IncludeGPOObject) {
$ReturnObject['GPOObject'] = $GPO
$ReturnObject['GPOSecurity'] = $SecurityRights
@@ -183,69 +211,139 @@
}
[PSCustomObject] $ReturnObject
}
if ($IncludeOwner.IsPresent) {
if ($IncludeOwner) {
if ($GPO.Owner) {
$SplittedOwner = $GPO.Owner.Split('\')
$DomainOwner = $SplittedOwner[0] #: EVOTEC
$DomainUserName = $SplittedOwner[1] #: Domain Admins
$SID = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"].Sid.Value
if ($SID) {
$SIDType = 'Group'
$DistinguishedName = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"].DistinguishedName
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
$OwnerAccount = Get-WinADObject -Identity $GPO.Owner -AddType -Cache
if ($OwnerAccount) {
$UserNameDomain = $OwnerAccount.DomainName
$UserName = $OwnerAccount.Name
$SidType = $OwnerAccount.Type
$OwnerObjectClass = $OwnerAccount.ObjectClass
$SID = $OwnerAccount.ObjectSID
} else {
$SIDType = ''
$DistinguishedName = ''
$ConvertFromSID = ConvertFrom-SID -SID $GPO.Owner
$UserNameDomain = ''
$Username = $ConvertFromSID.Name
$SidType = $ConvertFromSID.Type
if ($SidType -eq 'Unknown') {
$OwnerObjectClass = 'unknown'
} else {
$OwnerObjectClass = 'foreignSecurityPrincipal'
}
$SID = $ConvertFromSID.SID
}
} else {
$DomainOwner = $GPO.Owner
$DomainUserName = ''
$UserName = ''
$UserNameDomain = ''
$SID = ''
$SIDType = 'EmptyOrUnknown'
$SIDType = 'Unknown'
$DistinguishedName = ''
$OwnerObjectClass = 'unknown'
}
$ReturnObject = [ordered] @{
DisplayName = $GPO.DisplayName # : ALL | Enable RDP
GUID = $GPO.Id
DomainName = $GPO.DomainName # : ad.evotec.xyz
Enabled = $GPO.GpoStatus
Description = $GPO.Description
CreationDate = $GPO.CreationTime
ModificationTime = $GPO.ModificationTime
Permission = 'GpoOwner' # : GpoEditDeleteModifySecurity
Inherited = $false # : False
Domain = $DomainOwner
DistinguishedName = $DistinguishedName #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
Name = $DomainUserName
Sid = $SID #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
SidType = $SIDType # #: Group
}
if ($Accounts) {
$A = $GPO.Owner
if ($A -and $Accounts[$A]) {
$ReturnObject['UserPrincipalName'] = $Accounts[$A].UserPrincipalName
$ReturnObject['AccountEnabled'] = $Accounts[$A].Enabled
$ReturnObject['DistinguishedName'] = $Accounts[$A].DistinguishedName
$ReturnObject['PasswordLastSet'] = if ($Accounts[$A].PasswordLastSet) { $Accounts[$A].PasswordLastSet } else { '' }
$ReturnObject['LastLogonDate'] = if ($Accounts[$A].LastLogonDate ) { $Accounts[$A].LastLogonDate } else { '' }
if (-not $ReturnObject['Sid']) {
$ReturnObject['Sid'] = $Accounts[$A].Sid.Value
}
if ($Accounts[$A].ObjectClass -eq 'group') {
$ReturnObject['SidType'] = 'Group'
} elseif ($Accounts[$A].ObjectClass -eq 'user') {
$ReturnObject['SidType'] = 'User'
} elseif ($Accounts[$A].ObjectClass -eq 'computer') {
$ReturnObject['SidType'] = 'Computer'
} else {
$ReturnObject['SidType'] = 'EmptyOrUnknown'
# We have to process it for owners after querying user because $Owners are not as established as standard permissions so we don't know a lot
if ($Type -contains 'Administrative' -and $Type -notcontains 'All') {
if ($SID) {
$IsAdministrative = $ADAdministrativeGroups['BySID'][$SID]
if (-not $IsAdministrative) {
return
}
} else {
$ReturnObject['UserPrincipalName'] = ''
$ReturnObject['AccountEnabled'] = ''
$ReturnObject['PasswordLastSet'] = ''
$ReturnObject['LastLogonDate'] = ''
# if there is no SID, it's not administrative
return
}
}
if ($Type -contains 'NotWellKnownAdministrative' -and $Type -notcontains 'All') {
# We check for SYSTEM account
# Maybe we should make it a function and provide more
if ($SID -eq 'S-1-5-18') {
return
}
}
if ($Type -contains 'WellKnownAdministrative' -and $Type -notcontains 'All') {
# We check for SYSTEM account
# Maybe we should make it a function and provide more
if ($SID -ne 'S-1-5-18') {
return
}
}
if ($Type -contains 'Unknown' -and $Type -notcontains 'All') {
# May need updates if there's more types
if ($SidType -ne 'Unknown') {
return
}
}
if ($Type -contains 'AuthenticatedUsers' -and $Type -notcontains 'All') {
if ($SID -ne 'S-1-5-11') {
return
}
}
if ($Type -contains 'DomainComputers' -and $Type -notcontains 'All') {
$DomainComputersSID = -join ($ExtendedForestInformation['DomainsExtended'][$GPO.DomainName].DomainSID, '-515')
if ($SID -ne $DomainComputersSID) {
return
}
}
if ($Principal) {
if ($PrincipalType -eq 'Sid') {
if ($Principal -notcontains $SID) {
return
}
} elseif ($PrincipalType -eq 'DistinguishedName') {
if ($Principal -notcontains $DistinguishedName) {
return
}
} elseif ($PrincipalType -eq 'Name') {
if ($Principal -notcontains $UserName) {
return
}
} elseif ($PrincipalType -eq 'NetbiosName') {
if ($Principal -notcontains $GPO.Owner) {
return
}
}
}
if ($ExcludePrincipal) {
if ($ExcludePrincipalType -eq 'Sid') {
if ($ExcludePrincipal -contains $SID) {
return
}
} elseif ($ExcludePrincipalType -eq 'DistinguishedName') {
if ($ExcludePrincipal -contains $DistinguishedName) {
return
}
} elseif ($ExcludePrincipalType -eq 'Name') {
if ($ExcludePrincipal -contains $UserName) {
return
}
} elseif ($ExcludePrincipalType -eq 'NetbiosName') {
if ($ExcludePrincipal -contains $GPO.Owner) {
return
}
}
}
$ReturnObject = [ordered] @{
DisplayName = $GPO.DisplayName # : ALL | Enable RDP
GUID = $GPO.Id
DomainName = $GPO.DomainName # : ad.evotec.xyz
Enabled = $GPO.GpoStatus
Description = $GPO.Description
CreationDate = $GPO.CreationTime
ModificationTime = $GPO.ModificationTime
PermissionType = 'Allow'
Permission = 'GpoOwner' # : GpoEditDeleteModifySecurity
Inherited = $false # : False
PrincipalNetBiosName = $GPO.Owner
PrincipalDistinguishedName = $DistinguishedName #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
PrincipalDomainName = $UserNameDomain
PrincipalName = $UserName
PrincipalSid = $SID #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
PrincipalSidType = $SIDType # #: Group
PrincipalObjectClass = $OwnerObjectClass
}
if ($IncludeGPOObject) {
$ReturnObject['GPOObject'] = $GPO
$ReturnObject['GPOSecurity'] = $SecurityRights
+1 -1
View File
@@ -66,7 +66,7 @@
$OwnerType = 'NotAdministrative'
}
} else {
$OwnerType = 'EmptyOrUnknown'
$OwnerType = 'Unknown'
}
}
if ($PermissionsOnly) {
File diff suppressed because it is too large Load Diff
+69 -55
View File
@@ -3,14 +3,17 @@
param(
[Array] $GPOs,
[string] $Server,
[string] $Domain
[string] $Domain,
[System.Collections.IDictionary] $PoliciesAD,
[string] $PoliciesSearchBase
)
$Differences = @{ }
$SysvolHash = @{ }
$GPOGUIDS = $GPOs.ID.GUID
$SysVolPath = "\\$($Server)\SYSVOL\$Domain\Policies"
try {
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -ErrorAction Stop
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -Exclude 'PolicyDefinitions' -ErrorAction Stop -Verbose:$false
} catch {
$Sysvol = $Null
}
@@ -22,12 +25,20 @@
if ($Files) {
$Comparing = Compare-Object -ReferenceObject $GPOGUIDS -DifferenceObject $Files -IncludeEqual
foreach ($_ in $Comparing) {
if ($_.InputObject -eq 'PolicyDefinitions') {
# we skip policy definitions
continue
}
if ($_.SideIndicator -eq '==') {
$Found = 'Exists'
} elseif ($_.SideIndicator -eq '<=') {
$Found = 'Not available on SYSVOL'
} elseif ($_.SideIndicator -eq '=>') {
$Found = 'Orphaned GPO'
if ($PoliciesAD[$_.InputObject]) {
$Found = $PoliciesAD[$_.InputObject]
} else {
$Found = 'Not available in AD'
}
} else {
$Found = 'Orphaned GPO'
}
@@ -39,78 +50,81 @@
if ($null -ne $SysvolHash[$GPO.Id.GUID].FullName) {
$FullPath = $SysvolHash[$GPO.Id.GUID].FullName
try {
$ACL = Get-Acl -Path $SysvolHash[$GPO.Id.GUID].FullName -ErrorAction Stop
$ACL = Get-Acl -Path $SysvolHash[$GPO.Id.GUID].FullName -ErrorAction Stop -Verbose:$false
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrSysvol - ACL reading (1) failed for $FullPath with error: $($_.Exception.Message)"
Write-Warning "Get-GPOZaurrBroken - ACL reading (1) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = ''
$ErrorMessage = $_.Exception.Message
}
} else {
$FullPath = -join ($SysVolPath, "\{$($GPO.Id.Guid)}")
$ACL = $null
$Owner = ''
$ErrorMessage = 'Not found on SYSVOL'
}
if ($null -eq $Differences[$GPO.Id.Guid]) {
$SysVolStatus = 'Not available on SYSVOL'
$SysVolStatus = 'Unknown Issue'
} else {
$SysVolStatus = $Differences[$GPO.Id.Guid]
}
[PSCustomObject] @{
DisplayName = $GPO.DisplayName
Status = $Differences[$GPO.Id.Guid]
DomainName = $GPO.DomainName
SysvolServer = $Server
SysvolStatus = $SysVolStatus
Owner = $GPO.Owner
FileOwner = $Owner
Id = $GPO.Id.Guid
GpoStatus = $GPO.GpoStatus
Path = $FullPath
Description = $GPO.Description
CreationTime = $GPO.CreationTime
ModificationTime = $GPO.ModificationTime
UserVersion = $GPO.UserVersion
ComputerVersion = $GPO.ComputerVersion
WmiFilter = $GPO.WmiFilter
Error = $ErrorMessage
DisplayName = $GPO.DisplayName
Status = $SysVolStatus
DomainName = $GPO.DomainName
SysvolServer = $Server
SysvolStatus = $SysVolStatus
GpoStatus = $GPO.GpoStatus
Owner = $GPO.Owner
FileOwner = $Owner
Id = $GPO.Id.Guid
Path = $FullPath
DistinguishedName = -join ("CN={", $GPO.Id.Guid, "},", $PoliciesSearchBase)
Description = $GPO.Description
CreationTime = $GPO.CreationTime
ModificationTime = $GPO.ModificationTime
UserVersion = $GPO.UserVersion
ComputerVersion = $GPO.ComputerVersion
WmiFilter = $GPO.WmiFilter
Error = $ErrorMessage
}
}
# Now we need to list thru Sysvol files and fine those that do not exists as GPO and create dummy GPO objects to show orphaned gpos
foreach ($_ in $Differences.Keys) {
if ($Differences[$_] -eq 'Orphaned GPO') {
if ($SysvolHash[$_].BaseName -notcontains 'PolicyDefinitions') {
$FullPath = $SysvolHash[$_].FullName
try {
$ACL = Get-Acl -Path $FullPath -ErrorAction Stop
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrSysvol - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = $null
$ErrorMessage = $_.Exception.Message
}
if ($Differences[$_] -in 'Not available in AD', 'Permissions issue') {
$FullPath = $SysvolHash[$_].FullName
try {
$ACL = Get-Acl -Path $FullPath -ErrorAction Stop
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrBroken - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = $null
$ErrorMessage = $_.Exception.Message
}
[PSCustomObject] @{
DisplayName = $SysvolHash[$_].BaseName
Status = 'Orphaned GPO'
DomainName = $Domain
SysvolServer = $Server
SysvolStatus = $Differences[$GPO.Id.Guid]
Owner = ''
FileOwner = $Owner
Id = $_
GpoStatus = 'Orphaned'
Path = $FullPath
Description = $null
CreationTime = $SysvolHash[$_].CreationTime
ModificationTime = $SysvolHash[$_].LastWriteTime
UserVersion = $null
ComputerVersion = $null
WmiFilter = $null
Error = $ErrorMessage
}
[PSCustomObject] @{
DisplayName = $SysvolHash[$_].BaseName
Status = $Differences[$_]
DomainName = $Domain
SysvolServer = $Server
SysvolStatus = 'Exists' #$Differences[$GPO.Id.Guid]
GpoStatus = $Differences[$_]
Owner = ''
FileOwner = $Owner
Id = $_
Path = $FullPath
DistinguishedName = -join ("CN={", $_, "},", $PoliciesSearchBase)
Description = $null
CreationTime = $SysvolHash[$_].CreationTime
ModificationTime = $SysvolHash[$_].LastWriteTime
UserVersion = $null
ComputerVersion = $null
WmiFilter = $null
Error = $ErrorMessage
}
}
}
+2 -1
View File
@@ -69,7 +69,8 @@ function ConvertFrom-CSExtension {
'{D76B9641-3288-4f75-942D-087DE603E3EA}' = 'AdmPwd'
'{9650FDBC-053A-4715-AD14-FC2DC65E8330}' = 'Unknown'
'{B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A}' = 'EFS Recovery'
'{A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B}' = 'Internet Explorer Settings'
'{A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B}' = 'Internet Explorer Maintenance Policy Processing'
'{FC715823-C5FB-11D1-9EEF-00A0C90347FF}' = 'Internet Explorer Maintenance Extension Protocol' # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpie/f566a58a-4114-4981-b1e2-30b9d1a3c0e6
}
foreach ($C in $CSE) {
if (-not $Limited) {
+1 -1
View File
@@ -9,7 +9,7 @@ function Find-CSExtension {
foreach ($Key in $Keys.PSSubKeys) {
$RegistryKey = Get-PSRegistry -RegistryPath "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\$Key" -ComputerName $ComputerName
if ($CSE) {
foreach ($C in CSE) {
foreach ($C in $CSE) {
if ($RegistryKey.DefaultKey -eq $Key) {
[PSCustomObject] @{ Name = $Key; Description = $RegistryKey.DefaultKey }
}
+18 -6
View File
@@ -29,9 +29,13 @@
if (-not $GPOPath) {
foreach ($Domain in $ForestInformation.Domains) {
$QueryServer = $ForestInformation.QueryServers[$Domain]['HostName'][0]
$Count = 0
if ($GPOName) {
Get-GPO -Name $GPOName -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
$GroupPolicies = Get-GPO -Name $GPOName -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue
$GroupPolicies | ForEach-Object {
$Count++
#Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
Write-Verbose "Get-GPOZaurr - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
if (-not $Limited) {
try {
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
@@ -45,8 +49,11 @@
}
}
} elseif ($GPOGuid) {
Get-GPO -Guid $GPOGuid -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
$GroupPolicies = Get-GPO -Guid $GPOGuid -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue
$GroupPolicies | ForEach-Object {
$Count++
#Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
Write-Verbose "Get-GPOZaurr - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
if (-not $Limited) {
try {
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
@@ -60,8 +67,11 @@
}
}
} else {
Get-GPO -All -Server $QueryServer -Domain $Domain -ErrorAction SilentlyContinue | ForEach-Object {
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
$GroupPolicies = Get-GPO -All -Server $QueryServer -Domain $Domain -ErrorAction SilentlyContinue
$GroupPolicies | ForEach-Object {
$Count++
#Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
Write-Verbose "Get-GPOZaurr - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
if (-not $Limited) {
try {
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
@@ -78,11 +88,13 @@
}
} else {
foreach ($Path in $GPOPath) {
Write-Verbose "Get-GPOZaurr - Getting GPO content from XML files"
Get-ChildItem -LiteralPath $Path -Recurse -Filter *.xml | ForEach-Object {
$XMLContent = [XML]::new()
$XMLContent.Load($_.FullName)
Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -PermissionsOnly:$PermissionsOnly.IsPresent
}
Write-Verbose "Get-GPOZaurr - Finished GPO content from XML files"
}
}
}
+57
View File
@@ -0,0 +1,57 @@
function Get-GPOZaurrBroken {
[alias('Get-GPOZaurrSysvol')]
[cmdletBinding()]
param(
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[string[]] $ExcludeDomainControllers,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[alias('DomainControllers')][string[]] $IncludeDomainControllers,
[switch] $SkipRODC,
[Array] $GPOs,
[System.Collections.IDictionary] $ExtendedForestInformation,
[switch] $VerifyDomainControllers
)
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation -Extended
foreach ($Domain in $ForestInformation.Domains) {
$TimeLog = Start-TimeLog
Write-Verbose "Get-GPOZaurrBroken - Starting process for $Domain"
$QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0]
$SystemsContainer = $ForestInformation['DomainsExtended'][$Domain].SystemsContainer
$PoliciesAD = @{}
if ($SystemsContainer) {
$PoliciesSearchBase = -join ("CN=Policies,", $SystemsContainer)
$PoliciesInAD = Get-ADObject -SearchBase $PoliciesSearchBase -SearchScope OneLevel -Filter * -Server $QueryServer
foreach ($Policy in $PoliciesInAD) {
$GUIDFromDN = ConvertFrom-DistinguishedName -DistinguishedName $Policy.DistinguishedName
$GUIDFromDN = $GUIDFromDN -replace '{' -replace '}'
$GUID = $Policy.Name -replace '{' -replace '}'
if ($GUID -and $GUIDFromDN) {
$PoliciesAD[$GUIDFromDN] = 'Exists'
} else {
$PoliciesAD[$GUIDFromDN] = 'Permissions issue'
}
}
}
Try {
[Array]$GPOs = Get-GPO -All -Domain $Domain -Server $QueryServer
} catch {
Write-Warning "Get-GPOZaurrBroken - Couldn't get GPOs from $Domain. Error: $($_.Exception.Message)"
continue
}
if ($GPOs.Count -ge 2) {
if (-not $VerifyDomainControllers) {
Test-SysVolFolders -GPOs $GPOs -Server $Domain -Domain $Domain -PoliciesAD $PoliciesAD -PoliciesSearchBase $PoliciesSearchBase
} else {
foreach ($Server in $ForestInformation['DomainDomainControllers']["$Domain"]) {
Write-Verbose "Get-GPOZaurrBroken - Processing $Domain \ $($Server.HostName.Trim())"
Test-SysVolFolders -GPOs $GPOs -Server $Server.Hostname -Domain $Domain -PoliciesAD $PoliciesAD -PoliciesSearchBase $PoliciesSearchBase
}
}
} else {
Write-Warning "Get-GPOZaurrBroken - GPO count for $Domain is less then 2. This is not expected for fully functioning domain. Skipping processing SYSVOL folder."
}
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
Write-Verbose "Get-GPOZaurrBroken - Finishing process for $Domain (Time to process: $TimeEnd)"
}
}
+33 -12
View File
@@ -4,9 +4,9 @@
[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,
[switch] $ExtendedMetaData,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
@@ -265,7 +265,7 @@
$SuggestedAction = 'Requires verification'
$SuggestedActionComment = 'Not able to auto asses'
}
if ($Limited) {
if (-not $ExtendedMetaData) {
$MetaData = [ordered] @{
LocationType = $FileType.Name
FullName = $_.FullName
@@ -282,18 +282,39 @@
}
} else {
$MetaData = Get-FileMetaData -File $_ -AsHashTable
$MetaData['SuggestedAction'] = $SuggestedAction
$MetaData['SuggestedActionComment'] = $SuggestedActionComment
$MetaData['BelongsToGPO'] = $BelongsToGPO
$MetaData['GPODisplayName'] = $GPODisplayName
}
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
try {
$DigitalSignature = Get-AuthenticodeSignature -FilePath $_.Fullname -ErrorAction Stop
} catch {
Write-Warning "Get-GPOZaurrFiles - Error when reading signature: $($_.Exception.Message)"
}
if ($DigitalSignature) {
$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
}
} else {
$MetaData['SignatureStatus'] = 'Not available'
$MetaData['IsOSBinary'] = $null
$MetaData['SignatureCertificateSubject'] = $null
if ($Extended) {
$MetaData['SignatureCertificateIssuer'] = $null
$MetaData['SignatureCertificateSerialNumber'] = $null
$MetaData['SignatureCertificateNotBefore'] = $null
$MetaData['SignatureCertificateNotAfter'] = $null
$MetaData['SignatureCertificateThumbprint'] = $null
}
}
}
if ($HashAlgorithm -ne 'None') {
+3 -3
View File
@@ -17,7 +17,6 @@
$OrganizationalUnits = Get-ADOrganizationalUnit -Filter * -Properties gpOptions, canonicalName -Server $ForestInformation['QueryServers'][$Domain]['HostName'][0]
foreach ($OU in $OrganizationalUnits) {
$InheritanceInformation = [Ordered] @{
DistinguishedName = $OU.DistinguishedName
CanonicalName = $OU.canonicalName
BlockedInheritance = if ($OU.gpOptions -eq 1) { $true } else { $false }
}
@@ -34,8 +33,8 @@
if ($InheritanceInformation.BlockedInheritance -eq $true) {
$InheritanceInformation['UsersCount'] = $null
$InheritanceInformation['ComputersCount'] = $null
$InheritanceInformation['Users'] = Get-ADUser -SearchBase $InheritanceInformation.DistinguishedName -Server $ForestInformation['QueryServers'][$Domain]['HostName'][0] -Filter *
$InheritanceInformation['Computers'] = Get-ADComputer -SearchBase $InheritanceInformation.DistinguishedName -Server $ForestInformation['QueryServers'][$Domain]['HostName'][0] -Filter *
[Array] $InheritanceInformation['Users'] = (Get-ADUser -SearchBase $OU.DistinguishedName -Server $ForestInformation['QueryServers'][$Domain]['HostName'][0] -Filter *).SamAccountName
[Array] $InheritanceInformation['Computers'] = (Get-ADComputer -SearchBase $OU.DistinguishedName -Server $ForestInformation['QueryServers'][$Domain]['HostName'][0] -Filter *).SamAccountName
$InheritanceInformation['UsersCount'] = $InheritanceInformation['Users'].Count
$InheritanceInformation['ComputersCount'] = $InheritanceInformation['Computers'].Count
} else {
@@ -53,6 +52,7 @@
[PSCustomObject] $InheritanceInformation
}
}
$InheritanceInformation['DistinguishedName'] = $OU.DistinguishedName
}
}
}
+70
View File
@@ -0,0 +1,70 @@
function Get-GPOZaurrNetLogon {
[cmdletBinding(DefaultParameterSetName = 'Default')]
param(
[parameter(ParameterSetName = 'OwnerOnly')][switch] $OwnerOnly,
[parameter(ParameterSetName = 'SkipOwner')][switch] $SkipOwner
)
$ForestInformation = Get-WinADForestDetails -Extended
$FilesAll = foreach ($Domain in $ForestInformation.Domains) {
$Path = -join ("\\", $Domain, '\Netlogon')
$Files = Get-ChildItem -LiteralPath $Path -Recurse
foreach ($_ in $Files) {
$ACL = Get-Acl -Path $_.FullName
if ($ACL.Owner) {
$IdentityOwner = Convert-Identity -Identity $ACL.Owner
} else {
$IdentityOwner = [PSCustomObject] @{ SID = ''; Type = 'Uknown' }
}
if (-not $OwnerOnly) {
if (-not $SkipOwner) {
[PSCustomObject] @{
FullName = $_.FullName
Extension = $_.Extension
CreationTime = $_.CreationTime
LastAccessTime = $_.LastAccessTime
LastWriteTime = $_.LastWriteTime
Attributes = $_.Attributes
AccessControlType = 'Allow' # : Allow
Principal = $IdentityOwner.Name # : BUILTIN\Administrators
PrincipalSid = $IdentityOwner.SID
PrincipalType = $IdentityOwner.Type
FileSystemRights = 'Owner' # : FullControl
IsInherited = $false
#Owner = $ACL.Owner
}
}
$FilePermission = Get-FilePermissions -Path $_.FullName -ACLS $ACL
foreach ($Perm in $FilePermission) {
$Identity = Convert-Identity -Identity $Perm.Principal
[PSCustomObject] @{
FullName = $_.FullName
Extension = $_.Extension
CreationTime = $_.CreationTime
LastAccessTime = $_.LastAccessTime
LastWriteTime = $_.LastWriteTime
Attributes = $_.Attributes
AccessControlType = $Perm.AccessControlType # : Allow
Principal = $Identity.Name # : BUILTIN\Administrators
PrincipalSid = $Identity.SID
PrincipalType = $Identity.Type
FileSystemRights = $Perm.FileSystemRights # : FullControl
IsInherited = $Perm.IsInherited # : True
}
}
} else {
[PSCustomObject] @{
FullName = $_.FullName
Extension = $_.Extension
CreationTime = $_.CreationTime
LastAccessTime = $_.LastAccessTime
LastWriteTime = $_.LastWriteTime
Attributes = $_.Attributes
Owner = $IdentityOwner.Name
OwnerSid = $IdentityOwner.SID
OwnerType = $IdentityOwner.Type
}
}
}
}
$FilesAll
}
+3
View File
@@ -49,6 +49,9 @@
$Object['SysvolType'] = $FileOwner.OwnerType
$Object['SysvolPath'] = $_.Path
$Object['IsOwnerConsistent'] = if ($ACL.OwnerName -eq $FileOwner.OwnerName) { $true } else { $false }
$Object['IsOwnerAdministrative'] = if ($Object['SysvolType'] -eq 'Administrative' -and $Object['OwnerType'] -eq 'Administrative') { $true } else { $false }
} else {
$Object['IsOwnerAdministrative'] = if ($Object['OwnerType'] -eq 'Administrative') { $true } else { $false }
}
$Object['DistinguishedName'] = $_.GPODistinguishedName
[PSCUstomObject] $Object
+5 -3
View File
@@ -8,13 +8,13 @@
[alias('GUID', 'GPOID')][string] $GPOGuid,
[string[]] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
[validateset('DistinguishedName', 'Name', 'NetbiosName', 'Sid')][string] $PrincipalType = 'Sid',
[validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All',
[switch] $SkipWellKnown,
[switch] $SkipAdministrative,
[switch] $ResolveAccounts,
#[switch] $ResolveAccounts,
[switch] $IncludeOwner,
[Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
@@ -43,6 +43,7 @@
Write-Warning "Get-GPOZaurrPermission - Using SkipAdministrative or SkipWellKnown while looking for Unknown doesn't make sense as only Unknown will be displayed."
}
}
<#
if ($ResolveAccounts) {
$Accounts = @{ }
foreach ($Domain in $ForestInformation.Domains) {
@@ -60,6 +61,7 @@
}
}
}
#>
}
Process {
foreach ($Domain in $ForestInformation.Domains) {
@@ -96,7 +98,7 @@
Principal = $Principal
PrincipalType = $PrincipalType
PermitType = $PermitType
Accounts = $Accounts
#Accounts = $Accounts
Type = $Type
GPO = $_
SkipWellKnown = $SkipWellKnown.IsPresent
+26 -16
View File
@@ -16,6 +16,8 @@
}
Process {
foreach ($Domain in $ForestInformation.Domains) {
$TimeLog = Start-TimeLog
Write-Verbose "Get-GPOZaurrPermissionConsistency - Starting process for $Domain"
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
if ($GPOName) {
$getGPOSplat = @{
@@ -39,30 +41,36 @@
ErrorAction = 'SilentlyContinue'
}
}
Get-GPO @getGPOSplat | ForEach-Object -Process {
$GroupPolicies = Get-GPO @getGPOSplat
$Count = 0
$GroupPolicies | ForEach-Object -Process {
$Count++
Write-Verbose "Get-GPOZaurrPermissionConsistency - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
try {
$IsConsistent = $_.IsAclConsistent()
$ErrorMessage = ''
} catch {
$ErrorMessage = $_.Exception.Message
Write-Warning "Get-GPOZaurrPermissionConsistency - Failed to get consistency: $($_.Exception.Message)."
$IsConsistent = 'Not available.'
$IsConsistent = 'Not available'
}
$SysVolpath = -join ('\\', $Domain, '\sysvol\', $Domain, '\Policies\{', $_.ID.GUID, '}')
if ($VerifyInheritance) {
$FolderPermissions = Get-WinADSharePermission -Path $SysVolpath
[Array] $NotInheritedPermissions = foreach ($File in $FolderPermissions) {
if ($File.Path -ne $SysVolpath -and $File.IsInherited -eq $false) {
$File
$FolderPermissions = Get-WinADSharePermission -Path $SysVolpath -Verbose:$false
if ($FolderPermissions) {
[Array] $NotInheritedPermissions = foreach ($File in $FolderPermissions) {
if ($File.Path -ne $SysVolpath -and $File.IsInherited -eq $false) {
$File
}
}
if ($NotInheritedPermissions.Count -eq 0) {
$ACLConsistentInside = $true
} else {
$ACLConsistentInside = $false
}
}
if ($NotInheritedPermissions.Count -eq 0) {
$ACLConsistentInside = $true
} else {
$ACLConsistentInside = $false
$ACLConsistentInside = 'Not available'
}
} else {
$ACLConsistentInside = $null
}
$Object = [ordered] @{
DisplayName = $_.DisplayName # : New Group Policy Object
@@ -94,26 +102,28 @@
[PSCustomObject] $Object
} elseif ($Type -eq 'Inconsistent') {
if ($VerifyInheritance) {
if (-not $IsConsistent -or -not $ACLConsistentInside) {
if (-not ($IsConsistent -eq $true) -or (-not $ACLConsistentInside -eq $true)) {
[PSCustomObject] $Object
}
} else {
if (-not $IsConsistent) {
if (-not ($IsConsistent -eq $true)) {
[PSCustomObject] $Object
}
}
} elseif ($Type -eq 'Consistent') {
if ($VerifyInheritance) {
if ($IsConsistent -and $ACLConsistentInside) {
if ($IsConsistent -eq $true -and $ACLConsistentInside -eq $true) {
[PSCustomObject] $Object
}
} else {
if ($IsConsistent) {
if ($IsConsistent -eq $true) {
[PSCustomObject] $Object
}
}
}
}
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
Write-Verbose "Get-GPOZaurrPermissionConsistency - Finishing process for $Domain (Time to process: $TimeEnd)"
}
}
End {
+62
View File
@@ -0,0 +1,62 @@
function Get-GPOZaurrPermissionRoot {
[cmdletBinding()]
param(
[ValidateSet('GpoRootCreate', 'GpoRootOwner')][string[]] $IncludePermissionType,
[ValidateSet('GpoRootCreate', 'GpoRootOwner')][string[]] $ExcludePermissionType,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation
)
Begin {
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Extended
}
Process {
foreach ($Domain in $ForestInformation.Domains) {
$DomainDistinguishedName = $ForestInformation['DomainsExtended'][$Domain].DistinguishedName
$QueryServer = $ForestInformation['QueryServers'][$Domain].HostName[0]
$getADACLSplat = @{
ADObject = "CN=Policies,CN=System,$DomainDistinguishedName"
IncludeActiveDirectoryRights = 'GenericAll', 'CreateChild', 'WriteOwner', 'WriteDACL'
IncludeObjectTypeName = 'All', 'Group-Policy-Container'
IncludeInheritedObjectTypeName = 'All', 'Group-Policy-Container'
ADRightsAsArray = $true
ResolveTypes = $true
}
$GPOPermissionsGlobal = Get-ADACL @getADACLSplat -Verbose:$false
$GPOs = Get-ADObject -SearchBase "CN=Policies,CN=System,$DomainDistinguishedName" -SearchScope OneLevel -Filter * -Properties DisplayName -Server $QueryServer -Verbose:$false
foreach ($Permission in $GPOPermissionsGlobal) {
$CustomPermission = foreach ($_ in $Permission.ActiveDirectoryRights) {
if ($_ -in 'WriteDACL', 'WriteOwner', 'GenericAll' ) {
'GpoRootOwner'
}
if ($_ -in 'CreateChild', 'GenericAll') {
'GpoRootCreate'
}
}
$CustomPermission = $CustomPermission | Sort-Object -Unique
foreach ($SinglePermission in $CustomPermission) {
if ($SinglePermission -in $ExcludePermissionType) {
continue
}
if ($IncludePermissionType.Count -gt 0 -and $SinglePermission -notin $IncludePermissionType) {
continue
}
[PSCustomObject] @{
PrincipalName = $Permission.Principal
Permission = $SinglePermission
PermissionType = $Permission.AccessControlType
PrincipalSidType = $Permission.PrincipalType
PrincipalObjectClass = $Permission.PrincipalObjectType
PrincipalDomainName = $Permission.PrincipalObjectDomain
PrincipalSid = $Permission.PrincipalObjectSid
GPOCount = $GPOs.Count
GPONames = $GPOs.DisplayName
DomainName = $Domain
}
}
}
}
}
End {}
}
+130
View File
@@ -0,0 +1,130 @@
function Get-GPOZaurrPermissionSummary {
[cmdletBinding()]
param(
[validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All',
[validateSet('Allow', 'Deny', 'All')][string] $PermitType = 'All',
[ValidateSet('GpoApply', 'GpoEdit', 'GpoCustom', 'GpoEditDeleteModifySecurity', 'GpoRead', 'GpoOwner', 'GpoRootCreate', 'GpoRootOwner')][string[]] $IncludePermissionType,
[ValidateSet('GpoApply', 'GpoEdit', 'GpoCustom', 'GpoEditDeleteModifySecurity', 'GpoRead', 'GpoOwner', 'GpoRootCreate', 'GpoRootOwner')][string[]] $ExcludePermissionType,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation,
[string] $Separator
)
$IncludePermTypes = [System.Collections.Generic.List[Microsoft.GroupPolicy.GPPermissionType]]::new()
$ExcludePermTypes = [System.Collections.Generic.List[Microsoft.GroupPolicy.GPPermissionType]]::new()
$CustomPermissions = [System.Collections.Generic.List[string]]::new()
foreach ($PermType in $IncludePermissionType) {
if ($PermType -in 'GpoApply', 'GpoEdit', 'GPOCustom', 'GpoEditDeleteModifySecurity', 'GPORead') {
$IncludePermTypes.Add([Microsoft.GroupPolicy.GPPermissionType]::$PermType)
} elseif ($PermType -in 'GpoOwner') {
$IncludeOwner = $true
} elseif ($PermType -in 'GpoRootCreate', 'GpoRootOwner') {
$CustomPermissions.Add($PermType)
}
}
foreach ($PermType in $ExcludePermissionType) {
if ($PermType -in 'GpoApply', 'GpoEdit', 'GPOCustom', 'GpoEditDeleteModifySecurity', 'GPORead') {
$ExcludePermTypes.Add([Microsoft.GroupPolicy.GPPermissionType]::$PermType)
} elseif ($PermType -in 'GpoOwner') {
$IncludeOwner = $false
} elseif ($PermType -in 'GpoRootCreate', 'GpoRootOwner') {
$CustomPermissions.Add($PermType)
}
}
$RootPermissions = Get-GPOZaurrPermissionRoot -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
$Permissions = Get-GPOZaurrPermission -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -IncludePermissionType $IncludePermTypes -ExcludePermissionType $ExcludePermissionType -Type $Type -PermitType $PermitType -IncludeOwner:$IncludeOwner
$Entries = @(
foreach ($Permission in $Permissions) {
[PSCustomObject] @{
PrincipalName = $Permission.PrincipalName
PrincipalDomainName = $Permission.PrincipalDomainName
Permission = $Permission.Permission
PermissionType = $Permission.PermissionType
PrincipalSid = $Permission.PrincipalSid
PrincipalSidType = $Permission.PrincipalSidType
PrincipalObjectClass = $Permission.PrincipalObjectClass
DisplayName = $Permission.DisplayName
DomainName = $Permission.DomainName
}
}
foreach ($RootPermission in $RootPermissions) {
[PSCustomObject] @{
PrincipalName = $RootPermission.PrincipalName
PrincipalDomainName = $RootPermission.PrincipalDomainName
Permission = $RootPermission.Permission
PermissionType = $RootPermission.PermissionType
PrincipalSid = $RootPermission.PrincipalSid
PrincipalSidType = $RootPermission.PrincipalSidType
PrincipalObjectClass = $RootPermission.PrincipalObjectClass
DisplayName = $RootPermission.GPONames
DomainName = $RootPermission.DomainName
}
}
)
$PermissionsData = [ordered] @{}
foreach ($Entry in $Entries) {
$Key = -join ($Entry.Permission, $Entry.PrincipalName, $Entry.PrincipalDomainName)
if (-not $PermissionsData[$Key]) {
$PermissionsData[$Key] = [PSCustomObject] @{
Permission = $Entry.Permission
PrincipalName = $Entry.PrincipalName
PrincipalDomainName = $Entry.PrincipalDomainName
PrincipalSidType = $Entry.PrincipalSidType
DomainName = $Entry.DomainName
PermissionType = $Entry.PermissionType
GPOCOunt = 0
GPONames = [System.Collections.Generic.List[string]]::new()
}
}
#if ($IncludeNames) {
$PermissionsData[$Key].GPONames.Add($Entry.DisplayName)
#}
$PermissionsData[$Key].GPOCOunt = $PermissionsData[$Key].GPOCOunt + ($Entry.DisplayName).Count
}
$PermissionsData.Values
<#
($Entries | Group-Object -Property Permission, PrincipalSidType, PrincipalName, PrincipalDomainName, DomainName, PermissionType) | ForEach-Object {
$Property = $_.Name -split ', '
Write-Verbose "$Property - $($Property.Count)"
if ($Property[0] -eq 'GpoOwner') {
[PSCustomObject] @{
Permission = $Property[0]
PrincipalSidType = $Property[1]
PrincipalName = $Property[2]
PrincipalDomainName = $Property[3]
DomainName = $Property[4]
PermissionType = 'Allow'
GPOCount = $_.Count
GPONames = if ($Separator) { $_.Group.DisplayName -join $Separator } else { $_.Group.DisplayName }
}
} elseif ($Property.Count -eq 5) {
[PSCustomObject] @{
Permission = $Property[0]
PrincipalSidType = $Property[1]
PrincipalName = $Property[2]
PrincipalDomainName = $Property[3]
DomainName = $Property[4]
PermissionType = if ($Property[5]) { $Property[5] } else { 'Owner' }
GPOCount = $_.Count
GPONames = if ($Separator) { $_.Group.DisplayName -join $Separator } else { $_.Group.DisplayName }
}
} else {
[PSCustomObject] @{
Permission = $Property[0]
PrincipalSidType = $Property[1]
PrincipalName = ''
PrincipalDomainName = ''
DomainName = $Property[2]
PermissionType = if ($Property[3]) { $Property[3] } else { 'Owner' }
GPOCount = $_.Count
GPONames = if ($Separator) { $_.Group.DisplayName -join $Separator } else { $_.Group.DisplayName }
}
}
}
#>
}
-37
View File
@@ -1,37 +0,0 @@
function Get-GPOZaurrSysvol {
[cmdletBinding()]
param(
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[string[]] $ExcludeDomainControllers,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[alias('DomainControllers')][string[]] $IncludeDomainControllers,
[switch] $SkipRODC,
[Array] $GPOs,
[System.Collections.IDictionary] $ExtendedForestInformation,
[switch] $VerifyDomainControllers
)
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation
foreach ($Domain in $ForestInformation.Domains) {
Write-Verbose "Get-WinADGPOSysvolFolders - Processing $Domain"
$QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0]
Try {
[Array]$GPOs = Get-GPO -All -Domain $Domain -Server $QueryServer
} catch {
Write-Warning "Get-GPOZaurrSysvol - Couldn't get GPOs from $Domain. Error: $($_.Exception.Message)"
continue
}
if ($GPOs.Count -ge 2) {
if (-not $VerifyDomainControllers) {
Test-SysVolFolders -GPOs $GPOs -Server $Domain -Domain $Domain
} else {
foreach ($Server in $ForestInformation['DomainDomainControllers']["$Domain"]) {
Write-Verbose "Get-GPOZaurrSysvol - Processing $Domain \ $($Server.HostName.Trim())"
Test-SysVolFolders -GPOs $GPOs -Server $Server.Hostname -Domain $Domain
}
}
} else {
Write-Warning "Get-GPOZaurrSysvol - GPO count for $Domain is less then 2. This is not expected for fully functioning domain. Skipping processing SYSVOL folder."
}
}
}
+47 -7
View File
@@ -21,11 +21,9 @@
[Parameter(ParameterSetName = 'Local')]
[switch] $FullObjects,
<#
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Local')]
[ValidateSet('HTML', 'Object', 'Excel')][string[]] $OutputType = 'Object',
[ValidateSet('HTML', 'Object')][string[]] $OutputType = 'Object',
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Local')]
@@ -34,7 +32,10 @@
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Local')]
[switch] $Open,
#>
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Local')]
[switch] $Online,
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Local')]
@@ -50,12 +51,15 @@
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Local')]
[switch] $SkipCleanup
[switch] $SkipCleanup,
[switch] $Extended
)
if ($Type.Count -eq 0) {
$Type = $Script:GPODitionary.Keys
}
if ($GPOPath) {
Write-Verbose "Invoke-GPOZaurr - Reading GPOs from $GPOPath"
if (Test-Path -LiteralPath $GPOPath) {
$GPOFiles = Get-ChildItem -LiteralPath $GPOPath -Recurse -File -Filter *.xml
[Array] $GPOs = foreach ($File in $GPOFiles) {
@@ -79,6 +83,7 @@
return
}
} else {
Write-Verbose "Invoke-GPOZaurr - Query AD for GPOs"
[Array] $GPOs = Get-GPOZaurrAD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
}
# This caches single reports.
@@ -89,6 +94,7 @@
$Output['Reports'] = [ordered] @{}
$Output['CategoriesFull'] = [ordered] @{}
Write-Verbose "Invoke-GPOZaurr - Loading GPO Report to Categories"
[Array] $GPOCategories = foreach ($GPO in $GPOs) {
if ($GPOPath) {
$GPOOutput = $GPO.GPOOutput
@@ -109,6 +115,7 @@
# Build reports based on categories
if ($Output['CategoriesFull'].Count -gt 0) {
foreach ($Report in $Type) {
Write-Verbose "Invoke-GPOZaurr - Processing report type $Report"
foreach ($CategoryType in $Script:GPODitionary[$Report].Types) {
$Category = $CategoryType.Category
$Settings = $CategoryType.Settings
@@ -142,6 +149,7 @@
}
}
if ($Script:GPODitionary[$Report]['CodeSingle']) {
#Write-Verbose "Invoke-GPOZaurr - Processing $Report single entry mode"
$TranslatedGpo = Invoke-Command -ScriptBlock $Script:GPODitionary[$Report]['CodeSingle']
if ($Report -in $FindRequiredSingle) {
foreach ($T in $TranslatedGpo) {
@@ -160,6 +168,7 @@
# think drive mapping - showing 1 mapping of a drive per object even if there are 50 drive mappings within 1 gpo
# this would result in 50 objects created
if ($Script:GPODitionary[$Report]['Code']) {
#Write-Verbose "Invoke-GPOZaurr - Processing $Report multi entry mode"
$TranslatedGpo = Invoke-Command -ScriptBlock $Script:GPODitionary[$Report]['Code']
foreach ($T in $TranslatedGpo) {
$Output['Reports'][$Report].Add($T)
@@ -178,6 +187,7 @@
$Output['Reports'][$Report] = [System.Collections.Generic.List[PSCustomObject]]::new()
}
$FindReport = $ReportType.Report
Write-Verbose "Invoke-GPOZaurr - Processing reports based on other report $Report ($FindReport)"
foreach ($GPO in $TemporaryCachedSingleReports['ReportsSingle'][$FindReport]) {
$TranslatedGpo = Invoke-Command -ScriptBlock $Script:GPODitionary[$Report]['CodeReport']
foreach ($T in $TranslatedGpo) {
@@ -193,7 +203,8 @@
if (-not $SkipNormalize) {
foreach ($Report in [string[]] $Output['Reports'].Keys) {
$FirstProperties = 'DisplayName', 'DomainName', 'GUID', 'GpoType'
$EndProperties = 'CreatedTime', 'ModifiedTime', 'ReadTime', 'Filters', 'Linked', 'LinksCount', 'Links'
#$EndProperties = 'CreatedTime', 'ModifiedTime', 'ReadTime', 'Filters', 'Linked', 'LinksCount', 'Links'
$EndProperties = 'Filters', 'Linked', 'LinksCount', 'Links'
$Properties = $Output['Reports'][$Report] | Select-Properties -ExcludeProperty ($FirstProperties + $EndProperties) -AllProperties -WarningAction SilentlyContinue
$DisplayProperties = @(
$FirstProperties
@@ -210,9 +221,38 @@
#$Output['PoliciesTotal'] = $Output.Reports.Policies.PolicyCategory | Group-Object | Select-Object Name, Count | Sort-Object -Property Count -Descending
if (-not $SkipCleanup) {
Write-Verbose "Invoke-GPOZaurr - Cleaning up output"
Remove-EmptyValue -Hashtable $Output -Recursive
}
return $Output
if ($Extended) {
$Output
} else {
if ($Output.Reports) {
if ($OutputType -eq 'Object') {
$Output.Reports
}
if ($OutputType -eq 'HTML') {
if (-not $OutputPath) {
$OutputPath = Get-FileName -Extension 'html' -Temporary
Write-Warning "Invoke-GPOZaurr - OutputPath not given. Using $OutputPath"
}
Write-Verbose "Invoke-GPOZaurr - Generating HTML output"
New-HTML {
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
New-HTMLTableOption -DataStore JavaScript
foreach ($Key in $Output.Reports.Keys) {
New-HTMLTab -Name $Key {
Write-Verbose "Invoke-GPOZaurr - Generating HTML Table for $Key"
New-HTMLTable -DataTable $Output.Reports[$Key] -Filtering -Title $Key
}
}
} -FilePath $OutputPath -ShowHTML:$Open -Online:$Online
}
} else {
Write-Warning "Invoke-GPOZaurr - There was no data output for requested types."
}
}
}
[scriptblock] $SourcesAutoCompleter = {
+110 -18
View File
@@ -7,26 +7,30 @@
[string] $Path,
[string] $Splitter = [System.Environment]::NewLine,
[switch] $PreventShow,
[switch] $Offline
[switch] $Offline,
[switch] $ForceGPResult
)
# if user didn't choose anything, lets run as currently logged in user locally
if (-not $UserName -and -not $ComputerName) {
$UserName = $Env:USERNAME
# we can also check if the session is Administrative and if so request computer policies
if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
$ComputerName = $Env:COMPUTERNAME
}
}
If ($Type -eq 'HTML') {
$Exists = Get-Command -Name 'New-HTML' -ErrorAction SilentlyContinue
if (-not $Exists) {
Write-Warning "Request-GPOZaurr - PSWriteHTML module is required for HTML functionality. Use XML, Object or NativeHTML option instead."
Write-Warning "Invoke-GPOZaurrSupport - PSWriteHTML module is required for HTML functionality. Use XML, Object or NativeHTML option instead."
return
}
}
$Command = Get-Command -Name 'Get-GPResultantSetOfPolicy' -ErrorAction SilentlyContinue
$NativeCommand = Get-Command -Name 'gpresult' -ErrorAction SilentlyContinue
if (-not $Command -and -not $NativeCommand) {
Write-Warning "Invoke-GPOZaurrSupport - Neither gpresult or Get-GPResultantSetOfPolicy are available. Terminating."
return
}
$SplatPolicy = @{}
if ($Type -in 'Object', 'XML', 'HTML') {
@@ -50,22 +54,42 @@
if ($UserName) {
$SplatPolicy['User'] = $UserName
}
try {
#Write-Verbose "Request-GPOZaurr - ComputerName: $($SplatPolicy['Computer']) UserName: $($SplatPolicy['User'])"
$ResultantSetPolicy = Get-GPResultantSetOfPolicy @SplatPolicy -ErrorAction Stop
} catch {
if ($_.Exception.Message -eq 'Exception from HRESULT: 0x80041003') {
Write-Warning "Request-GPOZaurr - Are you running as admin? $($_.Exception.Message)"
return
} else {
$ErrorMessage = $($_.Exception.Message).Replace([Environment]::NewLine, ' ')
Write-Warning "Request-GPOZaurr - Error: $ErrorMessage"
return
if ($Command -and -not $ForceGPResult) {
try {
#Write-Verbose "Request-GPOZaurr - ComputerName: $($SplatPolicy['Computer']) UserName: $($SplatPolicy['User'])"
$ResultantSetPolicy = Get-GPResultantSetOfPolicy @SplatPolicy -ErrorAction Stop
} catch {
if ($_.Exception.Message -eq 'Exception from HRESULT: 0x80041003') {
Write-Warning "Request-GPOZaurr - Are you running as admin? $($_.Exception.Message)"
return
} else {
$ErrorMessage = $($_.Exception.Message).Replace([Environment]::NewLine, ' ')
Write-Warning "Request-GPOZaurr - Error: $ErrorMessage"
return
}
}
} else {
$Arguments = @(
if ($SplatPolicy['Computer']) {
"/S $ComputerName"
}
if ($SplatPolicy['User']) {
"/USER $($SplatPolicy['User'])"
}
if ($SplatPolicy['ReportType'] -eq 'HTML') {
'/H'
} elseif ($SplatPolicy['ReportType'] -eq 'XML') {
'/X'
}
$SplatPolicy['Path']
"/F"
)
Write-Verbose "Invoke-GPOZaurrSupport - GPResult Arguments: $Arguments"
Start-Process -NoNewWindow -FilePath 'gpresult' -ArgumentList $Arguments -Wait
}
if ($Type -eq 'NativeHTML') {
if (-not $PreventShow) {
Write-Verbose "Invoke-GPOZaurrSupport - Opening up file $SplatPolicy['Path']"
Write-Verbose "Invoke-GPOZaurrSupport - Opening up file $($SplatPolicy['Path'])"
Start-Process -FilePath $SplatPolicy['Path']
}
return
@@ -109,4 +133,72 @@
New-GPOZaurrReportHTML -Path $Path -Offline:$Offline -Open:(-not $PreventShow) -Support $Output
}
}
}
}
<#
GPRESULT [/S system [/U username [/P [password]]]] [/SCOPE scope]
[/USER targetusername] [/R | /V | /Z] [(/X | /H) <filename> [/F]]
Description:
This command line tool displays the Resultant Set of Policy (RSoP)
information for a target user and computer.
Parameter List:
/S system Specifies the remote system to connect to.
/U [domain\]user Specifies the user context under which the
command should run.
Can not be used with /X, /H.
/P [password] Specifies the password for the given user
context. Prompts for input if omitted.
Cannot be used with /X, /H.
/SCOPE scope Specifies whether the user or the
computer settings need to be displayed.
Valid values: "USER", "COMPUTER".
/USER [domain\]user Specifies the user name for which the
RSoP data is to be displayed.
/X <filename> Saves the report in XML format at the
location and with the file name specified
by the <filename> parameter. (valid in Windows
Vista SP1 and later and Windows Server 2008 and later)
/H <filename> Saves the report in HTML format at the
location and with the file name specified by
the <filename> parameter. (valid in Windows
at least Vista SP1 and at least Windows Server 2008)
/F Forces Gpresult to overwrite the file name
specified in the /X or /H command.
/R Displays RSoP summary data.
/V Specifies that verbose information should
be displayed. Verbose information provides
additional detailed settings that have
been applied with a precedence of 1.
/Z Specifies that the super-verbose
information should be displayed. Super-
verbose information provides additional
detailed settings that have been applied
with a precedence of 1 and higher. This
allows you to see if a setting was set in
multiple places. See the Group Policy
online help topic for more information.
/? Displays this help message.
Examples:
GPRESULT /R
GPRESULT /H GPReport.html
GPRESULT /USER targetusername /V
GPRESULT /S system /USER targetusername /SCOPE COMPUTER /Z
GPRESULT /S system /U username /P password /SCOPE USER /V
#>
+75
View File
@@ -0,0 +1,75 @@
function Remove-GPOZaurrBroken {
[alias('Remove-GPOZaurrOrphaned')]
[cmdletBinding(SupportsShouldProcess)]
param(
[ValidateSet('SYSVOL', 'AD')][string[]] $Type = @('SYSVOL', 'AD'),
[string] $BackupPath,
[switch] $BackupDated,
[int] $LimitProcessing = [int32]::MaxValue,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation
)
if ($BackupPath) {
if ($BackupDated) {
$BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))"
} else {
$BackupFinalPath = $BackupPath
}
} else {
$BackupFinalPath = ''
}
Get-GPOZaurrSysvol -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation | Where-Object {
if ($Type -contains 'SYSVOL') {
if ($_.Status -eq 'Not available in AD') {
$_
}
}
if ($Type -contains 'AD') {
if ($_.Status -eq 'Not available on SYSVOL') {
$_
}
}
} | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object {
if ($_.Status -eq 'Not available in AD') {
Write-Verbose "Remove-GPOZaurrBroken - Processing $($_.Path)"
if ($BackupFinalPath) {
Try {
Write-Verbose "Remove-GPOZaurrBroken - Backing up $($_.Path)"
Copy-Item -LiteralPath $_.Path -Recurse -Destination $BackupFinalPath -ErrorAction Stop
$BackupWorked = $true
} catch {
Write-Warning "Remove-GPOZaurrBroken - Error backing up error: $($_.Exception.Message)"
$BackupWorked = $false
}
}
if ($BackupWorked -or $BackupFinalPath -eq '') {
Write-Verbose "Remove-GPOZaurrBroken - Deleting $($_.Path)"
try {
Remove-Item -Recurse -Force -LiteralPath $_.Path
} catch {
Write-Warning "Remove-GPOZaurrBroken - Failed to remove file $($_.Path): $($_.Exception.Message)."
}
}
} elseif ($_.Status -eq 'Not available on SYSVOL') {
try {
$ExistingObject = Get-ADObject -Identity $_.DistinguishedName -Server $_.DomainName -ErrorAction Stop
} catch {
Write-Warning "Remove-GPOZaurrBroken - Error getting $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
$ExistingObject = $null
}
if ($ExistingObject -and $ExistingObject.ObjectClass -eq 'groupPolicyContainer') {
Write-Verbose "Remove-GPOZaurrBroken - Removing DN: $($_.DistinguishedName) / ObjectClass: $($ExistingObject.ObjectClass)"
try {
Remove-ADObject -Server $_.DomainName -Identity $_.DistinguishedName -Recursive -Confirm:$false
} catch {
Write-Warning "Remove-GPOZaurrBroken - Failed to remove $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
}
} else {
Write-Warning "Remove-GPOZaurrBroken - DistinguishedName $($_.DistinguishedName) not found or ObjectClass is not groupPolicyContainer ($($ExistingObject.ObjectClass))"
}
}
}
}
@@ -1,48 +0,0 @@
function Remove-GPOZaurrOrphanedSysvolFolders {
[cmdletBinding(SupportsShouldProcess)]
param(
[string] $BackupPath,
[switch] $BackupDated,
[int] $LimitProcessing = [int32]::MaxValue,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation
)
if ($BackupPath) {
if ($BackupDated) {
$BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))"
} else {
$BackupFinalPath = $BackupPath
}
} else {
$BackupFinalPath = ''
}
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 {
Write-Verbose "Remove-GPOZaurrOrphanedSysvolFolders - Backing up $($_.Path)"
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 -or $BackupFinalPath -eq '') {
Write-Verbose "Remove-GPOZaurrOrphanedSysvolFolders - Deleting $($_.Path)"
try {
Remove-Item -Recurse -Force -LiteralPath $_.Path
} catch {
$ErrorMessage = $_.Exception.Message
Write-Warning "Remove-GPOZaurrOrphanedSysvolFolders - Failed to remove file $($_.Path): $($ErrorMessage)."
}
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
[alias('GUID', 'GPOID')][string] $GPOGuid,
[string[]] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
[validateset('DistinguishedName', 'Name', 'NetbiosName', 'Sid')][string] $PrincipalType = 'Sid',
[validateset('Unknown', 'NotAdministrative', 'Default')][string[]] $Type = 'Default',
+4
View File
@@ -17,8 +17,12 @@
}
}
$null = New-Item -ItemType Directory -Path $GPOPath -Force
Write-Verbose "Save-GPOZaurrFiles - Gathering GPO data"
$Count = 0
$GPOs = Get-GPOZaurrAD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
foreach ($GPO in $GPOS) {
$Count++
Write-Verbose "Save-GPOZaurrFiles - Processing GPO ($Count/$($GPOS.Count)) $($GPO.DomainName) | $($GPO.DisplayName)"
$XMLContent = Get-GPOReport -ID $GPO.Guid -ReportType XML -Domain $GPO.DomainName
$GPODOmainFolder = [io.path]::Combine($GPOPath, $GPO.DomainName)
if (-not (Test-Path -Path $GPODOmainFolder)) {
+457
View File
@@ -0,0 +1,457 @@
function Show-GPOZaurr {
[cmdletBinding()]
param(
[string] $FilePath,
[ValidateSet(
'GPOList', 'GPOOrphans', 'GPOPermissions', 'GPOPermissionsRoot', 'GPOFiles',
'GPOConsistency', 'GPOOwners', 'GPOAnalysis', 'NetLogon'
)][string[]] $Type
)
$Script:Reporting = [ordered] @{
}
# Provide version check for easy use
$GPOZaurrVersion = Get-Command -Name 'Show-GPOZaurr' -ErrorAction SilentlyContinue
[Array] $GitHubReleases = (Get-GitHubLatestRelease -Url "https://api.github.com/repos/evotecit/GpoZaurr/releases" -Verbose:$false)
$LatestVersion = $GitHubReleases[0]
if (-not $LatestVersion.Errors) {
if ($GPOZaurrVersion.Version -eq $LatestVersion.Version) {
$Script:Reporting['Version'] = "GPOZaurr Current/Latest: $($LatestVersion.Version) at $($LatestVersion.PublishDate)"
} elseif ($GPOZaurrVersion.Version -lt $LatestVersion.Version) {
$Script:Reporting['Version'] = "GPOZaurr Current: $($GPOZaurrVersion.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Update?"
} elseif ($GPOZaurrVersion.Version -gt $LatestVersion.Version) {
$Script:Reporting['Version'] = "GPOZaurr Current: $($GPOZaurrVersion.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Lucky you!"
}
} else {
$Script:Reporting['Version'] = "GPOZaurr Current: $($GPOZaurrVersion.Version)"
}
# Gather data
$TimeLog = Start-TimeLog
if ($Type -contains 'GPOList' -or $null -eq $Type) {
$TimeLogGPOList = Start-TimeLog
Write-Verbose -Message "Show-GPOZaurr - Processing GPO List"
$GPOSummary = Get-GPOZaurr
$GPOLinkedStatus = $GPOSummary.Where( { $_.Linked -eq $true }, 'split')
[Array] $GPONotLinked = $GPOLinkedStatus[1]
[Array] $GPOLinked = $GPOLinkedStatus[0]
$GPOEmptyStatus = $GPOSummary.Where( { $_.Empty -eq $true }, 'split' )
[Array] $GPOEmpty = $GPOEmptyStatus[0]
[Array] $GPONotEmpty = $GPOEmptyStatus[1]
$GPOTotal = $GPOSummary.Count
$TimeEndGPOList = Stop-TimeLog -Time $TimeLog -Option OneLiner
}
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
#Write-Color -Text "[Info] ", "Processing GPOOrphans" -Color Yellow, White
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Sysvol"
$GPOOrphans = Get-GPOZaurrBroken
$NotAvailableInAD = [System.Collections.Generic.List[PSCustomObject]]::new()
$NotAvailableOnSysvol = [System.Collections.Generic.List[PSCustomObject]]::new()
$NotAvailablePermissionIssue = [System.Collections.Generic.List[PSCustomObject]]::new()
foreach ($_ in $GPOOrphans) {
if ($_.Status -eq 'Not available in AD') {
$NotAvailableInAD.Add($NotAvailableInAD)
} elseif ($_.Status -eq 'Not available on SYSVOL') {
$NotAvailableOnSysvol.Add($NotAvailableInAD)
} elseif ( $_.Status -eq 'Permissions issue') {
$NotAvailablePermissionIssue.Add($NotAvailableInAD)
}
}
}
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
#Write-Color -Text "[Info] ", "Processing GPOPermissions" -Color Yellow, White
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions"
$GPOPermissions = Get-GPOZaurrPermission -Type All -IncludePermissionType GpoEditDeleteModifySecurity, GpoEdit, GpoCustom -IncludeOwner
}
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Consistency"
$GPOPermissionsConsistency = Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance
[Array] $Inconsistent = $GPOPermissionsConsistency.Where( { $_.ACLConsistent -eq $true } , 'split' )
[Array] $InconsistentInside = $GPOPermissionsConsistency.Where( { $_.ACLConsistentInside -eq $true }, 'split' )
}
if ($Type -contains 'GPOPermissionsRoot' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Root"
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot
}
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
Write-Verbose "Show-GPOZaurr - Processing GPO Owners"
$GPOOwners = Get-GPOZaurrOwner -IncludeSysvol
$IsOwnerConsistent = $GPOOwners.Where( { $_.IsOwnerConsistent -eq $true } , 'split' )
$IsOwnerAdministrative = $GPOOwners.Where( { $_.IsOwnerAdministrative -eq $true } , 'split' )
}
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
Write-Verbose "Get-GPOZaurrNetLogon - Processing NETLOGON Share"
$Netlogon = Get-GPOZaurrNetLogon
}
if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
Write-Verbose "Show-GPOZaurr - Processing GPO Analysis"
$GPOContent = Invoke-GPOZaurr
}
if ($Type -contains 'GPOFiles') {
Write-Verbose "Show-GPOZaurr - Processing GPOFiles"
$GPOFiles = Get-GPOZaurrFiles
}
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
# Generate pretty HTML
Write-Verbose "Show-GPOZaurr - Generating HTML"
New-HTML {
New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
New-HTMLPanelStyle -BorderRadius 0px
New-HTMLTableOption -DataStore JavaScript -BoolAsString
New-HTMLHeader {
New-HTMLSection -Invisible {
New-HTMLSection {
New-HTMLText -Text "Report generated on $(Get-Date)" -Color Blue
} -JustifyContent flex-start -Invisible
New-HTMLSection {
New-HTMLText -Text $Script:Reporting['Version'] -Color Blue
} -JustifyContent flex-end -Invisible
}
}
New-HTMLTab -Name 'Overview' {
if ($Type -contains 'GPOConsistency' -or $Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLSection -Invisible {
if ($Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLPanel {
New-HTMLText -Text 'Following chart presents ', 'Linked / Empty and Unlinked Group Policies' -FontSize 10pt -FontWeight normal, bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies total: ', $GPOTotal -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies linked: ', $GPOLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPONotLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOEmpty.Count -FontWeight normal, bold
} -FontSize 10pt
New-HTMLText -FontSize 10pt -Text 'Usually empty or unlinked Group Policies are safe to delete.'
New-HTMLChart -Title 'Group Policies Summary' {
New-ChartBarOptions -Type barStacked
#New-ChartLegend -Names 'Unlinked', 'Linked', 'Empty', 'Total' -Color Salmon, PaleGreen, PaleVioletRed, PaleTurquoise
New-ChartLegend -Names 'Bad', 'Good' -Color PaleGreen, Salmon
#New-ChartBar -Name 'Group Policies' -Value $GPONotLinked.Count, $GPOLinked.Count, $GPOEmpty.Count, $GPOTotal
New-ChartBar -Name 'Linked' -Value $GPOLinked.Count, $GPONotLinked.Count
New-ChartBar -Name 'Empty' -Value $GPONotEmpty.Count, $GPOEmpty.Count
} -TitleAlignment center
}
}
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
New-HTMLPanel {
New-HTMLText -Text 'Following chart presents ', 'permissions consistency between Active Directory and SYSVOL for Group Policies' -FontSize 10pt -FontWeight normal, bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Top level permissions consistency: ', $Inconsistent[0].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Inherited permissions consistency: ', $InconsistentInside[0].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $Inconsistent[1].Count -FontWeight normal, bold
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $InconsistentInside[1].Count -FontWeight normal, bold
} -FontSize 10pt
New-HTMLText -FontSize 10pt -Text 'Having incosistent permissions on AD in comparison to those on SYSVOL can lead to uncontrolled ability to modify them.'
New-HTMLChart {
New-ChartLegend -Names 'Bad', 'Good' -Color PaleGreen, Salmon
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Consistent', 'Inconsistent'
New-ChartBar -Name 'TopLevel' -Value $Inconsistent[0].Count, $Inconsistent[1].Count
New-ChartBar -Name 'Inherited' -Value $InconsistentInside[0].Count, $InconsistentInside[1].Count
} -Title 'Permissions Consistency' -TitleAlignment center
}
}
}
}
if ($Type -contains 'GPOOwners' -or $Type -contains 'GPOOrphans' -or $null -eq $Type) {
New-HTMLSection -Invisible {
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLPanel {
New-HTMLText -Text 'Following chart presents Group Policy owners and whether they are administrative and consistent. By design an owner of Group Policy should be Domain Admins or Enterprise Admins group only to prevent malicious takeover. ', `
"It's also important that owner in Active Directory matches owner on SYSVOL (file system)."
New-HTMLChart {
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Yes', 'No' -Color PaleGreen, Orchid
New-ChartBar -Name 'Is administrative' -Value $IsOwnerAdministrative[0].Count, $IsOwnerAdministrative[1].Count
New-ChartBar -Name 'Is consistent' -Value $IsOwnerConsistent[0].Count, $IsOwnerConsistent[1].Count
} -Title 'Group Policy Owners'
}
}
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
New-HTMLPanel {
New-HTMLText -Text 'Following chart presents ', 'Broken / Orphaned Group Policies' -FontSize 10pt -FontWeight normal, bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies on SYSVOL, but no details in AD: ', $NotAvailableInAD.Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $NotAvailableOnSysvol.Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $NotAvailablePermissionIssue.Count -FontWeight normal, bold
} -FontSize 10pt
New-HTMLText -FontSize 10pt -Text 'Those problems must be resolved before doing other clenaup activities.'
New-HTMLChart {
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Not in AD', 'Not on SYSVOL', 'Permissions Issue' -Color Crimson, LightCoral, IndianRed
New-ChartBar -Name 'Orphans' -Value $NotAvailableInAD.Count, $NotAvailableOnSysvol.Count, $NotAvailablePermissionIssue.Count
} -Title 'Broken / Orphaned Group Policies' -TitleAlignment center
}
}
}
}
}
if ($Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLTab -Name 'Group Policies Summary' {
New-HTMLPanel {
New-HTMLText -Text 'Following table shows a list of group policies. ', 'By using following table you can easily find which GPOs can be safely deleted because those are empty or unlinked.' -FontSize 10pt -FontWeight normal, bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies total: ', $GPOTotal -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies linked: ', $GPOLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPONotLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOEmpty.Count -FontWeight normal, bold
} -FontSize 10pt
}
New-HTMLSection -Name 'Group Policies List' {
New-HTMLTable -DataTable $GPOSummary -Filtering {
New-HTMLTableCondition -Name 'Empty' -Value $true -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
New-HTMLTableCondition -Name 'Linked' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
} -PagingOptions 10, 20, 30, 40, 50
}
New-HTMLSection -Name 'Steps to fix - Empty & Unlinked Group Policies' {
New-HTMLContainer {
New-HTMLSpanStyle -FontSize 10pt {
New-HTMLText -Text 'Following steps will guide you how to remove empty or unlinked group policies'
New-HTMLWizard {
New-HTMLWizardStep {
}
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
}
}
}
}
}
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
New-HTMLTab -Name 'Health State' {
New-HTMLPanel {
New-HTMLText -TextBlock {
"Following table shows list of all group policies and their status in AD and SYSVOL. Due to different reasons it's "
"possible that "
} -FontSize 10pt
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies on SYSVOL, but no details in AD: ', $NotAvailableInAD.Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $NotAvailableOnSysvol.Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $NotAvailablePermissionIssue.Count -FontWeight normal, bold
} -FontSize 10pt
New-HTMLText -Text "Follow the steps below table to get Active Directory Group Policies in healthy state." -FontSize 10pt
}
New-HTMLSection -Name 'Health State of Group Policies' {
New-HTMLTable -DataTable $GPOOrphans -Filtering {
New-HTMLTableCondition -Name 'Status' -Value "Not available in AD" -BackgroundColor Salmon -ComparisonType string
New-HTMLTableCondition -Name 'Status' -Value "Not available on SYSVOL" -BackgroundColor LightCoral -ComparisonType string
New-HTMLTableCondition -Name 'Status' -Value "Permissions issue" -BackgroundColor MediumVioletRed -ComparisonType string -Color White
} -PagingOptions 10, 20, 30, 40, 50
}
New-HTMLSection -Name 'Steps to fix - Not available on SYSVOL / Active Directory' {
New-HTMLContainer {
New-HTMLSpanStyle -FontSize 10pt {
New-HTMLText -Text 'Following steps will guide you how to fix GPOs which are not available on SYSVOL or AD.'
New-HTMLWizard {
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 {
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrBrokenGpoBefore.html -Verbose -Type GPOOrphans
}
New-HTMLText -Text {
"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 {
$GPOOutput = Get-GPOZaurrBroken
$GPOOutput | 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 'Fix GPOs not available on SYSVOL' {
New-HTMLText -Text "Following command when executed runs cleanup procedure that removes all broken GPOs on SYSVOL side."
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 {
Remove-GPOZaurrBroken -Type SYSVOL -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 deleted matches expected data. Once happy with results please follow with command: "
}
New-HTMLCodeBlock -Code {
Remove-GPOZaurrBroken -Type SYSVOL -LimitProcessing 2 -BackupPath $Env:UserProfile\Desktop\GPOSYSVOLBackup
}
New-HTMLText -TextBlock {
"This command when executed deletes only first X broken GPOs. Use LimitProcessing parameter to prevent mass delete 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-HTMLText -Text "If there's nothing else to be deleted on SYSVOL side, we can skip to next step step"
}
New-HTMLWizardStep -Name 'Fix GPOs not available on AD' {
New-HTMLText -Text "Following command when executed runs cleanup procedure that removes all broken GPOs on Active Directory side."
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 {
Remove-GPOZaurrBroken -Type AD -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 deleted matches expected data. Once happy with results please follow with command: "
}
New-HTMLCodeBlock -Code {
Remove-GPOZaurrBroken -Type AD -LimitProcessing 2 -BackupPath $Env:UserProfile\Desktop\GPOSYSVOLBackup
}
New-HTMLText -TextBlock {
"This command when executed deletes only first X broken GPOs. Use LimitProcessing parameter to prevent mass delete 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-HTMLText -Text "If there's nothing else to be deleted on AD side, we can skip to next step step"
}
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 {
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrBrokenGpoAfter.html -Verbose -Type GPOOrphans
}
New-HTMLText -Text "If everything is health in the report you're done! Enjoy rest of the day!" -Color BlueDiamond
}
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
}
}
}
}
}
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
New-HTMLTab -Name 'NetLogon' {
New-HTMLTable -DataTable $Netlogon -Filtering
}
}
if ($Type -contains 'GPOPermissionsRoot' -or $Type -contains 'GPOOwners' -or
$Type -contains 'GPOPermissions' -or $Type -contains 'GPOConsistency' -or
$null -eq $Type
) {
New-HTMLTab -Name 'Permissions' {
if ($Type -contains 'GPOPermissionsRoot' -or $null -eq $Type) {
New-HTMLTab -Name 'Root' {
New-HTMLTable -DataTable $GPOPermissionsRoot -Filtering
}
}
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLTab -Name 'Owners' {
New-HTMLTable -DataTable $GPOOwners -Filtering
}
}
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
New-HTMLTab -Name 'Edit & Modify' {
New-HTMLTable -DataTable $GPOPermissions -Filtering
}
}
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
New-HTMLTab -Name 'Permissions Consistency' {
New-HTMLPanel {
New-HTMLText -Text 'Following table presents ', 'permissions consistency between Active Directory and SYSVOL for Group Policies' -FontSize 10pt -FontWeight normal, bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Top level permissions consistency: ', $Inconsistent[0].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Inherited permissions consistency: ', $InconsistentInside[0].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $Inconsistent[1].Count -FontWeight normal, bold
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $InconsistentInside[1].Count -FontWeight normal, bold
} -FontSize 10pt
New-HTMLText -FontSize 10pt -Text 'Having incosistent permissions on AD in comparison to those on SYSVOL can lead to uncontrolled ability to modify them. Please notice that if ', `
' Not available ', 'is visible in the table you should first fix related, more pressing issue, before fixing permissions inconsistency.' -FontWeight normal, bold, normal
}
New-HTMLSection -Name 'Group Policy Permissions Consistency' {
New-HTMLTable -DataTable $GPOPermissionsConsistency -Filtering {
New-HTMLTableCondition -Name 'ACLConsistent' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
New-HTMLTableCondition -Name 'ACLConsistent' -Value $true -BackgroundColor PaleGreen -TextTransform capitalize -ComparisonType string
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value $true -BackgroundColor PaleGreen -TextTransform capitalize -ComparisonType string
New-HTMLTableCondition -Name 'ACLConsistent' -Value 'Not available' -BackgroundColor Crimson -ComparisonType string
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value 'Not available' -BackgroundColor Crimson -ComparisonType string
} -PagingOptions 10, 20, 30, 40, 50
}
New-HTMLSection -Name 'Steps to fix - Permissions Consistency' {
New-HTMLContainer {
New-HTMLSpanStyle -FontSize 10pt {
New-HTMLText -Text 'Following steps will guide you how to fix permissions consistency'
New-HTMLWizard {
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 fixing permissions inconsistencies. To generate new report please use:"
New-HTMLCodeBlock -Code {
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrPermissionsInconsistentBefore.html -Verbose -Type GPOConsistency
}
New-HTMLText -Text {
"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 {
$GPOOutput = Get-GPOZaurrPermissionConsistency
$GPOOutput | Format-Table # do your actions as desired
}
New-HTMLText -Text "It provides same data as you see in table above just doesn't prettify it for you."
}
New-HTMLWizardStep -Name 'Fix inconsistent permissions' {
New-HTMLText -Text "Following command when executed fixes inconsistent permissions."
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-HTMLText -Text "Make sure to fill in TargetDomain to match your Domain Admin permission account"
New-HTMLCodeBlock -Code {
Repair-GPOZaurrPermissionConsistency -IncludeDomains "TargetDomain" -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 deleted matches expected data. Once happy with results please follow with command: "
}
New-HTMLCodeBlock -Code {
Repair-GPOZaurrPermissionConsistency -LimitProcessing 2 -IncludeDomains "TargetDomain"
}
New-HTMLText -TextBlock {
"This command when executed repairs only first X inconsistent permissions. Use LimitProcessing parameter to prevent mass fixing 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-HTMLText -Text "If there's nothing else to be fixed, we can skip to next step step"
}
New-HTMLWizardStep -Name 'Fix inconsistent downlevel permissions' {
New-HTMLText -Text "Unfortunetly this step is manual until automation is developed. "
New-HTMLText -Text "If there are inconsistent permissions found inside GPO one has to fix them manually by going into SYSVOL and making sure inheritance is enabled, and that permissions are consistent across all files."
}
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 {
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrPermissionsInconsistentAfter.html -Verbose -Type GPOConsistency
}
New-HTMLText -Text "If everything is health in the report you're done! Enjoy rest of the day!" -Color BlueDiamond
}
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
}
}
}
}
}
}
}
if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
New-HTMLTab -Name 'Analysis' {
foreach ($Key in $GPOContent.Keys) {
New-HTMLTab -Name $Key {
New-HTMLTable -DataTable $GPOContent[$Key] -Filtering -Title $Key
}
}
}
}
} -Online -ShowHTML -FilePath $FilePath
}
+48 -1
View File
@@ -49,11 +49,58 @@ That's it. Whenever there's a new version, you run the command, and you can enjo
## Changelog
- 0.0.52 - Unreleased
- 0.0.66 - 22.10.2020
- Improved `Show-GPOZaurr` (WIP)
- 0.0.65 - 22.10.2020
- Improved `Show-GPOZaurr` (WIP)
- 0.0.64 - 21.10.2020
- Renamed `Remove-GPOZaurrOrphaned` to `Remove-GPOZaurrBroken` keeping it as an alias
- Renamed `Get-GPOZaurrSysvol` to `Get-GPOZaurrBroken` keeping it as an alias
- Improved `Show-GPOZaurr` (WIP)
- 0.0.63 - 19.10.2020
- Renamed `Invoke-GPOZaurrContent` back to `Invoke-GPOZaurr`
- Added `Show-GPOZaurr` (WIP)
- Added `OutputType`,`OutputType`,`Open`,`Online` parameters to `Invoke-GPOZaurr`
- Added `Get-GPOZaurrNetLogon`
- Improved `Get-GPOZaurrOwner`
- Fixes `Get-GPOZaurrSysvol`
- 0.0.62 - 14.10.2020
- Renamed `Invoke-GPOZaurr` to `Invoke-GPOZaurrContent` - I want to use `Invoke-GPOZaurr` for something else
- Improvements to `Get-GPOZaurrPermissionConsistency` for GPOs without SYSVOL to be reported properly
- Added `Get-GPOZaurrPermissionRoot`
- Renamed `Remove-GPOZaurrOrphanedSysvolFolders` to `Remove-GPOZaurrOrphaned`
- Improved `Remove-GPOZaurrOrphaned` to deal with orphaned folders but also orphaned AD GPO (No sysvol data)
- Improved `Get-GPOZaurrSysVol` to detect orphaned SYSVOL or AD GPO objects
- Improved `Get-GPOZaurrSysVol` to detect permissions issue when reading AD GPO objects
- Added `Get-GPOZaurrPermissionRoot` to show which users/groups have control over all GPOs (allowed to create/modify)
- Improved `Get-GPOZaurrPermissionSummary` to include `Get-GPOZaurrPermissionRoot` custom permissions
- Updated `Remove-GPOZaurrPermission`
- Updated `Get-GpoZaurrPermission`
- Updated `Get-GPOZaurrFiles` to better handle access issue
- Reversed parameters `Get-GPOZaurrFiles` from `Limited` to `ExtendedMetaData` and fixed missing columns
- 0.0.61 - 31.08.2020
- Improvement to `Get-GPOZaurrPermissionSummary`
- Fixes to `ConvertFrom-CSExtension`
- Fixes to `Find-CSExtension`
- 0.0.59 - 26.08.2020
- Improvement to `Get-GPOZaurrPermissionSummary`
- 0.0.58 - 26.08.2020
- Improvement to `Get-GPOZaurrPermissionSummary`
- 0.0.57 - 26.08.2020
- Improvement to `Get-GPOZaurrPermissionSummary`
- 0.0.56 - 26.08.2020
- Added `Get-GPOZaurrPermissionSummary`
- 0.0.55 - 17.08.2020
- Improved `Get-GPOZaurrInheritance`
- 0.0.54 - 16.08.2020
- Added `Invoke-GPOZaurrSupport` (WIP)
- Added `ConvertFrom-CSExtension`
- Added `Find-CSExtension`
- Added `Get-GPOZaurrInheritance`
- 0.0.53 - 16.08.2020
- Bad release
- 0.0.52 - 16.08.2020
- Bad release
- 0.0.51 - 2.08.2020
- Updates to `Invoke-GPOZaurr` - still work in progress
- Added `Get-GPOZaurrSysvolDFSR`