Compare commits

...

47 Commits

Author SHA1 Message Date
Przemyslaw Klys 4acf509e2b Update 2020-05-26 19:16:32 +02:00
Przemyslaw Klys 4c0647b81f Remove Orphaned Sysvol Folders 2020-05-26 19:03:21 +02:00
Przemyslaw Klys 7415386a13 Update WMI filter 2020-05-26 18:32:06 +02:00
Przemyslaw Klys db7838fc18 Update SYSVOL/WMI 2020-05-26 18:31:57 +02:00
Przemyslaw Klys 19e6d514a1 Update psd1 2020-05-25 18:34:10 +02:00
Przemyslaw Klys 3375c10ee7 Update 2020-05-25 18:33:49 +02:00
Przemyslaw Klys ca030b5fee Improved function 2020-05-25 18:03:44 +02:00
Przemyslaw Klys 30660a9097 Update PSD1 2020-05-25 14:42:16 +02:00
Przemyslaw Klys 3e9848e705 Updates to functions 2020-05-25 14:40:59 +02:00
Przemyslaw Klys e04f5514f8 Cleanup dead code 2020-05-15 13:31:13 +02:00
Przemyslaw Klys 02dbe6c02c Small cleanup 2020-05-15 12:18:46 +02:00
Przemyslaw Klys 5959f31607 PSD1 update 2020-05-15 11:20:42 +02:00
Przemyslaw Klys 971f5a18e3 Update GPOZaurrAD 2020-05-15 11:20:03 +02:00
Przemyslaw Klys 6e81f6f80f More work 2020-05-14 22:27:48 +02:00
Przemyslaw Klys 6c607b28f3 Update PSD1 2020-05-14 17:43:12 +02:00
Przemyslaw Klys 288306228c Update 2020-05-14 17:28:14 +02:00
Przemyslaw Klys fb2285437a Update psd1 2020-05-14 13:42:16 +02:00
Przemyslaw Klys 3ff20afe30 Updated examples 2020-05-14 13:26:27 +02:00
Przemyslaw Klys ff6ad6735d Upgraded check for consistency of permissions 2020-05-14 13:26:16 +02:00
Przemyslaw Klys fe97c15741 Update small formatting 2020-05-14 13:21:15 +02:00
Przemyslaw Klys 66b60fdbfa PSD1 2020-05-14 00:12:11 +02:00
Przemyslaw Klys ba9f741a8d Repair inconsistency ACL 2020-05-14 00:11:32 +02:00
Przemyslaw Klys fc2ab5de2f Update to example 2020-05-13 22:59:48 +02:00
Przemyslaw Klys 131b92b2a1 PSD1 update 2020-05-13 22:59:40 +02:00
Przemyslaw Klys 3a4bf7ab56 Update Get-GPOZaurrOwner 2020-05-13 22:59:35 +02:00
Przemyslaw Klys 106a10d37b Updates to Get-GPOZaurrOwner to support Sysvol 2020-05-13 21:04:59 +02:00
Przemyslaw Klys b22d6ada7f Small formatting issues 2020-05-13 21:04:40 +02:00
Przemyslaw Klys cad485cd20 small formatting issues 2020-05-13 21:04:32 +02:00
Przemyslaw Klys c1f293e6f1 Work in progress for Owner 2020-05-12 17:04:05 +02:00
Przemyslaw Klys 0f9ed02a04 Updates to Remove-Permissions 2020-05-11 14:38:27 +02:00
Przemyslaw Klys 9f7bdd287e Update examples 2020-05-11 14:00:11 +02:00
Przemyslaw Klys 5ac5b7f0a1 Update PSD1 2020-05-11 11:50:15 +02:00
Przemyslaw Klys b915216eb4 New function Get-GPOZaurrOwner 2020-05-11 11:50:03 +02:00
Przemyslaw Klys 104aa43fd1 Another way to get GPOs via ADObject 2020-05-11 11:09:54 +02:00
Przemyslaw Klys 3691076d00 Get-GPOZaurrConsistency 2020-05-11 11:09:29 +02:00
Przemyslaw Klys c879c48b32 Update to Get-GPOZaurrPermission 2020-05-11 11:08:55 +02:00
Przemyslaw Klys 2c92e3f56e Update to remove permissions 2020-05-11 11:08:19 +02:00
Przemyslaw Klys c8ee43ee49 Update to Remove-PrivPermission 2020-05-11 11:08:03 +02:00
Przemysław Kłys a3e79a90e6 Update to PermissionType 2020-05-06 11:55:31 +02:00
Przemysław Kłys 63479e7075 Version change 2020-05-06 11:55:09 +02:00
Przemysław Kłys 9471ca3435 Typo 2020-05-06 11:55:01 +02:00
Przemysław Kłys 9ada311bb1 Small update 2020-05-05 19:28:49 +02:00
Przemysław Kłys efd4ee1bba Moved to PSSharedGoods 2020-05-05 19:28:33 +02:00
Przemysław Kłys 32b59ccc7f Added sponsorship 2020-05-02 19:00:22 +02:00
Przemysław Kłys 1499b2166d Update 2020-04-28 22:31:45 +02:00
Przemysław Kłys 9675324b07 Fixes for duplicate guids 2020-04-27 21:11:37 +02:00
Przemysław Kłys f518548880 This is disaster 2020-04-26 19:43:02 +02:00
53 changed files with 1793 additions and 593 deletions
+7
View File
@@ -0,0 +1,7 @@
# These are supported funding model platforms
github: PrzemyslawKlys
patreon: przemyslawklys
ko_fi: przemyslawklys
open_collective: evotec
custom: https://paypal.me/PrzemyslawKlys
+1 -1
View File
@@ -182,7 +182,7 @@ Accept wildcard characters: False
Type: String[]
Parameter Sets: Type
Aliases:
Accepted values: EmptyOrUnknown, NonAdministrative
Accepted values: EmptyOrUnknown, NotAdministrative
Required: True
Position: Named
+1 -1
View File
@@ -1,6 +1,6 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$RestoreFrom = 'C:\Users\przemyslaw.klys\Desktop\GPO\2020-04-20_15_51_00'
$RestoreFrom = 'C:\Users\przemyslaw.klys\Desktop\GPO\2020-04-26_10_29_34'
$BackupInformation = Get-GPOZaurrBackupInformation -BackupFolder $RestoreFrom
$BackupInformation | Format-Table -a
@@ -0,0 +1,3 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrWMI -Name 'Test - Dual Filter' | Format-Table -AutoSize *
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$T = Get-GPOZaurrPermission -GPOName 'Default Domain Policy' -Type 'All'
$T | Format-Table *
@@ -1,4 +1,12 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$T = Get-GPOZaurrPermission -GPOName 'ALL | Enable RDP' #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T = Get-GPOZaurrPermission -GPOName 'Default DOmain Policy' #-Principal 'marikegerard' -PrincipalType Name # #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
$T = Get-GPOZaurrPermission -GPOName 'Default DOmain Policy' -Principal 'marikegerard' -PrincipalType Name # #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
$T = Get-GPOZaurrPermission -GPOName 'Default DOmain Policy' -Principal 'EVOTEC\marikegerard' -PrincipalType Name # #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
$T = Get-GPOZaurrPermission -GPOName 'Default DOmain Policy' -Principal 'S-1-5-18' -PrincipalType Sid # #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
$T = Get-GPOZaurrPermission -GPOName 'Default DOmain Policy' -Principal 'CN=Enterprise Admins,CN=Users,DC=ad,DC=evotec,DC=xyz' -PrincipalType DistinguishedName # #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$T = Get-GPOZaurrPermission -Type Unknown -Verbose
$T | Format-Table *
@@ -1,3 +1,3 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Remove-GPOZaurrPermission -Verbose -Type Unknown -WhatIf
#Clear-Host
Remove-GPOZaurrPermission -Verbose -Type Unknown -LimitProcessing 1 #-WhatIf
@@ -0,0 +1,19 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
# Step 1 - Create report
$Report = Get-GPOZaurrPermission -Type All
$Report | ConvertTo-Excel -FilePath $Env:UserProfile\Desktop\GPOOutput.xlsx -ExcelWorkSheetName 'GPO Permissions Before' -AutoFilter -AutoFit
# Step 2 - Verify couple of GPOS returned with whatif
#Remove-GPOZaurrPermission -Verbose -Type Unknown -LimitProcessing 4 -WhatIf
# Step 3 - Confirm the change without whatif
#Remove-GPOZaurrPermission -Verbose -Type Unknown -LimitProcessing 4
# Step 4 - Analyze GPO manually to confirm only unknown sids were removed
# Step 5 - if everything went ok, continue process without whatif
# Step-6 - Generate new report
#$Report = Get-GPOZaurrPermission -Type All
#$Report | ConvertTo-Excel -FilePath $Env:UserProfile\Desktop\GPOOutput.xlsx -ExcelWorkSheetName 'GPO Permissions After' -AutoFilter -AutoFit
@@ -1,13 +1,6 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$Named = @(
'S-1-5-21-853615985-2870445339-3163598659-1105'
)
$T = Get-GPOZaurrPermission -GPOName 'Default DOmain Policy'
$T | Format-Table -AutoSize *
# Using exclude permission types (it may not be good idea to delete GPORead/GPOApply)
#Remove-GPOZaurrPermission -Verbose -Type Named -WhatIf -LimitProcessing 2 -NamedObjects $Named -ExcludePermissionType GpoRead,GpoApply
# But
#Remove-GPOZaurrPermission -Type Named -NamedObjects $Named -IncludePermissionType GpoEditDeleteModifySecurity -SkipWellKnown -SkipAdministrative -Verbose -WhatIf
Remove-GPOZaurrPermission -Type Named -NamedObjects $Named -SkipWellKnown -SkipAdministrative -Verbose #-WhatIf
Remove-GPOZaurrPermission -GPOName 'Default DOmain Policy' -Principal 'S-1-5-21-853615985-2870445339-3163598659-3755' -Verbose #-WhatIf #-IncludePermissionType GpoApply #-WhatIf
+6
View File
@@ -0,0 +1,6 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrAD | Format-Table
Get-GPOZaurrAD -Forest 'test.evotec.pl' | Format-Table
Get-GPOZaurrAD -GPOName 'Default Domain Policy' -IncludeDomains 'ad.evotec.pl' | Format-Table
+4
View File
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$GPOS = Get-GPOZaurr
$GPOS | Format-Table -AutoSize
@@ -1,13 +1,17 @@
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
# And also can fix at the same time NonAdministrative - this basically looks for users/groups that are not Domain Admins or Enterprise Admins
# 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-GPOZaurr #-GPOName 'New Group Policy Object'
$GPOs | Format-Table DisplayName, Owner, OwnerSID, OwnerType
$GPOs = Get-GPOZaurrOwner -IncludeSysvol #-GPOName
$GPOs | Format-Table DisplayName, Owner, OwnerSID, OwnerType, SysvolOwner, SysvolSID, SysvolType
Set-GPOZaurrOwner -Type 'EmptyOrUnknown' -Verbose -LimitProcessing 1 -WhatIf
#Set-GPOZaurrOwner -Type Unknown -Verbose #-LimitProcessing 2 -WhatIf
Set-GPOZaurrOwner -Type NotAdministrative -Verbose -LimitProcessing 2 -WhatIf
#Set-GPOZaurrOwner -Type NotMatching -Verbose -LimitProcessing 2 -WhatIf
$GPOs = Get-GPOZaurr #-GPOName 'New Group Policy Object'
$GPOs | Format-Table DisplayName, Owner, OwnerSID
#Set-GPOZaurrOwner -GPOName 'COMPUTERS | Enable Sets' -Verbose -Principal 'przemyslaw.klys' -WhatIf #-SkipSysvol
#Set-GPOZaurrOwner -GPOName 'New Group Policy Object' -Verbose #-WhatIf #-SkipSysvol
#$GPOs = Get-GPOZaurrOwner -IncludeSysvol #-GPOName 'New Group Policy Object'
#$GPOs | Format-Table DisplayName, Owner, OwnerSID
+12
View File
@@ -0,0 +1,12 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
# Step 1 - Create report
$Report = Get-GPOZaurrOwner -IncludeSysvol
$Report | ConvertTo-Excel -FilePath $Env:UserProfile\Desktop\GPOOwners.xlsx -ExcelWorkSheetName 'GPO Owners Before' -AutoFilter -AutoFit
# Step 2 - Fix owners / use WhatIf and LimitProcessing / verify changes before/after
Set-GPOZaurrOwner -Type NotAdministrative -Verbose -LimitProcessing 2 -WhatIf
# Step 3
$Report = Get-GPOZaurrOwner -IncludeSysvol
$Report | ConvertTo-Excel -FilePath $Env:UserProfile\Desktop\GPOOwners.xlsx -ExcelWorkSheetName 'GPO Owners After' -AutoFilter -AutoFit
+11
View File
@@ -0,0 +1,11 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$T = Get-GPOZaurrOwner -Verbose -IncludeSysvol
$T | Format-Table *
#$T | Out-HtmlView -ScrollX
$T = Get-GPOZaurrOwner -Verbose -IncludeSysvol -GPOName 'Default Domain Policy'
$T | Format-Table *
$T = Get-GPOZaurrOwner -Verbose -IncludeSysvol -GPOGuid '4E1F9C70-1DDB-4AB6-BBA3-14A8E07F0B4B'
$T | Format-Table *
+1 -1
View File
@@ -1,3 +1,3 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrLink | Format-Table -AutoSize
Get-GPOZaurrLink | Format-Table -AutoSize *
@@ -0,0 +1,11 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Clear-Host
Get-GPOZaurrLink -Linked Root | Format-Table -AutoSize
Get-GPOZaurrLink -Linked Site | Format-Table -AutoSize
Get-GPOZaurrLink -Linked DomainControllers | Format-Table -AutoSize
Get-GPOZaurrLink -Linked Other | Format-Table -AutoSize
@@ -5,13 +5,13 @@ Clear-Host
$T = Get-GPOZaurrPermission -GPOName 'ALL | Enable RDP' #-IncludeGPOObject #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
Add-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoApply -Principal 'przemyslaw.klys' -Verbose
Add-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoEdit -Principal 'przemyslaw.klys' -Verbose
$T = Get-GPOZaurrPermission -GPOName 'ALL | Enable RDP' #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
Add-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoEditDeleteModifySecurity -Principal 'Domain Admins' -Verbose
Remove-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoApply -Principal 'przemyslaw.klys' -PrincipalType Name -Verbose
Remove-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoEdit -Principal 'przemyslaw.klys' -PrincipalType Name -Verbose
$T = Get-GPOZaurrPermission -GPOName 'ALL | Enable RDP' #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject
$T | Format-Table -AutoSize *
@@ -0,0 +1,20 @@
#Clear-Host
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
$ApprovedGroups = @(
'GDS-TestGroup10'
)
$RootGroups = @(
#'przemyslaw.klys'
)
Invoke-GPOZaurrPermission -Linked Root -Verbose {
Set-GPOOwner -Type Administrative
#Set-GPOOwner -Principal 'EVOTEC\Enterprise Admins'
#Set-GPOOwner -Principal 'Domain Admins'
Remove-GPOPermission -Type Administrative -IncludePermissionType GPOCustom
Remove-GPOPermission -Type NotAdministrative, NotWellKnownAdministrative -IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity
Add-GPOPermission -Type Administrative -IncludePermissionType GpoEditDeleteModifySecurity
#Add-GPOPermission -Type WellKnownAdministrative -IncludePermissionType GpoEditDeleteModifySecurity
} #-WhatIf #| Format-Table *
@@ -0,0 +1,11 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Invoke-GPOZaurrPermission -Verbose -SearchBase 'OU=Computers,OU=Production,DC=ad,DC=evotec,DC=xyz' {
Set-GPOOwner -Type Administrative
#Set-GPOOwner -Principal 'EVOTEC\Enterprise Admins'
#Set-GPOOwner -Principal 'Domain Admins'
#Remove-GPOPermission -Type Administrative -IncludePermissionType GPOCustom
Remove-GPOPermission -Type NotAdministrative, NotWellKnownAdministrative -IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity
#Add-GPOPermission -Type Administrative -IncludePermissionType GpoEditDeleteModifySecurity
#Add-GPOPermission -Type WellKnownAdministrative -IncludePermissionType GpoEditDeleteModifySecurity
} #-WhatIf #| Format-Table *
@@ -0,0 +1,4 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
#Get-GPOZaurrPermissionConsistency -Type All -Forest 'test.evotec.pl' | Format-Table
Get-GPOZaurrPermissionConsistency -Type All | Format-Table
@@ -0,0 +1,5 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
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
@@ -0,0 +1,9 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
#Get-GPOZaurrPermissionConsistency -Type All -Forest 'test.evotec.pl' | Format-Table
$Output = Get-GPOZaurrPermissionConsistency -GPOName 'Default Domain Controllers Policy' -IncludeDomains 'ad.evotec.xyz' -VerifyInheritance
$Output | Format-Table DisplayName, DomainName, ACLConsistent, ACLConsistentInside
$Output.ACLConsistentInsideDetails | Format-Table
$Output = Get-GPOZaurrPermissionConsistency -VerifyInheritance -Type 'All'
$Output | Format-Table
+3
View File
@@ -0,0 +1,3 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrSysvol -Verbose | Format-Table
@@ -0,0 +1,3 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
Get-GPOZaurrSysvol -VerifyDomainControllers -Verbose | Format-Table *
@@ -0,0 +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
# this runs for whole SYSVOL and checks things against GPOS
Remove-GPOZaurrOrphanedSysvolFolders -Verbose -WhatIf
+4 -4
View File
@@ -5,9 +5,9 @@
CompatiblePSEditions = 'Desktop'
Copyright = '(c) 2011 - 2020 Przemyslaw Klys @ Evotec. All rights reserved.'
Description = 'Group Policy Eater'
FunctionsToExport = 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Get-GPOZaurr', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrLink', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrWMI', 'New-GPOZaurrWMI', 'Remove-GPOZaurr', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOZaurrOwner'
FunctionsToExport = 'Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrLink', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrSysvol', 'Get-WMIFilter', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurrPermission', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrOrphanedSysvolFolders', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner'
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
ModuleVersion = '0.0.19'
ModuleVersion = '0.0.31'
PowerShellVersion = '5.1'
PrivateData = @{
PSData = @{
@@ -17,11 +17,11 @@
}
}
RequiredModules = @{
ModuleVersion = '0.0.135'
ModuleVersion = '0.0.143'
ModuleName = 'PSSharedGoods'
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
}, @{
ModuleVersion = '0.0.48'
ModuleVersion = '0.0.57'
ModuleName = 'ADEssentials'
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
}, 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility'
-74
View File
@@ -1,74 +0,0 @@
function Get-ADADministrativeGroups {
<#
.SYNOPSIS
Short description
.DESCRIPTION
Long description
.PARAMETER Type
Parameter description
.PARAMETER Forest
Parameter description
.PARAMETER ExcludeDomains
Parameter description
.PARAMETER IncludeDomains
Parameter description
.PARAMETER ExtendedForestInformation
Parameter description
.EXAMPLE
Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins
Output (Where VALUE is Get-ADGroup output):
Name Value
---- -----
ByNetBIOS {EVOTEC\Domain Admins, EVOTEC\Enterprise Admins, EVOTECPL\Domain Admins}
ad.evotec.xyz {DomainAdmins, EnterpriseAdmins}
ad.evotec.pl {DomainAdmins}
.NOTES
General notes
#>
[cmdletBinding()]
param(
[parameter(Mandatory)][validateSet('DomainAdmins', 'EnterpriseAdmins')][string[]] $Type,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation
)
$ADDictionary = [ordered] @{ }
$ADDictionary['ByNetBIOS'] = [ordered] @{ }
$ADDictionary['BySID'] = [ordered] @{ }
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
foreach ($Domain in $ForestInformation.Domains) {
$ADDictionary[$Domain] = [ordered] @{ }
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
$DomainInformation = Get-ADDomain -Server $QueryServer
if ($Type -contains 'DomainAdmins') {
Get-ADGroup -Filter "SID -eq '$($DomainInformation.DomainSID)-512'" -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
$ADDictionary['ByNetBIOS']["$($DomainInformation.NetBIOSName)\$($_.Name)"] = $_
$ADDictionary[$Domain]['DomainAdmins'] = "$($DomainInformation.NetBIOSName)\$($_.Name)"
$ADDictionary['BySID'][$_.SID.Value] = $_
}
}
if ($Type -contains 'EnterpriseAdmins') {
Get-ADGroup -Filter "SID -eq '$($DomainInformation.DomainSID)-519'" -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
$ADDictionary['ByNetBIOS']["$($DomainInformation.NetBIOSName)\$($_.Name)"] = $_
$ADDictionary[$Domain]['EnterpriseAdmins'] = "$($DomainInformation.NetBIOSName)\$($_.Name)"
$ADDictionary['BySID'][$_.SID.Value] = $_ #"$($DomainInformation.NetBIOSName)\$($_.Name)"
}
}
}
return $ADDictionary
}
#Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins
+22 -18
View File
@@ -6,46 +6,50 @@
[System.Collections.IDictionary] $GPOCache
)
if ($Object.GpLink -and $Object.GpLink.Trim() -ne '') {
$Object.GpLink -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object {
$Object.GpLink -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object -Process {
if ($_) {
$DomainCN = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDomainCN
$Output = [ordered] @{
DistinguishedName = $Object.DistinguishedName
CanonicalName = $Object.CanonicalName
Guid = [Regex]::Match( $_, '(?={)(.*)(?<=})').Value -replace '{' -replace '}'
}
$Search = -join ($DomainCN, $Output['Guid'])
if ($GPOCache -and -not $Limited) {
$Output['Name'] = $GPOCache[$Output['Guid']].DisplayName
$Output['DomainName'] = $GPOCache[$Output['Guid']].DomainName
$Output['Owner'] = $GPOCache[$Output['Guid']].Owner
$Output['GpoStatus'] = $GPOCache[$Output['Guid']].GpoStatus
$Output['Description'] = $GPOCache[$Output['Guid']].Description
$Output['CreationTime'] = $GPOCache[$Output['Guid']].CreationTime
$Output['ModificationTime'] = $GPOCache[$Output['Guid']].ModificationTime
$Output['DisplayName'] = $GPOCache[$Search].DisplayName
$Output['DomainName'] = $GPOCache[$Search].DomainName
$Output['Owner'] = $GPOCache[$Search].Owner
$Output['GpoStatus'] = $GPOCache[$Search].GpoStatus
$Output['Description'] = $GPOCache[$Search].Description
$Output['CreationTime'] = $GPOCache[$Search].CreationTime
$Output['ModificationTime'] = $GPOCache[$Search].ModificationTime
}
$Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDC
$Output['GPOLink'] = $_
$Output['GPODistinguishedName'] = $_
[PSCustomObject] $Output
}
}
} elseif ($Object.LinkedGroupPolicyObjects -and $Object.LinkedGroupPolicyObjects.Trim() -ne '') {
$Object.LinkedGroupPolicyObjects -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object {
$Object.LinkedGroupPolicyObjects -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object -Process {
if ($_) {
$DomainCN = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDomainCN
$Output = [ordered] @{
DistinguishedName = $Object.DistinguishedName
CanonicalName = $Object.CanonicalName
Guid = [Regex]::Match( $_, '(?={)(.*)(?<=})').Value -replace '{' -replace '}'
}
$Search = -join ($DomainCN, $Output['Guid'])
if ($GPOCache -and -not $Limited) {
$Output['Name'] = $GPOCache[$Output['Guid']].DisplayName
$Output['DomainName'] = $GPOCache[$Output['Guid']].DomainName
$Output['Owner'] = $GPOCache[$Output['Guid']].Owner
$Output['GpoStatus'] = $GPOCache[$Output['Guid']].GpoStatus
$Output['Description'] = $GPOCache[$Output['Guid']].Description
$Output['CreationTime'] = $GPOCache[$Output['Guid']].CreationTime
$Output['ModificationTime'] = $GPOCache[$Output['Guid']].ModificationTime
$Output['Name'] = $GPOCache[$Search].DisplayName
$Output['DomainName'] = $GPOCache[$Search].DomainName
$Output['Owner'] = $GPOCache[$Search].Owner
$Output['GpoStatus'] = $GPOCache[$Search].GpoStatus
$Output['Description'] = $GPOCache[$Search].Description
$Output['CreationTime'] = $GPOCache[$Search].CreationTime
$Output['ModificationTime'] = $GPOCache[$Search].ModificationTime
}
$Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDC
$Output['GPOLink'] = $_
$Output['GPODistinguishedName'] = $_
[PSCustomObject] $Output
}
}
+185 -151
View File
@@ -2,6 +2,10 @@
[cmdletBinding()]
param(
[Microsoft.GroupPolicy.Gpo] $GPO,
[string[]] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
[switch] $SkipWellKnown,
[switch] $SkipAdministrative,
[switch] $IncludeOwner,
@@ -9,164 +13,194 @@
[Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType,
[switch] $IncludeGPOObject,
[System.Collections.IDictionary] $ADAdministrativeGroups,
[string[]] $Type,
[validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All', 'Default')][string[]] $Type,
[System.Collections.IDictionary] $Accounts
)
Write-Verbose "Get-GPOZaurrPermission - Processing $($GPO.DisplayName) from $($GPO.DomainName)"
$SecurityRights = $GPO.GetSecurityInfo()
$Index = 0
$SecurityRights | ForEach-Object -Process {
#Get-GPPermissions -Guid $GPO.ID -DomainName $GPO.DomainName -All -Server $QueryServer | ForEach-Object -Process {
$GPOPermission = $_
if ($ExcludePermissionType -contains $GPOPermission.Permission) {
$Index++
return
}
if ($IncludePermissionType) {
if ($IncludePermissionType -notcontains $GPOPermission.Permission) {
$Index++
return
}
}
if ($SkipWellKnown.IsPresent) {
if ($GPOPermission.Trustee.SidType -eq 'WellKnownGroup') {
$Index++
return
}
}
if ($SkipAdministrative.IsPresent) {
$IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value]
if ($IsAdministrative) {
$Index++
return
}
}
if ($Type -contains 'Unknown' -and $Type -notcontains 'All') {
# May need updates if there's more types
if ($GPOPermission.Trustee.SidType -ne 'Unknown') {
$Index++
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
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'
}
} else {
$ReturnObject['UserPrincipalName'] = ''
$ReturnObject['AccountEnabled'] = ''
$ReturnObject['PasswordLastSet'] = ''
$ReturnObject['LastLogonDate'] = ''
}
}
if ($IncludeGPOObject) {
$ReturnObject['GPOObject'] = $GPO
$ReturnObject['GPOSecurity'] = $SecurityRights
$ReturnObject['GPOSecurityPermissionIndex'] = $Index
}
[PSCustomObject] $ReturnObject
$Index++
Begin {
Write-Verbose "Get-PrivPermission - Processing $($GPO.DisplayName) from $($GPO.DomainName)"
}
if ($IncludeOwner.IsPresent) {
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
Process {
$SecurityRights = $GPO.GetSecurityInfo()
$SecurityRights | ForEach-Object -Process {
#Get-GPPermissions -Guid $GPO.ID -DomainName $GPO.DomainName -All -Server $QueryServer | ForEach-Object -Process {
$GPOPermission = $_
if ($ExcludePermissionType -contains $GPOPermission.Permission) {
return
}
if ($IncludePermissionType) {
if ($IncludePermissionType -notcontains $GPOPermission.Permission) {
return
}
}
if ($SkipWellKnown.IsPresent -or $Type -contains 'NotWellKnown') {
if ($GPOPermission.Trustee.SidType -eq 'WellKnownGroup') {
return
}
}
if ($SkipAdministrative.IsPresent -or $Type -contains 'NotAdministrative') {
$IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value]
if ($IsAdministrative) {
return
}
}
if ($Type -contains 'Administrative' -and $Type -notcontains 'All') {
$IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value]
if (-not $IsAdministrative) {
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 ($GPOPermission.Trustee.Sid -eq 'S-1-5-18') {
return
}
}
if ($Type -contains 'Unknown' -and $Type -notcontains 'All') {
# May need updates if there's more types
if ($GPOPermission.Trustee.SidType -ne 'Unknown') {
return
}
}
if ($Principal) {
if ($PrincipalType -eq 'Sid') {
if ($Principal -notcontains $GPOPermission.Trustee.Sid.Value) {
return
}
} elseif ($PrincipalType -eq 'DistinguishedName') {
if ($Principal -notcontains $GPOPermission.Trustee.DSPath) {
return
}
} elseif ($PrincipalType -eq 'Name') {
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
if ($Principal -notcontains $UserMerge -and $Principal -notcontains $GPOPermission.Trustee.Name) {
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'
}
} else {
$ReturnObject['UserPrincipalName'] = ''
$ReturnObject['AccountEnabled'] = ''
$ReturnObject['PasswordLastSet'] = ''
$ReturnObject['LastLogonDate'] = ''
}
}
if ($IncludeGPOObject) {
$ReturnObject['GPOObject'] = $GPO
$ReturnObject['GPOSecurity'] = $SecurityRights
$ReturnObject['GPOSecurityPermissionItem'] = $GPOPermission
}
[PSCustomObject] $ReturnObject
}
if ($IncludeOwner.IsPresent) {
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
} else {
$SIDType = ''
$DistinguishedName = ''
}
} else {
$SIDType = ''
$DomainOwner = $GPO.Owner
$DomainUserName = ''
$SID = ''
$SIDType = 'EmptyOrUnknown'
$DistinguishedName = ''
}
} else {
$DomainOwner = $GPO.Owner
$DomainUserName = ''
$SID = ''
$SIDType = 'EmptyOrUnknown'
$DistinguishedName = ''
}
$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'
}
} else {
$ReturnObject['UserPrincipalName'] = ''
$ReturnObject['AccountEnabled'] = ''
$ReturnObject['PasswordLastSet'] = ''
$ReturnObject['LastLogonDate'] = ''
$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'
}
} else {
$ReturnObject['UserPrincipalName'] = ''
$ReturnObject['AccountEnabled'] = ''
$ReturnObject['PasswordLastSet'] = ''
$ReturnObject['LastLogonDate'] = ''
}
}
if ($IncludeGPOObject) {
$ReturnObject['GPOObject'] = $GPO
$ReturnObject['GPOSecurity'] = $SecurityRights
$ReturnObject['GPOSecurityPermissionItem'] = $null
}
[PSCustomObject] $ReturnObject
}
if ($IncludeGPOObject) {
$ReturnObject['GPOObject'] = $GPO
$ReturnObject['GPOSecurity'] = $SecurityRights
$ReturnObject['GPOSecurityPermissionIndex'] = $null
}
[PSCustomObject] $ReturnObject
}
End {
}
}
+31 -28
View File
@@ -45,7 +45,7 @@
} elseif ($WellKnown.Name) {
$OwnerType = 'WellKnown'
} else {
$OwnerType = 'NonAdministrative'
$OwnerType = 'NotAdministrative'
}
} else {
$OwnerType = 'EmptyOrUnknown'
@@ -53,48 +53,51 @@
}
if ($PermissionsOnly) {
[PsCustomObject] @{
'DisplayName' = $XMLContent.GPO.Name
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText
'Enabled' = $Enabled
'Name' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text'
'Sid' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text'
'DisplayName' = $XMLContent.GPO.Name
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}'
'Enabled' = $Enabled
'Name' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text'
'Sid' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text'
#'SidType' = if (($XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text').Length -le 10) { 'WellKnown' } else { 'Other' }
'PermissionType' = 'Allow'
'Inherited' = $false
'Permissions' = 'Owner'
'PermissionType' = 'Allow'
'Inherited' = $false
'Permissions' = 'Owner'
'GPODistinguishedName' = $GPO.Path
}
$XMLContent.GPO.SecurityDescriptor.Permissions.TrusteePermissions | ForEach-Object -Process {
if ($_) {
[PsCustomObject] @{
'DisplayName' = $XMLContent.GPO.Name
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText
'Enabled' = $Enabled
'Name' = $_.trustee.name.'#Text'
'Sid' = $_.trustee.SID.'#Text'
'DisplayName' = $XMLContent.GPO.Name
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}'
'Enabled' = $Enabled
'Name' = $_.trustee.name.'#Text'
'Sid' = $_.trustee.SID.'#Text'
#'SidType' = if (($XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text').Length -le 10) { 'WellKnown' } else { 'Other' }
'PermissionType' = $_.type.PermissionType
'Inherited' = if ($_.Inherited -eq 'false') { $false } else { $true }
'Permissions' = $_.Standard.GPOGroupedAccessEnum
'PermissionType' = $_.type.PermissionType
'Inherited' = if ($_.Inherited -eq 'false') { $false } else { $true }
'Permissions' = $_.Standard.GPOGroupedAccessEnum
'GPODistinguishedName' = $GPO.Path
}
}
}
} elseif ($OwnerOnly) {
[PsCustomObject] @{
'DisplayName' = $XMLContent.GPO.Name
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText
'Enabled' = $Enabled
'Owner' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text'
'OwnerSID' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text'
'OwnerType' = $OwnerType
'DisplayName' = $XMLContent.GPO.Name
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}'
'Enabled' = $Enabled
'Owner' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text'
'OwnerSID' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text'
'OwnerType' = $OwnerType
'GPODistinguishedName' = $GPO.Path
}
} else {
[PsCustomObject] @{
'DisplayName' = $XMLContent.GPO.Name
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}'
'Linked' = $Linked
'LinksCount' = $LinksCount
'Enabled' = $Enabled
@@ -115,7 +118,7 @@
'WMIFilter' = $GPO.WmiFilter.name
'WMIFilterDescription' = $GPO.WmiFilter.Description
'DistinguishedName' = $GPO.Path
'GPODistinguishedName' = $GPO.Path
'SDDL' = if ($Splitter -ne '') { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' -join $Splitter } else { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' }
'Owner' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text'
'OwnerSID' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text'
+66
View File
@@ -0,0 +1,66 @@
function Remove-PrivPermission {
[cmdletBinding(SupportsShouldProcess)]
param(
[string] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName',
[PSCustomObject] $GPOPermission,
[alias('PermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType
)
if ($GPOPermission.Name) {
$Text = "Removing SID: $($GPOPermission.Sid), Name: $($GPOPermission.Name), SidType: $($GPOPermission.SidType) from domain $($GPOPermission.DomainName)"
} else {
$Text = "Removing SID: $($GPOPermission.Sid), Name: EMPTY, SidType: $($GPOPermission.SidType) from domain $($GPOPermission.DomainName)"
}
if ($PrincipalType -eq 'DistinguishedName') {
if ($GPOPermission.DistinguishedName -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, $Text)) {
try {
Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name) / Type: $($GPOPermission.PermissionType)"
$GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionItem)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
}
}
} elseif ($PrincipalType -eq 'Sid') {
if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, $Text)) {
try {
Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name) / Type: $($GPOPermission.PermissionType)"
$GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionItem)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
if ($_.Exception.Message -like '*The request is not supported. (Exception from HRESULT: 0x80070032)*') {
Write-Warning "Remove-GPOZaurrPermission - Bummer! The request is not supported, but lets fix it differently."
# This is basically atomic approach. We will totally remove any permissions for that user on ACL level to get rid of this situation.
# This situation should only happen if DENY is on FULL Control
$ACL = Get-ADACL -ADObject $GPOPermission.GPOObject.Path -Bundle #-Verbose:$VerbosePreference
if ($ACL) {
Remove-ADACL -ACL $ACL -Principal $Principal -AccessControlType Deny -Verbose:$VerbosePreference
}
# I've noticed that in situation where Edit settings, delete, modify security is set and then set to Deny we need to fix it once more
$ACL = Get-ADACL -ADObject $GPOPermission.GPOObject.Path -Bundle
if ($ACL) {
Remove-ADACL -ACL $ACL -Principal $Principal -AccessControlType Allow -Verbose:$VerbosePreference
}
} else {
Write-Warning "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
}
}
}
} elseif ($PrincipalType -eq 'Name') {
if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, $Text)) {
try {
Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name) / Type: $($GPOPermission.PermissionType)"
$GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionItem)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
}
}
}
}
+119
View File
@@ -0,0 +1,119 @@
function Test-SysVolFolders {
[cmdletBinding()]
param(
[Array] $GPOs,
[string] $Server,
[string] $Domain
)
$Differences = @{ }
$SysvolHash = @{ }
$GPOGUIDS = $GPOs.ID.GUID
try {
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -ErrorAction Stop
} catch {
$Sysvol = $Null
}
foreach ($_ in $SYSVOL) {
$GUID = $_.Name -replace '{' -replace '}'
$SysvolHash[$GUID] = $_
}
$Files = $SYSVOL.Name -replace '{' -replace '}'
if ($Files) {
$Comparing = Compare-Object -ReferenceObject $GPOGUIDS -DifferenceObject $Files -IncludeEqual
foreach ($_ in $Comparing) {
if ($_.SideIndicator -eq '==') {
$Found = 'Exists'
} elseif ($_.SideIndicator -eq '<=') {
$Found = 'Not available on SYSVOL'
} elseif ($_.SideIndicator -eq '=>') {
$Found = 'Orphaned GPO'
} else {
$Found = 'Orphaned GPO'
}
$Differences[$_.InputObject] = $Found
}
}
$GPOSummary = @(
foreach ($GPO in $GPOS) {
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
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrSysvol - ACL reading (1) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = ''
$ErrorMessage = $_.Exception.Message
}
} else {
$ACL = $null
}
if ($null -eq $Differences[$GPO.Id.Guid]) {
$SysVolStatus = 'Not available on SYSVOL'
} 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
}
}
# 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
}
[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
}
}
}
}
)
$GPOSummary | Sort-Object -Property DisplayName
}
+30
View File
@@ -0,0 +1,30 @@
function Add-GPOPermission {
[cmdletBinding()]
param(
[validateset('WellKnownAdministrative', 'Administrative', 'AuthenticatedUsers', 'Default')][string] $Type = 'Default',
[Microsoft.GroupPolicy.GPPermissionType] $IncludePermissionType,
[alias('Principal')][Array] $Trustee,
[alias('PrincipalType')][validateset('DistinguishedName', 'Name', 'Sid')][string] $TrusteeType = 'DistinguishedName'
)
if ($Type -eq 'Default') {
@{
Action = 'Add'
Type = 'Standard'
Trustee = $Trustee
IncludePermissionType = $IncludePermissionType
TrusteeType = $TrusteeType
}
} elseif ($Type -eq 'AuthenticatedUsers') {
@{
Action = 'Add'
Type = 'AuthenticatedUsers'
IncludePermissionType = $IncludePermissionType
}
} elseif ($Type -eq 'Administrative') {
@{
Action = 'Add'
Type = 'Administrative'
IncludePermissionType = $IncludePermissionType
}
}
}
+83 -24
View File
@@ -10,22 +10,28 @@
[Parameter(ParameterSetName = 'ADObject', Mandatory)]
[alias('OrganizationalUnit', 'DistinguishedName')][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject,
[validateset('WellKnownAdministrative', 'Administrative', 'AuthenticatedUsers', 'Default')][string] $Type = 'Default',
[string] $Principal,
[Microsoft.GroupPolicy.GPPermissionType[]] $PermissionType,
[alias('IncludePermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $PermissionType,
[switch] $Inheritable,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation,
[System.Collections.IDictionary] $ADAdministrativeGroups,
[int] $LimitProcessing
)
Begin {
$Count = 0
#$Count = 0
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
if (-not $ADAdministrativeGroups) {
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
}
$ForestInformation = Get-ADForest
}
Process {
if ($GPOName) {
$Splat = @{
GPOName = $GPOName
@@ -42,9 +48,9 @@
$Splat['IncludeGPOObject'] = $true
$Splat['Forest'] = $Forest
$Splat['IncludeDomains'] = $IncludeDomains
$Splat['ExcludeDomains'] = $ExcludeDomains
$Splat['ExtendedForestInformation'] = $ExtendedForestInformation
$Splat['IncludeDomains'] = $Domain
#$Splat['ExcludeDomains'] = $ExcludeDomains
#$Splat['ExtendedForestInformation'] = $ExtendedForestInformation
#$Splat['ExcludePermissionType'] = $ExcludePermissionType
#$Splat['IncludePermissionType'] = $PermissionType-
$Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent
@@ -54,15 +60,47 @@
#Set-GPPermission -PermissionLevel $PermissionType -TargetName $Principal -TargetType Group -Verbose -DomainName 'ad.evotec.xyz' -Name $GPOName -Replace #-WhatIf
$AdministrativeExists = @{
DomainAdmins = $false
EnterpriseAdmins = $false
}
#continue
[Array] $GPOPermissions = Get-GPOZaurrPermission @Splat
[Array] $LimitedPermissions = foreach ($GPOPermission in $GPOPermissions) {
#$GPOPermission = $_
# continue
if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) {
Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)"
$GPOPermission
#break
if ($Type -eq 'Default') {
if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) {
#Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)"
$GPOPermission
break
}
} elseif ($Type -eq 'Administrative') {
if ($GPOPermission.Permission -eq $PermissionType) {
$AdministrativeGroup = $ADAdministrativeGroups['BySID'][$GPOPermission.SID]
if ($AdministrativeGroup) {
if ($GPOPermission.SID -like '*-512') {
#Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)"
$AdministrativeExists['DomainAdmins'] = $true
} elseif ($GPOPermission.SID -like '*-519') {
#Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)"
$AdministrativeExists['EnterpriseAdmins'] = $true
}
}
}
} elseif ($Type -eq 'WellKnownAdministrative') {
if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) {
#Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)"
$GPOPermission
break
}
} elseif ($Type -eq 'AuthenticatedUsers') {
if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) {
#Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)"
$GPOPermission
break
}
}
# Write-Verbose "Test"
# $GPOPermission
@@ -78,20 +116,37 @@
# $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
}
if ($GPOPermissions.Count -gt 0) {
if ($LimitedPermissions.Count -gt 0) {
#$LimitedPermissions
} else {
if ($Type -eq 'Administrative') {
if ($AdministrativeExists['DomainAdmins'] -eq $false) {
$Principal = $ADAdministrativeGroups[$GPOPermission.DomainName]['DomainAdmins']
Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)"
$AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent)
$GPOPermissions[0].GPOSecurity.Add($AddPermission)
$GPOPermissions[0].GPOObject.SetSecurityInfo( $GPOPermissions[0].GPOSecurity)
}
if ($AdministrativeExists['EnterpriseAdmins'] -eq $false) {
$Principal = $ADAdministrativeGroups[$ForestInformation.RootDomain]['EnterpriseAdmins']
Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)"
$AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent)
$GPOPermissions[0].GPOSecurity.Add($AddPermission)
$GPOPermissions[0].GPOObject.SetSecurityInfo( $GPOPermissions[0].GPOSecurity)
}
} elseif ($Type -eq 'Default') {
try {
Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)"
$AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent)
$GPOPermissions[0].GPOSecurity.Add($AddPermission)
$GPOPermissions[0].GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
}
if ($LimitedPermissions.Count -gt 0) {
#$LimitedPermissions
} else {
try {
Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)"
$AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent)
$GPOPermissions[0].GPOSecurity.Add($AddPermission)
$GPOPermissions[0].GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
<#
<#
[Microsoft.GroupPolicy.GPPermission]::new
OverloadDefinitions
@@ -100,8 +155,12 @@
Microsoft.GroupPolicy.GPPermission new(System.Security.Principal.IdentityReference identity, Microsoft.GroupPolicy.GPPermissionType rights, bool inheritable)
#>
}
} else {
Write-Warning "Add-GPOZaurrPermission - GPO $($GPOPermissions[0].GPOName) has no permissions. Weird."
}
}
End {
}
+10 -5
View File
@@ -12,10 +12,15 @@
[switch] $PermissionsOnly,
[switch] $OwnerOnly,
[switch] $Limited
[switch] $Limited,
[System.Collections.IDictionary] $ADAdministrativeGroups
)
Begin {
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
if (-not $ADAdministrativeGroups) {
Write-Verbose "Get-GPOZaurr - Getting ADAdministrativeGroups"
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
}
if (-not $GPOPath) {
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
}
@@ -31,7 +36,7 @@
try {
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
} catch {
Write-Warning "Get-GPOZaurr - Failed to ger GPOReport: $($_.Exception.Message). Skipping."
Write-Warning "Get-GPOZaurr - Failed to get GPOReport: $($_.Exception.Message). Skipping."
continue
}
Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups
@@ -46,7 +51,7 @@
try {
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
} catch {
Write-Warning "Get-GPOZaurr - Failed to ger GPOReport: $($_.Exception.Message). Skipping."
Write-Warning "Get-GPOZaurr - Failed to get GPOReport: $($_.Exception.Message). Skipping."
continue
}
Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups
@@ -61,7 +66,7 @@
try {
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
} catch {
Write-Warning "Get-GPOZaurr - Failed to ger GPOReport: $($_.Exception.Message). Skipping."
Write-Warning "Get-GPOZaurr - Failed to get GPOReport: $($_.Exception.Message). Skipping."
continue
}
Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups
+72
View File
@@ -0,0 +1,72 @@
function Get-GPOZaurrAD {
[cmdletbinding(DefaultParameterSetName = 'Default')]
param(
[Parameter(ParameterSetName = 'GPOName')]
[string] $GPOName,
[Parameter(ParameterSetName = 'GPOGUID')]
[alias('GUID', 'GPOID')][string] $GPOGuid,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation
)
Begin {
$ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
}
Process {
foreach ($Domain in $ForestInformation.Domains) {
if ($PSCmdlet.ParameterSetName -eq 'GPOGUID') {
if ($GPOGuid) {
if ($GPOGUID -notlike '*{*') {
$GUID = -join ("{", $GPOGUID, '}')
} else {
$GUID = $GPOGUID
}
$Splat = @{
Filter = "(objectClass -eq 'groupPolicyContainer') -and (Name -eq '$GUID')"
Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
}
} else {
Write-Warning "Get-GPOZaurrAD - GPOGUID parameter is empty. Provide name and try again."
continue
}
} elseif ($PSCmdlet.ParameterSetName -eq 'GPOName') {
if ($GPOName) {
$Splat = @{
Filter = "(objectClass -eq 'groupPolicyContainer') -and (DisplayName -eq '$GPOName')"
Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
}
} else {
Write-Warning "Get-GPOZaurrAD - GPOName parameter is empty. Provide name and try again."
continue
}
} else {
$Splat = @{
Filter = "(objectClass -eq 'groupPolicyContainer')"
Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
}
}
Get-ADObject @Splat -Properties DisplayName, Name, Created, Modified, gPCFileSysPath, gPCFunctionalityVersion, gPCWQLFilter, gPCMachineExtensionNames, Description, CanonicalName, DistinguishedName | ForEach-Object -Process {
$DomainCN = ConvertFrom-DistinguishedName -DistinguishedName $_.DistinguishedName -ToDomainCN
$Output = [ordered]@{ }
$Output['DisplayName'] = $_.DisplayName
$Output['DomainName'] = $DomainCN
$Output['Description'] = $_.Description
$Output['GUID'] = $_.Name -replace '{' -replace '}'
$Output['Path'] = $_.gPCFileSysPath
$Output['FunctionalityVersion'] = $_.gPCFunctionalityVersion
$Output['Created'] = $_.Created
$Output['Modified'] = $_.Modified
$Output['GPOCanonicalName'] = $_.CanonicalName
$Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_.DistinguishedName -ToDC
$Output['GPODistinguishedName'] = $_.DistinguishedName
[PSCustomObject] $Output
}
}
}
End {
}
}
+5 -5
View File
@@ -11,15 +11,15 @@
if ($Folder) {
if ((Test-Path -LiteralPath "$Folder\manifest.xml")) {
[xml] $Xml = Get-Content -LiteralPath "$Folder\manifest.xml"
$Xml.Backups.BackupInst | ForEach-Object {
$Xml.Backups.BackupInst | ForEach-Object -Process {
[PSCustomObject] @{
DisplayName = $_.GPODisplayName.'#cdata-section'
DomainName = $_.GPODomain.'#cdata-section'
Guid = $_.GPOGUid.'#cdata-section'
DomainGuid = $_.GPODomainGuid.'#cdata-section'
Guid = $_.GPOGUid.'#cdata-section' -replace '{' -replace '}'
DomainGuid = $_.GPODomainGuid.'#cdata-section' -replace '{' -replace '}'
DomainController = $_.GPODomainController.'#cdata-section'
BackupTime = $_.BackupTime.'#cdata-section'
ID = $_.ID.'#cdata-section'
BackupTime = [DateTime]::Parse($_.BackupTime.'#cdata-section')
ID = $_.ID.'#cdata-section' -replace '{' -replace '}'
Comment = $_.Comment.'#cdata-section'
}
}
+122 -25
View File
@@ -1,18 +1,42 @@
function Get-GPOZaurrLink {
[cmdletbinding()]
param(
[parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject,
[parameter(ParameterSetName = 'ADObject', ValueFromPipeline, ValueFromPipelineByPropertyName, Mandatory)][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject,
# weirdly enough site doesn't really work this way unless you give it 'CN=Configuration,DC=ad,DC=evotec,DC=xyz' as SearchBase
[parameter(ParameterSetName = 'Filter')][string] $Filter = "(objectClass -eq 'organizationalUnit' -or objectClass -eq 'domainDNS' -or objectClass -eq 'site')",
[parameter(ParameterSetName = 'Filter')][string] $SearchBase,
[parameter(ParameterSetName = 'Filter')][Microsoft.ActiveDirectory.Management.ADSearchScope] $SearchScope,
[parameter(ParameterSetName = 'Linked', Mandatory)][validateset('Root', 'DomainControllers', 'Site', 'Other')][string] $Linked,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[switch] $Limited,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[System.Collections.IDictionary] $GPOCache,
[string] $Filter = '*',
[string] $SearchBase,
[Microsoft.ActiveDirectory.Management.ADSearchScope] $SearchScope,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('ForestName')][string] $Forest,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[string[]] $ExcludeDomains,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[System.Collections.IDictionary] $ExtendedForestInformation
)
Begin {
@@ -22,34 +46,107 @@
foreach ($Domain in $ForestInformation.Domains) {
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
Get-GPO -All -DomainName $Domain -Server $QueryServer | ForEach-Object {
$GPOCache[$_.ID.Guid] = $_
$GPOCache["$Domain$($_.ID.Guid)"] = $_
}
}
}
}
Process {
if (-not $ADObject) {
foreach ($Domain in $ForestInformation.Domains) {
$Splat = @{
Filter = $Filter
Properties = 'distinguishedName', 'gplink', 'CanonicalName'
Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
}
if ($PSBoundParameters.ContainsKey('SearchBase')) {
$DomainDistinguishedName = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName']
if ($SearchBase -notlike "*$DomainDistinguishedName") {
# we check if SearchBase is part of domain distinugishname. If it isn't we skip
continue
if ($Linked) {
foreach ($Domain in $ForestInformation.Domains) {
$Splat = @{
#Filter = $Filter
Properties = 'distinguishedName', 'gplink', 'CanonicalName'
# Filter = "(objectClass -eq 'organizationalUnit' -or objectClass -eq 'domainDNS' -or objectClass -eq 'site')"
Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
}
if ($Linked -contains 'DomainControllers') {
$SearchBase = $ForestInformation['DomainsExtended'][$Domain]['DomainControllersContainer']
#if ($SearchBase -notlike "*$DomainDistinguishedName") {
# we check if SearchBase is part of domain distinugishname. If it isn't we skip
# continue
#}
$Splat['Filter'] = "(objectClass -eq 'organizationalUnit')"
$Splat['SearchBase'] = $SearchBase
Get-ADObject @Splat | ForEach-Object -Process {
Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache
}
}
if ($Linked -contains 'Root') {
$SearchBase = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName']
#if ($SearchBase -notlike "*$DomainDistinguishedName") {
# we check if SearchBase is part of domain distinugishname. If it isn't we skip
# continue
# }
$Splat['Filter'] = "objectClass -eq 'domainDNS'"
$Splat['SearchBase'] = $SearchBase
Get-ADObject @Splat | ForEach-Object -Process {
Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache
}
}
if ($Linked -contains 'Site') {
# Sites are defined only in primary domain
if ($ForestInformation['DomainsExtended'][$Domain]['DNSRoot'] -eq $ForestInformation['DomainsExtended'][$Domain]['Forest']) {
$SearchBase = -join ("CN=Configuration,", $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName'])
# if ($SearchBase -notlike "*$DomainDistinguishedName") {
# we check if SearchBase is part of domain distinugishname. If it isn't we skip
#continue
#}
$Splat['Filter'] = "(objectClass -eq 'site')"
$Splat['SearchBase'] = $SearchBase
Get-ADObject @Splat | ForEach-Object -Process {
Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache
}
}
}
if ($Linked -contains 'Other') {
$SearchBase = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName']
#if ($SearchBase -notlike "*$DomainDistinguishedName") {
# we check if SearchBase is part of domain distinugishname. If it isn't we skip
# continue
#}
$Splat['Filter'] = "(objectClass -eq 'organizationalUnit')"
$Splat['SearchBase'] = $SearchBase
Get-ADObject @Splat | ForEach-Object -Process {
if ($_.DistinguishedName -eq $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName']) {
# other skips Domain Root
} elseif ($_.DistinguishedName -eq $ForestInformation['DomainsExtended'][$Domain]['DomainControllersContainer']) {
# other skips Domain Controllers
} else {
Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache
}
}
}
$Splat['SearchBase'] = $SearchBase
}
if ($PSBoundParameters.ContainsKey('SearchScope')) {
$Splat['SearchScope'] = $SearchScope
}
} else {
foreach ($Domain in $ForestInformation.Domains) {
$Splat = @{
Filter = $Filter
Properties = 'distinguishedName', 'gplink', 'CanonicalName'
Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
Get-ADObject @Splat | ForEach-Object {
Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache
}
if ($PSBoundParameters.ContainsKey('SearchBase')) {
$DomainDistinguishedName = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName']
if ($SearchBase -notlike "*$DomainDistinguishedName") {
# we check if SearchBase is part of domain distinugishname. If it isn't we skip
continue
}
$Splat['SearchBase'] = $SearchBase
}
if ($PSBoundParameters.ContainsKey('SearchScope')) {
$Splat['SearchScope'] = $SearchScope
}
try {
Get-ADObject @Splat | ForEach-Object {
Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache
}
} catch {
Write-Warning "Get-GPOZaurrLink - Processing error $($_.Exception.Message)"
}
}
}
} else {
+60
View File
@@ -0,0 +1,60 @@
function Get-GPOZaurrOwner {
[cmdletbinding(DefaultParameterSetName = 'Default')]
param(
[Parameter(ParameterSetName = 'GPOName')][string] $GPOName,
[Parameter(ParameterSetName = 'GPOGUID')][alias('GUID', 'GPOID')][string] $GPOGuid,
[switch] $IncludeSysvol,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation,
[System.Collections.IDictionary] $ADAdministrativeGroups
)
Begin {
$ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
if (-not $ADAdministrativeGroups) {
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
}
}
Process {
$getGPOZaurrADSplat = @{
Forest = $Forest
IncludeDomains = $IncludeDomains
ExcludeDomains = $ExcludeDomains
ExtendedForestInformation = $ForestInformation
}
if ($GPOName) {
$getGPOZaurrADSplat['GPOName'] = $GPOName
} elseif ($GPOGuid) {
$getGPOZaurrADSplat['GPOGUID'] = $GPOGuid
}
$Objects = Get-GPOZaurrAD @getGPOZaurrADSplat
foreach ($_ in $Objects) {
Write-Verbose "Get-GPOZaurrOwner - Processing GPO: $($_.DisplayName) from domain: $($_.DomainName)"
$ACL = Get-ADACLOwner -ADObject $_.GPODistinguishedName -Resolve -ADAdministrativeGroups $ADAdministrativeGroups
$Object = [ordered] @{
DisplayName = $_.DisplayName
DomainName = $_.DomainName
GUID = $_.GUID
Owner = $ACL.OwnerName
OwnerSid = $ACL.OwnerSid
OwnerType = $ACL.OwnerType
}
if ($IncludeSysvol) {
$FileOwner = Get-FileOwner -JustPath -Path $_.Path -Resolve
$Object['SysvolOwner'] = $FileOwner.OwnerName
$Object['SysvolSid'] = $FileOwner.OwnerSid
$Object['SysvolType'] = $FileOwner.OwnerType
$Object['SysvolPath'] = $_.Path
$Object['IsOwnerConsistent'] = if ($ACL.OwnerName -eq $FileOwner.OwnerName) { $true } else { $false }
}
$Object['DistinguishedName'] = $_.GPODistinguishedName
[PSCUstomObject] $Object
}
}
End {
}
}
+36 -8
View File
@@ -7,7 +7,10 @@
[Parameter(ParameterSetName = 'GPOGUID')]
[alias('GUID', 'GPOID')][string] $GPOGuid,
[validateSet('Unknown', 'All')][string[]] $Type = 'All',
[string[]] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
[validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All',
[switch] $SkipWellKnown,
[switch] $SkipAdministrative,
@@ -48,24 +51,49 @@
}
}
}
}
Process {
foreach ($Domain in $ForestInformation.Domains) {
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
if ($GPOName) {
Get-GPO -Name $GPOName -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object -Process {
Get-PrivPermission -Accounts $Accounts -Type $Type -GPO $_ -SkipWellKnown:$SkipWellKnown.IsPresent -SkipAdministrative:$SkipAdministrative.IsPresent -IncludeOwner:$IncludeOwner.IsPresent -IncludeGPOObject:$IncludeGPOObject.IsPresent -IncludePermissionType $IncludePermissionType -ExcludePermissionType $ExcludePermissionType -ADAdministrativeGroups $ADAdministrativeGroups
$getGPOSplat = @{
Name = $GPOName
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
} elseif ($GPOGuid) {
Get-GPO -Guid $GPOGuid -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object -Process {
Get-PrivPermission -Accounts $Accounts -Type $Type -GPO $_ -SkipWellKnown:$SkipWellKnown.IsPresent -SkipAdministrative:$SkipAdministrative.IsPresent -IncludeOwner:$IncludeOwner.IsPresent -IncludeGPOObject:$IncludeGPOObject.IsPresent -IncludePermissionType $IncludePermissionType -ExcludePermissionType $ExcludePermissionType -ADAdministrativeGroups $ADAdministrativeGroups
$getGPOSplat = @{
Guid = $GPOGuid
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
} else {
Get-GPO -All -Domain $Domain -Server $QueryServer | ForEach-Object -Process {
Get-PrivPermission -Accounts $Accounts -Type $Type -GPO $_ -SkipWellKnown:$SkipWellKnown.IsPresent -SkipAdministrative:$SkipAdministrative.IsPresent -IncludeOwner:$IncludeOwner.IsPresent -IncludeGPOObject:$IncludeGPOObject.IsPresent -IncludePermissionType $IncludePermissionType -ExcludePermissionType $ExcludePermissionType -ADAdministrativeGroups $ADAdministrativeGroups
$getGPOSplat = @{
All = $true
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
}
Get-GPO @getGPOSplat | ForEach-Object -Process {
$getPrivPermissionSplat = @{
Principal = $Principal
PrincipalType = $PrincipalType
Accounts = $Accounts
Type = $Type
GPO = $_
SkipWellKnown = $SkipWellKnown.IsPresent
SkipAdministrative = $SkipAdministrative.IsPresent
IncludeOwner = $IncludeOwner.IsPresent
IncludeGPOObject = $IncludeGPOObject.IsPresent
IncludePermissionType = $IncludePermissionType
ExcludePermissionType = $ExcludePermissionType
ADAdministrativeGroups = $ADAdministrativeGroups
}
Get-PrivPermission @getPrivPermissionSplat
}
}
}
End {
@@ -0,0 +1,122 @@
function Get-GPOZaurrPermissionConsistency {
[cmdletBinding()]
param(
[Parameter(ParameterSetName = 'GPOName')][string] $GPOName,
[Parameter(ParameterSetName = 'GPOGUID')][alias('GUID', 'GPOID')][string] $GPOGuid,
[Parameter(ParameterSetName = 'Type')][validateSet('Consistent', 'Inconsistent', 'All')][string[]] $Type = 'All',
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation,
[switch] $IncludeGPOObject,
[switch] $VerifyInheritance
)
Begin {
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
}
Process {
foreach ($Domain in $ForestInformation.Domains) {
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
if ($GPOName) {
$getGPOSplat = @{
Name = $GPOName
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
} elseif ($GPOGuid) {
$getGPOSplat = @{
Guid = $GPOGuid
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
} else {
$getGPOSplat = @{
All = $true
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
}
Get-GPO @getGPOSplat | ForEach-Object -Process {
try {
$IsConsistent = $_.IsAclConsistent()
$ErrorMessage = ''
} catch {
$ErrorMessage = $_.Exception.Message
Write-Warning "Get-GPOZaurrPermissionConsistency - Failed to get consistency: $($_.Exception.Message)."
$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
}
}
if ($NotInheritedPermissions.Count -eq 0) {
$ACLConsistentInside = $true
} else {
$ACLConsistentInside = $false
}
} else {
$ACLConsistentInside = $null
}
$Object = [ordered] @{
DisplayName = $_.DisplayName # : New Group Policy Object
DomainName = $_.DomainName # : ad.evotec.xyz
ACLConsistent = $IsConsistent
}
if ($VerifyInheritance) {
$Object['ACLConsistentInside'] = $ACLConsistentInside
}
$Object['Owner'] = $_.Owner # : EVOTEC\Enterprise Admins
$Object['Path'] = $_.Path
$Object['SysVolPath '] = $SysvolPath
$Object['Id '] = $_.Id # : 8a7bc515-d7fd-4d1f-90b8-e47c15f89295
$Object['GpoStatus'] = $_.GpoStatus # : AllSettingsEnabled
$Object['Description'] = $_.Description # :
$Object['CreationTime'] = $_.CreationTime # : 04.03.2020 17:19:42
$Object['ModificationTime'] = $_.ModificationTime# : 06.05.2020 10:30:36
$Object['UserVersion'] = $_.UserVersion # : AD Version: 0, SysVol Version: 0
$Object['ComputerVersion'] = $_.ComputerVersion # : AD Version: 1, SysVol Version: 1
$Object['WmiFilter'] = $_.WmiFilter # :
$Object['Error'] = $ErrorMessage
if ($IncludeGPOObject) {
$Object['IncludeGPOObject'] = $_
}
if ($VerifyInheritance) {
$Object['ACLConsistentInsideDetails'] = $NotInheritedPermissions
}
if ($Type -eq 'All') {
[PSCustomObject] $Object
} elseif ($Type -eq 'Inconsistent') {
if ($VerifyInheritance) {
if (-not $IsConsistent -or -not $ACLConsistentInside) {
[PSCustomObject] $Object
}
} else {
if (-not $IsConsistent) {
[PSCustomObject] $Object
}
}
} elseif ($Type -eq 'Consistent') {
if ($VerifyInheritance) {
if ($IsConsistent -and $ACLConsistentInside) {
[PSCustomObject] $Object
}
} else {
if ($IsConsistent) {
[PSCustomObject] $Object
}
}
}
}
}
}
End {
}
}
+37
View File
@@ -0,0 +1,37 @@
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."
}
}
}
+56 -65
View File
@@ -1,4 +1,11 @@
function Get-GPOZaurrWMI {
function Get-WMIFilter {
param(
)
}
function Get-GPOZaurrWMI {
[cmdletBinding()]
Param(
[Guid[]] $Guid,
@@ -13,79 +20,63 @@
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
foreach ($Domain in $ForestInformation.Domains) {
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
if ($Guid -or $Name) {
foreach ($N in $Name) {
try {
$ldapFilter = "(&(objectClass=msWMI-Som)(msWMI-Name=$N))"
Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer | ForEach-Object -Process {
$WMI = $_.'msWMI-Parm2' -split ';'
[PSCustomObject] @{
DisplayName = $_.'msWMI-Name'
Description = $_.'msWMI-Parm1'
DomainName = $Domain
NameSpace = $WMI[5]
Query = $WMI[6]
Author = $_.'msWMI-Author'
ID = $_.'msWMI-ID'
Created = $_.Created
Modified = $_.Modified
ObjectGUID = $_.'ObjectGUID'
CanonicalName = $_.CanonicalName
DistinguishedName = $_.'DistinguishedName'
}
$Objects = @(
if ($Name) {
foreach ($N in $Name) {
try {
$ldapFilter = "(&(objectClass=msWMI-Som)(msWMI-Name=$N))"
Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer
} catch {
Write-Warning "Get-GPOZaurrWMI - Error processing WMI for $Domain`: $($_.Error.Exception)"
}
}
} elseif ($GUID) {
foreach ($G in $GUID) {
try {
$ldapFilter = "(&(objectClass=msWMI-Som)(Name={$G}))"
Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer
} catch {
Write-Warning "Get-GPOZaurrWMI - Error processing WMI for $Domain`: $($_.Error.Exception)"
}
}
} else {
try {
$ldapFilter = "(objectClass=msWMI-Som)"
Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer
} catch {
Write-Warning "Get-GPOZaurrWMI - Error processing WMI for $Domain`: $($_.Error.Exception)"
}
}
foreach ($G in $GUID) {
$ldapFilter = "(&(objectClass=msWMI-Som)(Name={$G}))"
try {
Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer | ForEach-Object -Process {
$WMI = $_.'msWMI-Parm2' -split ';'
[PSCustomObject] @{
DisplayName = $_.'msWMI-Name'
Description = $_.'msWMI-Parm1'
DomainName = $Domain
NameSpace = $WMI[5]
Query = $WMI[6]
Author = $_.'msWMI-Author'
ID = $_.'msWMI-ID'
Created = $_.Created
Modified = $_.Modified
ObjectGUID = $_.'ObjectGUID'
CanonicalName = $_.CanonicalName
DistinguishedName = $_.'DistinguishedName'
}
}
} catch {
Write-Warning "Get-GPOZaurrWMI - Error processing WMI for $Domain`: $($_.Error.Exception)"
)
foreach ($_ in $Objects) {
$WMI = $_.'msWMI-Parm2' -split ';' #$WMI = $_.'msWMI-Parm2'.Split(';',8)
[Array] $Data = for ($i = 0; $i -lt $WMI.length; $i += 6) {
if ($WMI[$i + 5]) {
#[PSCustomObject] @{
# NameSpace = $WMI[$i + 5]
# Query = $WMI[$i + 6]
#}
-join ($WMI[$i + 5], ';' , $WMI[$i + 6])
}
}
} else {
$ldapFilter = "(objectClass=msWMI-Som)"
try {
Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer | ForEach-Object -Process {
$WMI = $_.'msWMI-Parm2' -split ';'
[PSCustomObject] @{
DisplayName = $_.'msWMI-Name'
Description = $_.'msWMI-Parm1'
DomainName = $Domain
NameSpace = $WMI[5]
Query = $WMI[6]
Author = $_.'msWMI-Author'
ID = $_.'msWMI-ID'
Created = $_.Created
Modified = $_.Modified
ObjectGUID = $_.'ObjectGUID'
CanonicalName = $_.CanonicalName
DistinguishedName = $_.'DistinguishedName'
}
}
} catch {
Write-Warning "Get-GPOZaurrWMI - Error processing WMI for $Domain`: $($_.Error.Exception)"
[PSCustomObject] @{
DisplayName = $_.'msWMI-Name'
Description = $_.'msWMI-Parm1'
DomainName = $Domain
#NameSpace = $WMI[$i + 5]
#Query = $WMI[$i + 6]
QueryCount = $Data.Count
Query = $Data -join ","
Author = $_.'msWMI-Author'
ID = $_.'msWMI-ID'
Created = $_.Created
Modified = $_.Modified
ObjectGUID = $_.'ObjectGUID'
CanonicalName = $_.CanonicalName
DistinguishedName = $_.'DistinguishedName'
}
}
}
}
<#
+229
View File
@@ -0,0 +1,229 @@
function Invoke-GPOZaurrPermission {
[cmdletBinding(SupportsShouldProcess)]
param(
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[parameter(Position = 0)]
[scriptblock] $PermissionRules,
[Parameter(ParameterSetName = 'GPOName')][string] $GPOName,
[Parameter(ParameterSetName = 'GPOGUID')][alias('GUID', 'GPOID')][string] $GPOGuid,
[parameter(ParameterSetName = 'Linked', Mandatory)][validateset('Root', 'DomainControllers', 'Site', 'Other')][string] $Linked,
[parameter(ParameterSetName = 'ADObject', ValueFromPipeline, ValueFromPipelineByPropertyName, Mandatory)][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject,
[parameter(ParameterSetName = 'Filter')][string] $Filter = "(objectClass -eq 'organizationalUnit' -or objectClass -eq 'domainDNS' -or objectClass -eq 'site')",
[parameter(ParameterSetName = 'Filter')][string] $SearchBase,
[parameter(ParameterSetName = 'Filter')][Microsoft.ActiveDirectory.Management.ADSearchScope] $SearchScope,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'All')][string[]] $Type,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[Array] $ApprovedGroups,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('Principal')][Array] $Trustee,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[Microsoft.GroupPolicy.GPPermissionType] $TrusteePermissionType,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('PrincipalType')][validateset('DistinguishedName', 'Name', 'Sid')][string] $TrusteeType = 'DistinguishedName',
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[System.Collections.IDictionary] $GPOCache,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('ForestName')][string] $Forest,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[string[]] $ExcludeDomains,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[Parameter(ParameterSetName = 'GPOGUID')]
[Parameter(ParameterSetName = 'GPOName')]
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[System.Collections.IDictionary] $ExtendedForestInformation
)
Begin {
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
<#
$Script:Actions = @{
GpoApply = @{
Remove = @{
NotAdministrative = $false
NotWellKnownAdministrative = $false
}
Add = @{
Administrative = $false
WellKnownAdministrative = $false
}
}
GpoRead = @{
Remove = @{
NotAdministrative = $false
NotWellKnownAdministrative = $false
}
Add = @{
Administrative = $false
WellKnownAdministrative = $false
}
}
GpoCustom = @{
Remove = @{
NotAdministrative = $false
NotWellKnownAdministrative = $false
}
Add = @{
Administrative = $false
WellKnownAdministrative = $false
}
}
GpoEditDeleteModifySecurity = @{
Remove = @{
NotAdministrative = $false
NotWellKnownAdministrative = $false
}
Add = @{
Administrative = $false
WellKnownAdministrative = $false
}
}
GpoEdit = @{
Remove = @{
NotAdministrative = $false
NotWellKnownAdministrative = $false
}
Add = @{
Administrative = $false
WellKnownAdministrative = $false
}
}
}
#>
}
Process {
if ($PermissionRules) {
$Rules = & $PermissionRules
<#
foreach ($Rule in $Rules) {
#$Actions["$Rule."]
if ($Rule.Action -eq 'Remove' -and $Rule.Type -contains 'NotWellKnownAdministrative') {
#$Actions.NotWellKnownAdministrative = $true
}
if ($Rule.Action -eq 'Remove' -and $Rule.Type -contains 'NotAdministrative') {
#$Actions.Remove.NotAdministrative = $true
}
}
#>
}
if ($GPOName -or $GPOGuid) {
} else {
$Splat = @{ }
if ($ADObject) {
$Splat['ADObject'] = $ADObject
} elseif ($Linked) {
$Splat['Linked'] = $Linked
} else {
if ($Filter) {
$Splat['Filter'] = $Filter
}
if ($SearchBase) {
$Splat['SearchBase'] = $SearchBase
}
if ($SearchScope) {
$Splat['SearchScope'] = $SearchScope
}
}
Get-GPOZaurrLink @Splat | ForEach-Object -Process {
$GPO = $_
foreach ($Rule in $Rules) {
if ($Rule.Action -eq 'Owner') {
if ($Rule.Type -eq 'Administrative') {
$AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"]
if (-not $AdministrativeGroup) {
$DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins']
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $DefaultPrincipal"
Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
}
} elseif ($Rule.Type -eq 'Default') {
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $($Rule.Principal)"
Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $Rule.Principal -Verbose:$false -WhatIf:$WhatIfPreference
}
continue
}
if ($Rule.Action -eq 'Remove') {
$GPOPermissions = Get-GPOZaurrPermission -GPOGuid $_.GUID -IncludePermissionType $Rule.IncludePermissionType -ExcludePermissionType $Rule.ExcludePermissionType -Type $Rule.Type -IncludeGPOObject
foreach ($Permission in $GPOPermissions) {
Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission #-IncludeDomains $GPO.DomainName
}
continue
}
if ($Rule.Action -eq 'Add') {
#$GPOPermissions = Get-GPOZaurrPermission -GPOGuid $_.GUID -IncludePermissionType $Rule.IncludePermissionType -ExcludePermissionType $Rule.ExcludePermissionType -Type 'All' -IncludeGPOObject
# foreach ($Permission in $GPOPermissions) {
Add-GPOZaurrPermission -GPOGuid $_.GUID -IncludeDomains $GPO.DomainName -Type $Rule.Type -PermissionType $Rule.IncludePermissionType -ADAdministrativeGroups $ADAdministrativeGroups
# }
}
}
}
}
}
End {
}
}
+3 -2
View File
@@ -3,6 +3,7 @@
param(
[parameter(Mandatory)][string] $Name,
[string] $Description = ' ',
[string] $Namespace = 'root\CIMv2',
[parameter(Mandatory)][string] $Query,
[switch] $SkipQueryCheck,
[switch] $Force,
@@ -50,7 +51,7 @@
[Array] $ExistingWmiFilter = Get-GPOZaurrWMI -ExtendedForestInformation $ForestInformation -IncludeDomains $Domain -Name $Name
if ($ExistingWmiFilter.Count -eq 0) {
[string] $WMIParm2 = -join ("1;3;10;", $Query.Length.ToString(), ";WQL;root\CIMv2;", $Query , ";")
[string] $WMIParm2 = -join ("1;3;10;", $Query.Length.ToString(), ";WQL;$Namespace;", $Query , ";")
$OtherAttributes = @{
"msWMI-Name" = $Name
"msWMI-Parm1" = $Description
@@ -67,7 +68,7 @@
try {
Write-Verbose "New-GPOZaurrWMI - Creating WMI filter $Name in $Domain"
New-ADObject -name $GUID -type "msWMI-Som" -Path $WMIPath -OtherAttributes $OtherAttributes -Server $QueryServer
New-ADObject -Name $GUID -Type "msWMI-Som" -Path $WMIPath -OtherAttributes $OtherAttributes -Server $QueryServer
} catch {
Write-Warning "New-GPOZaurrWMI - Creating GPO filter error $($_.Exception.Message). Terminating."
return
+45
View File
@@ -0,0 +1,45 @@
function Remove-GPOPermission {
[cmdletBinding()]
param(
[validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'Administrative', 'NotAdministrative', 'All')][string[]] $Type,
[Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
[Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType
)
if ($Type) {
@{
Action = 'Remove'
Type = $Type
IncludePermissionType = $IncludePermissionType
ExcludePermissionType = $ExcludePermissionType
}
}
<#
foreach ($T in $Type) {
foreach ($Permission in $IncludePermissionType) {
if ($T -eq 'NotWellKnownAdministrative') {
$Script:Actions[$Permission][$T] = $true
} elseif ($T -eq 'NotAdministrative') {
$Script:Actions[$Permission][$T] = $true
}
}
}
#>
}
<#
function Find-GPOPermission {
param(
$GPOPermissions,
[Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
[bool] $NotAdministrative,
[bool] $NotWellKnownAdministrative
)
foreach ($Permission in $GPOPermissions) {
if ($Permission.Permission -in $IncludePermissionType) {
if ($NotAdministrative -and $NotWellKnownAdministrative) {
$Permission
}
}
}
}
#>
@@ -0,0 +1,13 @@
function Remove-GPOZaurrOrphanedSysvolFolders {
[cmdletBinding(SupportsShouldProcess)]
param(
[int] $LimitProcessing = [int32]::MaxValue
)
Get-GPOZaurrSysvol | Where-Object {
if ($_.Status -eq 'Orphaned GPO') {
$_
}
} | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object {
Remove-Item -Recurse -Force -LiteralPath $_.Path
}
}
+69 -93
View File
@@ -7,18 +7,16 @@
[Parameter(ParameterSetName = 'GPOGUID', Mandatory)]
[alias('GUID', 'GPOID')][string] $GPOGuid,
[string] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName',
[string[]] $Principal,
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
[validateset('Unknown', 'Named', 'NonAdministrative', 'Default')][string[]] $Type = 'Default',
[validateset('Unknown', 'NotAdministrative', 'Default')][string[]] $Type = 'Default',
[alias('PermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
[Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType,
[switch] $SkipWellKnown,
[switch] $SkipAdministrative,
[string[]]$NamedObjects,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
@@ -28,37 +26,19 @@
)
Begin {
$Count = 0
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ForestInformation
if ($Type -eq 'Unknown') {
if ($SkipAdministrative -or $SkipWellKnown) {
Write-Warning "Remove-GPOZaurrPermission - Using SkipAdministrative or SkipWellKnown while looking for Unknown doesn't make sense as only Unknown will be displayed."
}
}
}
Process {
if ($Type -contains 'Named' -and $NamedObjects.Count -eq 0) {
if ($Type -contains 'Named' -and $Principal.Count -eq 0) {
Write-Warning "Remove-GPOZaurrPermission - When using type Named you need to provide names to remove. Terminating."
return
}
if ($GPOName) {
$Splat = @{
GPOName = $GPOName
}
} elseif ($GPOGUID) {
$Splat = @{
GPOGUID = $GPOGUID
}
} else {
$Splat = @{
}
}
$Splat['IncludeGPOObject'] = $true
$Splat['Forest'] = $Forest
$Splat['IncludeDomains'] = $IncludeDomains
$Splat['ExcludeDomains'] = $ExcludeDomains
$Splat['ExtendedForestInformation'] = $ExtendedForestInformation
$Splat['ExcludePermissionType'] = $ExcludePermissionType
$Splat['IncludePermissionType'] = $IncludePermissionType
$Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent
$Splat['SkipAdministrative'] = $SkipAdministrative.IsPresent
# $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid)
#void RemoveTrustee(string trustee)
#void RemoveTrustee(System.Security.Principal.IdentityReference identity)
@@ -67,6 +47,59 @@
#void IList[GPPermission].RemoveAt(int index)
#void IList.RemoveAt(int index)
foreach ($Domain in $ForestInformation.Domains) {
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
if ($GPOName) {
$getGPOSplat = @{
Name = $GPOName
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
} elseif ($GPOGuid) {
$getGPOSplat = @{
Guid = $GPOGuid
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
} else {
$getGPOSplat = @{
All = $true
Domain = $Domain
Server = $QueryServer
ErrorAction = 'SilentlyContinue'
}
}
Get-GPO @getGPOSplat | ForEach-Object -Process {
$getPrivPermissionSplat = @{
Principal = $Principal
PrincipalType = $PrincipalType
Accounts = $Accounts
Type = $Type
GPO = $_
SkipWellKnown = $SkipWellKnown.IsPresent
SkipAdministrative = $SkipAdministrative.IsPresent
IncludeOwner = $false
IncludeGPOObject = $true
IncludePermissionType = $IncludePermissionType
ExcludePermissionType = $ExcludePermissionType
ADAdministrativeGroups = $ADAdministrativeGroups
}
[Array] $GPOPermissions = Get-PrivPermission @getPrivPermissionSplat
if ($GPOPermissions.Count -gt 0) {
foreach ($Permission in $GPOPermissions) {
Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission #-IncludeDomains $GPO.DomainName
}
$Count++
if ($Count -eq $LimitProcessing) {
# skipping skips per removed permission not per gpo.
break
}
}
}
}
<#
Get-GPOZaurrPermission @Splat | ForEach-Object -Process {
$GPOPermission = $_
if ($Type -contains 'Unknown') {
@@ -77,7 +110,7 @@
Write-Verbose "Remove-GPOZaurrPermission - Removing permission $($GPOPermission.Permission) for $($GPOPermission.Sid)"
$GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
#$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex)
#$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionItem)
#$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Remove-GPOZaurrPermission - Removing permission $($GPOPermission.Permission) for $($GPOPermission.Sid) with error: $($_.Exception.Message)"
@@ -92,76 +125,19 @@
}
}
if ($Type -contains 'Named') {
<#
if ($PrincipalType -eq 'DistinguishedName') {
} elseif ($PrincipalType -eq 'Sid') {
if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
}
} elseif ($PrincipalType -eq 'Name') {
if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
}
}
if ($NamedObjects -contains $GPOPermission.Sid) {
#Write-Verbose "Remove-GPOZaurrPermission - Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)"
if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)")) {
$GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
# Set-GPPPermission doesn't work on Unknown Accounts
}
$Count++
if ($Count -eq $LimitProcessing) {
# skipping skips per removed permission not per gpo.
break
}
}
#>
}
if ($Type -contains 'NonAdministrative') {
if ($Type -contains 'NotAdministrative') {
}
if ($Type -contains 'Default') {
if ($PrincipalType -eq 'DistinguishedName') {
if ($GPOPermission.DistinguishedName -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
try {
Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)"
$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
}
} elseif ($PrincipalType -eq 'Sid') {
if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
try {
Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)"
$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
}
} elseif ($PrincipalType -eq 'Name') {
if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) {
try {
Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)"
$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex)
$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity)
} catch {
Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)"
}
}
}
Remove-PrivPermission -Principal $Principal -PrincipalType $PrincipalType -GPOPermission $GPOPermission -IncludePermissionType $IncludePermissionType
}
#Set-GPPermission -PermissionLevel None -TargetName $GPOPermission.Sid -Verbose -DomainName $GPOPermission.DomainName -Guid $GPOPermission.GUID #-WhatIf
#Set-GPPermission -PermissionLevel GpoRead -TargetName 'Authenticated Users' -TargetType Group -Verbose -DomainName $Domain -Guid $_.GUID -WhatIf
}
#>
}
End {
}
End {}
}
@@ -0,0 +1,44 @@
function Repair-GPOZaurrPermissionConsistency {
[cmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Default')]
param(
[Parameter(ParameterSetName = 'GPOName')][string] $GPOName,
[Parameter(ParameterSetName = 'GPOGUID')][alias('GUID', 'GPOID')][string] $GPOGuid,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation,
[int] $LimitProcessing = [int32]::MaxValue
)
$ConsistencySplat = @{
Forest = $Forest
IncludeDomains = $IncludeDomains
ExcludeDomains = $ExcludeDomains
ExtendedForestInformation = $ExtendedForestInformation
Verbose = $VerbosePreference
}
if ($GPOName) {
$ConsistencySplat['GPOName'] = $GPOName
} elseif ($GPOGuid) {
$ConsistencySplat['GPOGuid'] = $GPOGUiD
} else {
$ConsistencySplat['Type'] = 'Inconsistent'
}
Get-GPOZaurrPermissionConsistency @ConsistencySplat -IncludeGPOObject | Where-Object {
if ($_.ACLConsistent -eq $false) {
$_
}
} | Select-Object -First $LimitProcessing | ForEach-Object {
#Write-Verbose "Repair-GPOZaurrPermissionConsistency - Repairing GPO consistency $($_.DisplayName) from domain: $($_.DomainName)"
if ($PSCmdlet.ShouldProcess($_.DisplayName, "Reparing GPO permissions consistency in domain $($_.DomainName)")) {
try {
$_.IncludeGPOObject.MakeAclConsistent()
} catch {
$ErrorMessage = $_.Exception.Message
Write-Warning "Repair-GPOZaurrPermissionConsistency - Failed to set consistency: $($ErrorMessage)."
}
}
}
}
+22
View File
@@ -0,0 +1,22 @@
function Set-GPOOwner {
[cmdletBinding()]
param(
[validateset('Administrative', 'Default')][string] $Type = 'Default',
[string] $Principal
)
if ($Type -eq 'Default') {
if ($Principal) {
@{
Action = 'Owner'
Type = 'Default'
Principal = $Principal
}
}
} elseif ($Type -eq 'Administrative') {
@{
Action = 'Owner'
Type = 'Administrative'
Principal = ''
}
}
}
+136 -67
View File
@@ -1,8 +1,53 @@
function Set-GPOZaurrOwner {
<#
.SYNOPSIS
Short description
.DESCRIPTION
Long description
.PARAMETER Type
Unknown - finds unknown Owners and sets them to Administrative (Domain Admins) or chosen principal
NotMatching - find administrative groups only and if sysvol and gpo doesn't match - replace with chosen principal or Domain Admins if not specified
NotAdministrative - combination of Unknown/NotMatching and NotAdministrative - replace with chosen principal or Domain Admins if not specified
All - if Owner is known it checks if it's Administrative, if it sn't it fixes that. If owner is unknown it fixes it
.PARAMETER GPOName
Parameter description
.PARAMETER GPOGuid
Parameter description
.PARAMETER Forest
Parameter description
.PARAMETER ExcludeDomains
Parameter description
.PARAMETER IncludeDomains
Parameter description
.PARAMETER ExtendedForestInformation
Parameter description
.PARAMETER Principal
Parameter description
.PARAMETER SkipSysvol
Parameter description
.PARAMETER LimitProcessing
Parameter description
.EXAMPLE
An example
.NOTES
General notes
#>
[cmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Type')]
param(
[Parameter(ParameterSetName = 'Type', Mandatory)]
[validateset('EmptyOrUnknown', 'NonAdministrative', 'All')][string[]] $Type,
[validateset('Unknown', 'NotAdministrative', 'NotMatching', 'All')][string] $Type,
[Parameter(ParameterSetName = 'Named')][string] $GPOName,
[Parameter(ParameterSetName = 'Named')][alias('GUID', 'GPOID')][string] $GPOGuid,
@@ -27,83 +72,107 @@
[Parameter(ParameterSetName = 'Named')]
[string] $Principal,
[switch] $SkipSysvol,
[Parameter(ParameterSetName = 'Type')]
[Parameter(ParameterSetName = 'Named')]
[int] $LimitProcessing
[int] $LimitProcessing = [int32]::MaxValue
)
Begin {
#Write-Verbose "Set-GPOZaurrOwner - Getting ADAdministrativeGroups"
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
$Count = 0
#Write-Verbose "Set-GPOZaurrOwner - Processing GPO for Type $Type"
}
Process {
if ($Type) {
Get-GPOZaurr -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Verbose:$false | ForEach-Object -Process {
$GPO = $_
if ($Type -contains 'All') {
# Regardless who is the owner it is overwritten
if ($Principal) {
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
} else {
$DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins']
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
$Count++
if ($Count -eq $LimitProcessing) {
break
}
}
}
if ($Type -contains 'NonAdministrative' -and $Type -notcontains 'All') {
if ($GPO.Owner) {
$AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"]
if (-not $AdministrativeGroup) {
if ($Principal) {
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
} else {
$DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins']
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
$Count++
if ($Count -eq $LimitProcessing) {
break
}
}
}
}
}
if ($Type -contains 'EmptyOrUnknown' -and $Type -notcontains 'All') {
if ($null -eq $GPO.Owner) {
if ($Principal) {
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner NULL/$($GPO.OwnerSID) to $Principal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
} else {
$DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins']
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner NULL/$($GPO.OwnerSID) to $DefaultPrincipal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
}
$Count++
if ($Count -eq $LimitProcessing) {
break
}
}
$getGPOZaurrOwnerSplat = @{
IncludeSysvol = -not $SkipSysvol.IsPresent
Forest = $Forest
IncludeDomains = $IncludeDomains
ExcludeDomains = $ExcludeDomains
ExtendedForestInformation = $ExtendedForestInformation
ADAdministrativeGroups = $ADAdministrativeGroups
Verbose = $VerbosePreference
}
if ($GPOName) {
$getGPOZaurrOwnerSplat['GPOName'] = $GPOName
} elseif ($GPOGuid) {
$getGPOZaurrOwnerSplat['GPOGuid'] = $GPOGUiD
}
Get-GPOZaurrOwner @getGPOZaurrOwnerSplat | Where-Object {
if ($_.Owner) {
$AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($_.Owner)"]
} else {
$AdministrativeGroup = $null
}
if (-not $SkipSysvol) {
if ($_.SysvolOwner) {
$AdministrativeGroupSysvol = $ADAdministrativeGroups['ByNetBIOS']["$($_.SysvolOwner)"]
} else {
$AdministrativeGroupSysvol = $null
}
}
} else {
Get-GPOZaurr -GPOName $GPOName -GPOGuid $GPOGUiD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Verbose:$false | ForEach-Object -Process {
$GPO = $_
if ($Principal) {
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $Principal -Verbose:$false -WhatIf:$WhatIfPreference
if ($Type -eq 'NotAdministrative') {
if (-not $AdministrativeGroup -or (-not $AdministrativeGroupSysvol -and -not $SkipSysvol)) {
$_
} else {
$DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins']
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
if ($AdministrativeGroup -ne $AdministrativeGroupSysvol) {
Write-Verbose "Set-GPOZaurrOwner - Detected mismatch GPO: $($_.DisplayName) from domain: $($_.DomainName) - owner $($_.Owner) / sysvol owner $($_.SysvolOwner). Fixing required."
$_
}
}
$Count++
if ($Count -eq $LimitProcessing) {
break
} elseif ($Type -eq 'Unknown') {
if (-not $_.Owner -or (-not $_.SysvolOwner -and -not $SkipSysvol)) {
$_
}
} elseif ($Type -eq 'NotMatching') {
if ($SkipSysvol) {
Write-Verbose "Set-GPOZaurrOwner - Detected mismatch GPO: $($_.DisplayName) from domain: $($_.DomainName) - owner $($_.Owner) / sysvol owner $($_.SysvolOwner). SysVol scanning is disabled. Skipping."
} else {
if ($AdministrativeGroup -ne $AdministrativeGroupSysvol) {
#Write-Verbose "Set-GPOZaurrOwner - Detected mismatch GPO: $($_.DisplayName) from domain: $($_.DomainName) - owner $($_.Owner) / sysvol owner $($_.SysvolOwner). Fixing required."
$_
}
}
} else {
# we run with no type, that means we need to either set it to principal or to Administrative
if ($_.Owner) {
# we check if Principal is not set
$AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($_.Owner)"]
if (-not $SkipSysvol -and $_.SysvolOwner) {
$AdministrativeGroupSysvol = $ADAdministrativeGroups['ByNetBIOS']["$($_.SysvolOwner)"]
if (-not $AdministrativeGroup -or -not $AdministrativeGroupSysvol) {
$_
}
} else {
if (-not $AdministrativeGroup) {
$_
}
}
} else {
$_
}
}
} | Select-Object -First $LimitProcessing | ForEach-Object -Process {
$GPO = $_
if (-not $Principal) {
$DefaultPrincipal = $ADAdministrativeGroups["$($_.DomainName)"]['DomainAdmins']
} else {
$DefaultPrincipal = $Principal
}
if ($Action -eq 'OnlyGPO') {
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) (SID: $($GPO.OwnerSID)) to $DefaultPrincipal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
} elseif ($Action -eq 'OnlyFileSystem') {
if (-not $SkipSysvol) {
Write-Verbose "Set-GPOZaurrOwner - Changing Sysvol Owner GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.SysvolOwner) (SID: $($GPO.SysvolSid)) to $DefaultPrincipal"
Set-FileOwner -JustPath -Path $GPO.SysvolPath -Owner $DefaultPrincipal -Verbose:$true -WhatIf:$WhatIfPreference
}
} else {
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) (SID: $($GPO.OwnerSID)) to $DefaultPrincipal"
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference
if (-not $SkipSysvol) {
Write-Verbose "Set-GPOZaurrOwner - Changing Sysvol Owner GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.SysvolOwner) (SID: $($GPO.SysvolSid)) to $DefaultPrincipal"
Set-FileOwner -JustPath -Path $GPO.SysvolPath -Owner $DefaultPrincipal -Verbose:$true -WhatIf:$WhatIfPreference
}
}
}