mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 20:00:09 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 02dcbdac9d | |||
| 82e0e16019 | |||
| 3821a38b32 | |||
| 7fbb65107c | |||
| 0d12bb9b05 | |||
| cfdd544491 | |||
| 7394c7b5cc | |||
| 9a1e445083 | |||
| 238f84309b | |||
| 7dfe5b0e41 | |||
| 3fce54e75a | |||
| 1241cf3680 |
@@ -0,0 +1,24 @@
|
||||
$GPPermissions = [ordered] @{
|
||||
GpoApply = 'The trustee can apply the GPO; corresponds to the READ and APPLY Group Policy access rights being set to "Allow" for a user.'
|
||||
GpoCustom = 'The trustee has custom permissions for the GPO.'
|
||||
GpoEdit = 'The trustee can read and edit the policy settings for the GPO; corresponds to the READ, WRITE, CREATE CHILD OBJECT, and DELETE CHILD OBJECT Group Policy access rights set to "Allow" for a user.'
|
||||
GpoEditDeleteModifySecurity = 'The trustee can read, edit and delete the permissions for the GPO; corresponds to the Group Policy access rights specified by GpoEdit plus the DELETE, MODIFY PERMISSIONS, and MODIFY OWNER access rights set to "Allow" for a user.'
|
||||
GpoRead = 'The trustee can read the GPO; corresponds to the READ Group Policy access right set to "Allow" for a user.'
|
||||
None = 'This value is reserved for internal use by the Group Policy Windows PowerShell cmdlets.'
|
||||
SomCreateGpo = 'The trustee can create GPOs in the domain. Applies to domains only.'
|
||||
SomCreateStarterGpo = 'The trustee can create Starter GPOs in the domain. Applies to domains only.'
|
||||
SomCreateWmiFilter = 'The trustee can create WMI filters in the domain. Applies to domains only.'
|
||||
SomLink = 'The trustee can link GPOs to the SOM. Applies to sites, domains and OUs.'
|
||||
SomLogging = 'The trustee can generate RSoP logging data for the SOM. Applies to domains and OUs.'
|
||||
SomPlanning = 'The trustee can generate RSoP planning data for the SOM. Applies to domains and OUs.'
|
||||
SomWmiFilterFullControl = 'The trustee has full control over all WMI filters in the domain. Applies to domains only.'
|
||||
StarterGpoCustom = 'The trustee has custom permissions for the Starter GPO.'
|
||||
StarterGpoEdit = 'The trustee can read and edit the administrative template policy settings for the Starter GPO; corresponds to the READ, WRITE, CREATE CHILD OBJECT, and DELETE CHILD OBJECT Group Policy access rights set to "Allow" for a user.'
|
||||
StarterGpoFullControl = 'The trustee has full control for the Starter GPO. Applies to domains only.'
|
||||
StarterGpoRead = 'The trustee can read the Starter GPO; corresponds to the READ Group Policy access right set to "Allow" for a user.'
|
||||
WmiFilterCustom = 'The trustee has custom permissions for the WMI filter.'
|
||||
WmiFilterEdit = 'The trustee can edit the WMI filter.'
|
||||
WmiFilterFullControl = 'The trustee has full control over the WMI filter.'
|
||||
}
|
||||
|
||||
$GPPermissions | Format-Table
|
||||
@@ -0,0 +1,9 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# Backup GPOs
|
||||
$BackupPath = "$Env:UserProfile\Desktop\GPO"
|
||||
$GPOSummary = Backup-GPOZaurr -BackupPath $BackupPath -Verbose -Type Unlinked -BackupDated #-LimitProcessing 1
|
||||
$GPOSummary | Format-Table -AutoSize
|
||||
|
||||
# Confirm GPOs are backed up properly
|
||||
Get-GPOZaurrBackupInformation -BackupFolder $GPOSummary[0].BackupDirectory | Format-Table -a
|
||||
@@ -0,0 +1,5 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# Remove GPOS
|
||||
$BackupPath = "$Env:UserProfile\Desktop\GPO"
|
||||
Remove-GPOZaurr -Type Empty -BackupPath $BackupPath -BackupDated -LimitProcessing 2 -Verbose
|
||||
@@ -0,0 +1,14 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$RestoreFrom = 'C:\Users\przemyslaw.klys\Desktop\GPO\2020-04-12_10_11_24'
|
||||
|
||||
$BackupInformation = Get-GPOZaurrBackupInformation -BackupFolder $RestoreFrom
|
||||
$BackupInformation | Format-Table -a
|
||||
|
||||
# restore all gpos
|
||||
$RestoredGPOs = Restore-GPOZaurr -BackupFolder $RestoreFrom -Verbose
|
||||
$RestoredGPOs | Format-Table -AutoSize
|
||||
|
||||
# restore just one Gpo
|
||||
#$RestoredGPOs = Restore-GPOZaurr -BackupFolder $RestoreFrom -Verbose -DisplayName 'Users | Synced Office 365 Users'
|
||||
#$RestoredGPOs | Format-Table -AutoSize
|
||||
@@ -0,0 +1,12 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$GPOS = Get-GPOZaurr
|
||||
$GPOS | Format-Table -AutoSize
|
||||
|
||||
$GPOS[0] | Format-List
|
||||
|
||||
$GPOs[0].ACL | Format-Table -AutoSize
|
||||
|
||||
$GPOs.Links | Format-Table -AutoSize
|
||||
|
||||
$GPOS | Format-Table -AutoSize Name, WmiFilter, WMIDescription
|
||||
@@ -0,0 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Get-GPOZaurrWMI | Format-Table -AutoSize *
|
||||
@@ -0,0 +1,7 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# By default it deletes WMI filter in $Env:USERDNSDOMAIN if no Forest/IncludeDomains/ExcludeDomains are specified
|
||||
Remove-GPOZaurrWMI -Name 'Test' -WhatIf
|
||||
|
||||
# If we want to remove it from all domains within forest
|
||||
Remove-GPOZaurrWMI -Name 'Test' -Forest 'ad.evotec.xyz' -WhatIf
|
||||
@@ -0,0 +1,10 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# By default it creates WMI filter in $Env:USERDNSDOMAIN if no Forest/IncludeDomains/ExcludeDomains are specified
|
||||
New-GPOZaurrWMI -Query 'select * from Win32_OperatingSystem where Version like "6.0%" and ProductType = "3"' -Name 'Test' -Verbose #-Force
|
||||
|
||||
# If you want to force creation of same filter in all domains of a forest (this overwrites set value)
|
||||
#New-GPOZaurrWMI -Query 'select * from Win32_OperatingSystem where Version like "6.0%" and ProductType = "3"' -Name 'Test' -Verbose -Forest 'ad.evotec.xyz' -WhatIf
|
||||
|
||||
# this will target different forest
|
||||
#New-GPOZaurrWMI -Query 'select * from Win32_OperatingSystem where Version like "6.0%" and ProductType = "3"' -Name 'Test' -Verbose -Forest 'test.evotec.pl' -WhatIf
|
||||
@@ -0,0 +1,5 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$T = Get-GPOZaurrPermission #-SkipWellKnown #-SkipAdministrative # -ExcludePermissionType GpoRead,GpoApply #| Out-HtmlView
|
||||
$T | Format-Table -AutoSize *
|
||||
#$T | Out-HtmlView -ScrollX -Filtering -Online -DisablePaging
|
||||
@@ -0,0 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Remove-GPOZaurrPermission -Verbose -Type Unknown -WhatIf
|
||||
@@ -0,0 +1,13 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$Named = @(
|
||||
'S-1-5-21-853615985-2870445339-3163598659-1105'
|
||||
)
|
||||
|
||||
# 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
|
||||
@@ -0,0 +1,21 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$LImitProcessing = 2
|
||||
|
||||
# check what is there now
|
||||
$GPOs = Get-GPOZaurr #-GPOName 'New Group Policy Object'
|
||||
$GPOs | Format-Table DisplayName, Owner, OwnerSID
|
||||
$Count = 0
|
||||
|
||||
# loop thru all GPOS (or use LimitProcessing)
|
||||
foreach ($GPO in $GPOS) {
|
||||
$Count++
|
||||
Set-GPOZaurrOwner -GPOID $GPO.GUID -Verbose -Principal 'przemyslaw.klys@evotec.pl' #-WhatIf
|
||||
if ($Count -eq $LImitProcessing) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# Confirm what changed
|
||||
$GPOs = Get-GPOZaurr #-GPOName 'New Group Policy Object'
|
||||
$GPOs | Format-Table DisplayName, Owner, OwnerSID
|
||||
@@ -0,0 +1,13 @@
|
||||
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
|
||||
# regardless if current user is still Domain Admin or not
|
||||
|
||||
$GPOs = Get-GPOZaurr #-GPOName 'New Group Policy Object'
|
||||
$GPOs | Format-Table DisplayName, Owner, OwnerSID
|
||||
|
||||
Set-GPOZaurrOwner -Type 'NonAdministrative','EmptyOrUnknown' -Verbose -LimitProcessing 3 #-WhatIf
|
||||
|
||||
$GPOs = Get-GPOZaurr #-GPOName 'New Group Policy Object'
|
||||
$GPOs | Format-Table DisplayName, Owner, OwnerSID
|
||||
@@ -0,0 +1,9 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$GPOS = Get-GPOZaurr -PermissionsOnly
|
||||
# to screen
|
||||
$GPOS | Format-Table -AutoSize
|
||||
# to html
|
||||
#$GPOS | Out-HtmlView
|
||||
# to excel
|
||||
#$GPOS | ConvertTo-Excel -FilePath $Env:UserProfile\Desktop\GPOExport.xlsx -ExcelWorkSheetName 'Permissions' -AutoFit -AutoFilter
|
||||
+21
-114
@@ -1,122 +1,29 @@
|
||||
#
|
||||
# Module manifest for module 'GPOZaurr'
|
||||
#
|
||||
# Generated by: Przemyslaw Klys
|
||||
#
|
||||
# Generated on: 24.02.2020
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'GPOZaurr.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '0.0.4'
|
||||
|
||||
# Supported PSEditions
|
||||
CompatiblePSEditions = 'Desktop'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
|
||||
|
||||
# Author of this module
|
||||
@{
|
||||
AliasesToExport = ''
|
||||
Author = 'Przemyslaw Klys'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Evotec'
|
||||
|
||||
# Copyright statement for this module
|
||||
CompatiblePSEditions = 'Desktop'
|
||||
Copyright = '(c) 2011 - 2020 Przemyslaw Klys @ Evotec. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'Group Policy Eater'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
FunctionsToExport = 'Backup-GPOZaurr', 'Get-GPOZaurr', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrWMI', 'New-GPOZaurrWMI', 'Remove-GPOZaurr', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOZaurrOwner', 'Set-GPOZaurrWMI'
|
||||
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
|
||||
ModuleVersion = '0.0.10'
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# CLRVersion = ''
|
||||
|
||||
# Processor architecture (None, X86, Amd64) required by this module
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
RequiredModules = @(@{ModuleName = 'PSSharedGoods'; GUID = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'; ModuleVersion = '0.0.123'; })
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
# FormatsToProcess = @()
|
||||
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
# NestedModules = @()
|
||||
|
||||
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||
FunctionsToExport = 'Get-GPOZaurr', 'Get-GPOZaurrPassword', 'Save-GPOZaurrFiles'
|
||||
|
||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
# VariablesToExport = @()
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
AliasesToExport = @()
|
||||
|
||||
# DSC resources to export from this module
|
||||
# DscResourcesToExport = @()
|
||||
|
||||
# List of all modules packaged with this module
|
||||
# ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
# FileList = @()
|
||||
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
|
||||
PrivateData = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
# Tags applied to this module. These help with module discovery in online galleries.
|
||||
Tags = 'Windows', 'ActiveDirectory', 'GPO'
|
||||
|
||||
# A URL to the license for this module.
|
||||
# LicenseUri = ''
|
||||
|
||||
# A URL to the main website for this project.
|
||||
ProjectUri = 'https://github.com/EvotecIT/GPOZaurr'
|
||||
|
||||
# A URL to an icon representing this module.
|
||||
# IconUri = ''
|
||||
|
||||
# ReleaseNotes of this module
|
||||
# ReleaseNotes = ''
|
||||
|
||||
} # End of PSData hashtable
|
||||
|
||||
} # End of PrivateData hashtable
|
||||
|
||||
# HelpInfo URI of this module
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
||||
Tags = 'Windows', 'ActiveDirectory', 'GPO'
|
||||
ProjectUri = 'https://github.com/EvotecIT/GPOZaurr'
|
||||
ExternalModuleDependencies = 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility'
|
||||
}
|
||||
}
|
||||
RequiredModules = @{
|
||||
ModuleVersion = '0.0.134'
|
||||
ModuleName = 'PSSharedGoods'
|
||||
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
|
||||
}, @{
|
||||
ModuleVersion = '0.0.47'
|
||||
ModuleName = 'ADEssentials'
|
||||
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
|
||||
}, 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility'
|
||||
RootModule = 'GPOZaurr.psm1'
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
|
||||
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
|
||||
+99
-36
@@ -1,7 +1,9 @@
|
||||
function Get-XMLGPO {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[XML] $XMLContent
|
||||
[XML] $XMLContent,
|
||||
[Microsoft.GroupPolicy.Gpo] $GPO,
|
||||
[switch] $PermissionsOnly
|
||||
)
|
||||
if ($XMLContent.GPO.LinksTo) {
|
||||
$Linked = $true
|
||||
@@ -27,48 +29,109 @@
|
||||
$Enabled = 'Enabled'
|
||||
} elseif ($UserEnabled -eq $false -and $ComputerEnabled -eq $false) {
|
||||
$Enabled = 'All settings disabled'
|
||||
}elseif ($UserEnabled -eq $true -and $ComputerEnabled -eq $false) {
|
||||
} elseif ($UserEnabled -eq $true -and $ComputerEnabled -eq $false) {
|
||||
$Enabled = 'Computer configuration settings disabled'
|
||||
}elseif ($UserEnabled -eq $false -and $ComputerEnabled -eq $true) {
|
||||
} elseif ($UserEnabled -eq $false -and $ComputerEnabled -eq $true) {
|
||||
$Enabled = 'User configuration settings disabled'
|
||||
}
|
||||
|
||||
[PsCustomObject] @{
|
||||
'Name' = $XMLContent.GPO.Name
|
||||
'Domain' = $XMLContent.GPO.Identifier.Domain.'#text'
|
||||
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText
|
||||
'Linked' = $Linked
|
||||
'LinksCount' = $LinksCount
|
||||
'Enabled' = $Enabled
|
||||
'ComputerEnabled' = $ComputerEnabled
|
||||
'UserEnabled' = $UserEnabled
|
||||
'ComputerSettingsAvailable' = if ($null -eq $XMLContent.GPO.Computer.ExtensionData) { $false } else { $true }
|
||||
'UserSettingsAvailable' = if ($null -eq $XMLContent.GPO.User.ExtensionData) { $false } else { $true }
|
||||
'ComputerSettingsStatus' = if ($XMLContent.GPO.Computer.VersionDirectory -eq 0 -and $XMLContent.GPO.Computer.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
'ComputerSetttingsVersionIdentical' = if ($XMLContent.GPO.Computer.VersionDirectory -eq $XMLContent.GPO.Computer.VersionSysvol) { $true } else { $false }
|
||||
'ComputerSettings' = $XMLContent.GPO.Computer.ExtensionData.Extension
|
||||
'UserSettingsStatus' = if ($XMLContent.GPO.User.VersionDirectory -eq 0 -and $XMLContent.GPO.User.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
'UserSettingsVersionIdentical' = if ($XMLContent.GPO.User.VersionDirectory -eq $XMLContent.GPO.User.VersionSysvol) { $true } else { $false }
|
||||
'UserSettings' = $XMLContent.GPO.User.ExtensionData.Extension
|
||||
|
||||
'CreationTime' = [DateTime] $XMLContent.GPO.CreatedTime
|
||||
'ModificationTime' = [DateTime] $XMLContent.GPO.ModifiedTime
|
||||
'ReadTime' = [DateTime] $XMLContent.GPO.ReadTime
|
||||
|
||||
'WMIFilter' = $GPO.WmiFilter.name
|
||||
'WMIFilterDescription' = $GPO.WmiFilter.Description
|
||||
'Path' = $GPO.Path
|
||||
#'SDDL' = if ($Splitter -ne '') { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' -join $Splitter } else { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' }
|
||||
'ACL' = $XMLContent.GPO.SecurityDescriptor.Permissions.TrusteePermissions | ForEach-Object -Process {
|
||||
[PsCustomObject] @{
|
||||
'User' = $_.trustee.name.'#Text'
|
||||
'Permission Type' = $_.type.PermissionType
|
||||
'Inherited' = $_.Inherited
|
||||
'Permissions' = $_.Standard.GPOGroupedAccessEnum
|
||||
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'
|
||||
#'SidType' = if (($XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text').Length -le 10) { 'WellKnown' } else { 'Other' }
|
||||
'PermissionType' = 'Allow'
|
||||
'Inherited' = $false
|
||||
'Permissions' = 'Owner'
|
||||
}
|
||||
$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'
|
||||
#'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
|
||||
}
|
||||
}
|
||||
}
|
||||
'Links' = $XMLContent.GPO.LinksTo #| Select-Object -ExpandProperty SOMPath
|
||||
} else {
|
||||
[PsCustomObject] @{
|
||||
'DisplayName' = $XMLContent.GPO.Name
|
||||
'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text'
|
||||
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText
|
||||
'Linked' = $Linked
|
||||
'LinksCount' = $LinksCount
|
||||
'Enabled' = $Enabled
|
||||
'ComputerEnabled' = $ComputerEnabled
|
||||
'UserEnabled' = $UserEnabled
|
||||
'ComputerSettingsAvailable' = if ($null -eq $XMLContent.GPO.Computer.ExtensionData) { $false } else { $true }
|
||||
'UserSettingsAvailable' = if ($null -eq $XMLContent.GPO.User.ExtensionData) { $false } else { $true }
|
||||
'ComputerSettingsStatus' = if ($XMLContent.GPO.Computer.VersionDirectory -eq 0 -and $XMLContent.GPO.Computer.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
'ComputerSetttingsVersionIdentical' = if ($XMLContent.GPO.Computer.VersionDirectory -eq $XMLContent.GPO.Computer.VersionSysvol) { $true } else { $false }
|
||||
'ComputerSettings' = $XMLContent.GPO.Computer.ExtensionData.Extension
|
||||
'UserSettingsStatus' = if ($XMLContent.GPO.User.VersionDirectory -eq 0 -and $XMLContent.GPO.User.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
'UserSettingsVersionIdentical' = if ($XMLContent.GPO.User.VersionDirectory -eq $XMLContent.GPO.User.VersionSysvol) { $true } else { $false }
|
||||
'UserSettings' = $XMLContent.GPO.User.ExtensionData.Extension
|
||||
|
||||
'CreationTime' = [DateTime] $XMLContent.GPO.CreatedTime
|
||||
'ModificationTime' = [DateTime] $XMLContent.GPO.ModifiedTime
|
||||
'ReadTime' = [DateTime] $XMLContent.GPO.ReadTime
|
||||
|
||||
'WMIFilter' = $GPO.WmiFilter.name
|
||||
'WMIFilterDescription' = $GPO.WmiFilter.Description
|
||||
'DistinguishedName' = $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'
|
||||
'ACL' = @(
|
||||
[PsCustomObject] @{
|
||||
'Name' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text'
|
||||
'Sid' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text'
|
||||
'PermissionType' = 'Allow'
|
||||
'Inherited' = $false
|
||||
'Permissions' = 'Owner'
|
||||
}
|
||||
$XMLContent.GPO.SecurityDescriptor.Permissions.TrusteePermissions | ForEach-Object -Process {
|
||||
if ($_) {
|
||||
[PsCustomObject] @{
|
||||
'Name' = $_.trustee.name.'#Text'
|
||||
'Sid' = $_.trustee.SID.'#Text'
|
||||
'PermissionType' = $_.type.PermissionType
|
||||
'Inherited' = if ($_.Inherited -eq 'false') { $false } else { $true }
|
||||
'Permissions' = $_.Standard.GPOGroupedAccessEnum
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
'Auditing' = if ($XMLContent.GPO.SecurityDescriptor.AuditingPresent.'#text' -eq 'true') { $true } else { $false }
|
||||
'Links' = $XMLContent.GPO.LinksTo | ForEach-Object -Process {
|
||||
if ($_) {
|
||||
[PSCustomObject] @{
|
||||
CanonicalName = $_.SOMPath
|
||||
Enabled = $_.Enabled
|
||||
NoOverride = $_.NoOverride
|
||||
}
|
||||
}
|
||||
}
|
||||
<#
|
||||
SOMName SOMPath Enabled NoOverride
|
||||
------- ------- ------- ----------
|
||||
ad ad.evotec.xyz true false
|
||||
#>
|
||||
|
||||
#| Select-Object -ExpandProperty SOMPath
|
||||
|
||||
}
|
||||
}
|
||||
#break
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
function New-ADForestDrives {
|
||||
[cmdletbinding()]
|
||||
param(
|
||||
[string] $ForestName,
|
||||
[string] $ObjectDN
|
||||
)
|
||||
if (-not $Global:ADDrivesMapped) {
|
||||
if ($ForestName) {
|
||||
$Forest = Get-ADForest -Identity $ForestName
|
||||
} else {
|
||||
$Forest = Get-ADForest
|
||||
}
|
||||
if ($ObjectDN) {
|
||||
# This doesn't work because no Domain and no $Server
|
||||
$DNConverted = (ConvertFrom-Distinguishedname -DistinguishedName $ObjectDN -ToDC) -replace '=' -replace ','
|
||||
if (-not(Get-PSDrive -Name $DNConverted -ErrorAction SilentlyContinue)) {
|
||||
try {
|
||||
|
||||
if ($Server) {
|
||||
$null = New-PSDrive -Name $DNConverted -Root '' -PsProvider ActiveDirectory -Server $Server.Hostname[0] -Scope Global -WhatIf:$false
|
||||
Write-Verbose "New-ADForestDrives - Mapped drive $Domain / $($Server.Hostname[0])"
|
||||
} else {
|
||||
$null = New-PSDrive -Name $DNConverted -Root '' -PsProvider ActiveDirectory -Server $Domain -Scope Global -WhatIf:$false
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "New-ADForestDrives - Couldn't map new AD psdrive for $Domain / $($Server.Hostname[0])"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($Domain in $Forest.Domains) {
|
||||
try {
|
||||
$Server = Get-ADDomainController -Discover -DomainName $Domain
|
||||
$DomainInformation = Get-ADDomain -Server $Server.Hostname[0]
|
||||
} catch {
|
||||
Write-Warning "New-ADForestDrives - Can't process domain $Domain - $($_.Exception.Message)"
|
||||
continue
|
||||
}
|
||||
$ObjectDN = $DomainInformation.DistinguishedName
|
||||
$DNConverted = (ConvertFrom-Distinguishedname -DistinguishedName $ObjectDN -ToDC) -replace '=' -replace ','
|
||||
if (-not(Get-PSDrive -Name $DNConverted -ErrorAction SilentlyContinue)) {
|
||||
try {
|
||||
if ($Server) {
|
||||
$null = New-PSDrive -Name $DNConverted -Root '' -PsProvider ActiveDirectory -Server $Server.Hostname[0] -Scope Global -WhatIf:$false
|
||||
Write-Verbose "New-ADForestDrives - Mapped drive $Domain / $Server"
|
||||
} else {
|
||||
$null = New-PSDrive -Name $DNConverted -Root '' -PsProvider ActiveDirectory -Server $Domain -Scope Global -WhatIf:$false
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "New-ADForestDrives - Couldn't map new AD psdrive for $Domain / $Server $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$Global:ADDrivesMapped = $true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
function Backup-GPOZaurr {
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[int] $LimitProcessing,
|
||||
[validateset('All', 'Empty', 'Unlinked')][string[]] $Type = 'All',
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
[string[]] $GPOPath,
|
||||
[string] $BackupPath,
|
||||
[switch] $BackupDated
|
||||
)
|
||||
Begin {
|
||||
if ($BackupDated) {
|
||||
$BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))"
|
||||
} else {
|
||||
$BackupFinalPath = $BackupPath
|
||||
}
|
||||
Write-Verbose "Backup-GPOZaurr - Backing up to $BackupFinalPath"
|
||||
$null = New-Item -ItemType Directory -Path $BackupFinalPath -Force
|
||||
$Count = 0
|
||||
}
|
||||
Process {
|
||||
Get-GPOZaurr -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -GPOPath $GPOPath | ForEach-Object {
|
||||
if ($Type -contains 'All') {
|
||||
Write-Verbose "Backup-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName)"
|
||||
$Count++
|
||||
try {
|
||||
$BackupInfo = Backup-GPO -Guid $_.GUID -Domain $_.DomainName -Path $BackupFinalPath -ErrorAction Stop #-Server $QueryServer
|
||||
$BackupInfo
|
||||
} catch {
|
||||
Write-Warning "Backup-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
if ($LimitProcessing -eq $Count) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($Type -notcontains 'All' -and $Type -contains 'Empty') {
|
||||
if ($_.ComputerSettingsAvailable -eq $false -and $_.UserSettingsAvailable -eq $false) {
|
||||
Write-Verbose "Backup-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName)"
|
||||
$Count++
|
||||
try {
|
||||
$BackupInfo = Backup-GPO -Guid $_.GUID -Domain $_.DomainName -Path $BackupFinalPath -ErrorAction Stop #-Server $QueryServer
|
||||
$BackupInfo
|
||||
} catch {
|
||||
Write-Warning "Backup-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
if ($LimitProcessing -eq $Count) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -notcontains 'All' -and $Type -contains 'Unlinked') {
|
||||
if ($_.Linked -eq $false) {
|
||||
Write-Verbose "Backup-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName)"
|
||||
$Count++
|
||||
try {
|
||||
$BackupInfo = Backup-GPO -Guid $_.GUID -Domain $_.DomainName -Path $BackupFinalPath -ErrorAction Stop #-Server $QueryServer
|
||||
$BackupInfo
|
||||
} catch {
|
||||
Write-Warning "Backup-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
if ($LimitProcessing -eq $Count) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End {
|
||||
|
||||
}
|
||||
}
|
||||
+58
-20
@@ -1,32 +1,70 @@
|
||||
function Get-GPOZaurr {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[string] $GPOName,
|
||||
[alias('GUID', 'GPOID')][string] $GPOGuid,
|
||||
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
[string[]] $GPOPath
|
||||
)
|
||||
if (-not $GPOPath) {
|
||||
if (-not $ExtendedForestInformation) {
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains
|
||||
} else {
|
||||
$ForestInformation = $ExtendedForestInformation
|
||||
}
|
||||
[string[]] $GPOPath,
|
||||
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
Get-GPO -All -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain | ForEach-Object {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain
|
||||
Get-XMLGPO -XMLContent $XMLContent
|
||||
}
|
||||
[switch] $PermissionsOnly,
|
||||
[switch] $Limited
|
||||
)
|
||||
Begin {
|
||||
if (-not $GPOPath) {
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
}
|
||||
} else {
|
||||
foreach ($Path in $GPOPath) {
|
||||
Get-ChildItem -LiteralPath $Path -Recurse -Filter *.xml | ForEach-Object {
|
||||
$XMLContent = [XML]::new()
|
||||
$XMLContent.Load($_.FullName)
|
||||
Get-XMLGPO -XMLContent $XMLContent
|
||||
}
|
||||
Process {
|
||||
if (-not $GPOPath) {
|
||||
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 {
|
||||
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
if (-not $Limited) {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain
|
||||
Get-XMLGPO -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent
|
||||
} else {
|
||||
$_
|
||||
}
|
||||
}
|
||||
} elseif ($GPOGuid) {
|
||||
Get-GPO -Guid $GPOGuid -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
if (-not $Limited) {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain
|
||||
Get-XMLGPO -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent
|
||||
} else {
|
||||
$_
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Get-GPO -All -Server $QueryServer -Domain $Domain -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
if (-not $Limited) {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain
|
||||
Get-XMLGPO -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent
|
||||
} else {
|
||||
$_
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($Path in $GPOPath) {
|
||||
Get-ChildItem -LiteralPath $Path -Recurse -Filter *.xml | ForEach-Object {
|
||||
$XMLContent = [XML]::new()
|
||||
$XMLContent.Load($_.FullName)
|
||||
Get-XMLGPO -XMLContent $XMLContent -PermissionsOnly:$PermissionsOnly.IsPresent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
function Get-GPOZaurrBackupInformation {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[string[]] $BackupFolder
|
||||
)
|
||||
Begin {
|
||||
|
||||
}
|
||||
Process {
|
||||
foreach ($Folder in $BackupFolder) {
|
||||
if ($Folder) {
|
||||
if ((Test-Path -LiteralPath "$Folder\manifest.xml")) {
|
||||
[xml] $Xml = Get-Content -LiteralPath "$Folder\manifest.xml"
|
||||
$Xml.Backups.BackupInst | ForEach-Object {
|
||||
[PSCustomObject] @{
|
||||
DisplayName = $_.GPODisplayName.'#cdata-section'
|
||||
DomainName = $_.GPODomain.'#cdata-section'
|
||||
Guid = $_.GPOGUid.'#cdata-section'
|
||||
DomainGuid = $_.GPODomainGuid.'#cdata-section'
|
||||
DomainController = $_.GPODomainController.'#cdata-section'
|
||||
BackupTime = $_.BackupTime.'#cdata-section'
|
||||
ID = $_.ID.'#cdata-section'
|
||||
Comment = $_.Comment.'#cdata-section'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Get-GPOZaurrBackupInformation - No backup information available"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
function Get-GPOZaurrPermission {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[string[]]$NamedObjects,
|
||||
[switch] $SkipWellKnown,
|
||||
[switch] $SkipAdministrative,
|
||||
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
|
||||
[alias('Unknown', 'All')][string[]] $Type = 'All',
|
||||
[switch] $IncludeOwner,
|
||||
[Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
|
||||
[Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType,
|
||||
[switch] $IncludeGPOObject
|
||||
)
|
||||
Begin {
|
||||
# if ($Type -contains 'NonAdministrative') {
|
||||
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
#}
|
||||
#$Count = 0
|
||||
}
|
||||
Process {
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
|
||||
Get-GPO -All -Domain $Domain -Server $QueryServer | ForEach-Object -Process {
|
||||
$GPO = $_
|
||||
Write-Verbose "Get-GPOZaurrPermission - Processing $($GPO.DisplayName) from $($GPO.DomainName)"
|
||||
$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) {
|
||||
if ($GPOPermission.Trustee.SidType -eq 'WellKnownGroup') {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($SkipAdministrative.IsPresent) {
|
||||
$IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value]
|
||||
if ($IsAdministrative) {
|
||||
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 ($IncludeGPOObject) {
|
||||
$ReturnObject.GPOObject = $GPO
|
||||
$ReturnObject.GPOSecurity = $SecurityRights
|
||||
}
|
||||
[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 {
|
||||
$DomainOwner = $GPO.Owner
|
||||
$DomainUserName = ''
|
||||
$SID = ''
|
||||
$SIDType = ''
|
||||
$DistinguishedName = ''
|
||||
}
|
||||
$ReturnObject = [ordered] @{
|
||||
DisplayName = $GPO.DisplayName # : ALL | Enable RDP
|
||||
GUID = $GPO.GUID
|
||||
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 ($IncludeGPOObject) {
|
||||
$ReturnObject.GPOObject = $GPO
|
||||
$ReturnObject.GPOSecurity = $SecurityRights
|
||||
}
|
||||
[PSCustomObject] $ReturnObject
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
function Get-GPOZaurrWMI {
|
||||
[cmdletBinding()]
|
||||
Param(
|
||||
[Guid[]] $Guid,
|
||||
[string[]] $Name,
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
$wmiFilterAttr = "msWMI-Name", "msWMI-Parm1", "msWMI-Parm2", "msWMI-Author", "msWMI-ID", 'CanonicalName', 'Created', 'Modified'
|
||||
|
||||
$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'
|
||||
}
|
||||
}
|
||||
} 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)"
|
||||
}
|
||||
}
|
||||
} 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)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<#
|
||||
CanonicalName : ad.evotec.xyz/System/WMIPolicy/SOM/{E988C890-BDBC-4946-87B5-BF70F39F4686}
|
||||
CN : {E988C890-BDBC-4946-87B5-BF70F39F4686}
|
||||
Created : 08.04.2020 19:04:06
|
||||
createTimeStamp : 08.04.2020 19:04:06
|
||||
Deleted :
|
||||
Description :
|
||||
DisplayName :
|
||||
DistinguishedName : CN={E988C890-BDBC-4946-87B5-BF70F39F4686},CN=SOM,CN=WMIPolicy,CN=System,DC=ad,DC=evotec,DC=xyz
|
||||
dSCorePropagationData : {01.01.1601 01:00:00}
|
||||
instanceType : 4
|
||||
isDeleted :
|
||||
LastKnownParent :
|
||||
Modified : 08.04.2020 19:04:06
|
||||
modifyTimeStamp : 08.04.2020 19:04:06
|
||||
msWMI-Author : przemyslaw.klys@evotec.pl
|
||||
msWMI-ChangeDate : 20200408170406.280000-000
|
||||
msWMI-CreationDate : 20200408170406.280000-000
|
||||
msWMI-ID : {E988C890-BDBC-4946-87B5-BF70F39F4686}
|
||||
msWMI-Name : Virtual Machines
|
||||
msWMI-Parm1 : Oh my description
|
||||
msWMI-Parm2 : 1;3;10;66;WQL;root\CIMv2;SELECT * FROM Win32_ComputerSystem WHERE Model = "Virtual Machine";
|
||||
Name : {E988C890-BDBC-4946-87B5-BF70F39F4686}
|
||||
nTSecurityDescriptor : System.DirectoryServices.ActiveDirectorySecurity
|
||||
ObjectCategory : CN=ms-WMI-Som,CN=Schema,CN=Configuration,DC=ad,DC=evotec,DC=xyz
|
||||
ObjectClass : msWMI-Som
|
||||
ObjectGUID : c1ee708d-7a67-46e2-b13f-d11a573d2597
|
||||
ProtectedFromAccidentalDeletion : False
|
||||
sDRightsEffective : 15
|
||||
showInAdvancedViewOnly : True
|
||||
uSNChanged : 12785589
|
||||
uSNCreated : 12785589
|
||||
whenChanged : 08.04.2020 19:04:06
|
||||
whenCreated : 08.04.2020 19:04:06
|
||||
#>
|
||||
@@ -0,0 +1,81 @@
|
||||
function New-GPOZaurrWMI {
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[parameter(Mandatory)][string] $Name,
|
||||
[string] $Description = ' ',
|
||||
[parameter(Mandatory)][string] $Query,
|
||||
[switch] $SkipQueryCheck,
|
||||
[switch] $Force,
|
||||
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
if (-not $Forest -and -not $ExcludeDomains -and -not $IncludeDomains -and -not $ExtendedForestInformation) {
|
||||
$IncludeDomains = $Env:USERDNSDOMAIN
|
||||
}
|
||||
|
||||
if (-not $SkipQueryCheck) {
|
||||
try {
|
||||
$null = Get-CimInstance -Query $Query -ErrorAction Stop -Verbose:$false
|
||||
} catch {
|
||||
Write-Warning "New-GPOZaurrWMI - Query error $($_.Exception.Message). Terminating."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
|
||||
$DomainInformation = Get-ADDomain -Server $QueryServer
|
||||
$defaultNamingContext = $DomainInformation.DistinguishedName
|
||||
#$defaultNamingContext = (Get-ADRootDSE).defaultnamingcontext
|
||||
[string] $Author = (([ADSI]"LDAP://<SID=$([System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value)>").UserPrincipalName).ToString()
|
||||
[string] $GUID = "{" + ([System.Guid]::NewGuid()) + "}"
|
||||
|
||||
[string] $DistinguishedName = -join ("CN=", $GUID, ",CN=SOM,CN=WMIPolicy,CN=System,", $defaultNamingContext)
|
||||
$CurrentTime = (Get-Date).ToUniversalTime()
|
||||
[string] $CurrentDate = -join (
|
||||
($CurrentTime.Year).ToString("0000"),
|
||||
($CurrentTime.Month).ToString("00"),
|
||||
($CurrentTime.Day).ToString("00"),
|
||||
($CurrentTime.Hour).ToString("00"),
|
||||
($CurrentTime.Minute).ToString("00"),
|
||||
($CurrentTime.Second).ToString("00"),
|
||||
".",
|
||||
($CurrentTime.Millisecond * 1000).ToString("000000"),
|
||||
"-000"
|
||||
)
|
||||
|
||||
[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 , ";")
|
||||
$OtherAttributes = @{
|
||||
"msWMI-Name" = $Name
|
||||
"msWMI-Parm1" = $Description
|
||||
"msWMI-Parm2" = $WMIParm2
|
||||
"msWMI-Author" = $Author
|
||||
"msWMI-ID" = $GUID
|
||||
"instanceType" = 4
|
||||
"showInAdvancedViewOnly" = "TRUE"
|
||||
"distinguishedname" = $DistinguishedName
|
||||
"msWMI-ChangeDate" = $CurrentDate
|
||||
"msWMI-CreationDate" = $CurrentDate
|
||||
}
|
||||
$WMIPath = -join ("CN=SOM,CN=WMIPolicy,CN=System,", $defaultNamingContext)
|
||||
|
||||
try {
|
||||
Write-Verbose "New-GPOZaurrWMI - Creating WMI filter $Name in $Domain"
|
||||
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
|
||||
}
|
||||
} else {
|
||||
foreach ($_ in $ExistingWmiFilter) {
|
||||
Write-Warning "New-GPOZaurrWMI - Skipping creation of GPO because name: $($_.DisplayName) guid: $($_.ID) for $($_.DomainName) already exists."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
function Remove-GPOZaurr {
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[parameter(Mandatory)][validateset('Empty', 'Unlinked')][string[]] $Type,
|
||||
[int] $LimitProcessing,
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
[string[]] $GPOPath,
|
||||
[string] $BackupPath,
|
||||
[switch] $BackupDated
|
||||
)
|
||||
Begin {
|
||||
if ($BackupPath) {
|
||||
$BackupRequired = $true
|
||||
if ($BackupDated) {
|
||||
$BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))"
|
||||
} else {
|
||||
$BackupFinalPath = $BackupPath
|
||||
}
|
||||
Write-Verbose "Remove-GPOZaurr - Backing up to $BackupFinalPath"
|
||||
$null = New-Item -ItemType Directory -Path $BackupFinalPath -Force
|
||||
} else {
|
||||
$BackupRequired = $false
|
||||
}
|
||||
$Count = 0
|
||||
}
|
||||
Process {
|
||||
Get-GPOZaurr -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -GPOPath $GPOPath | ForEach-Object {
|
||||
if ($Type -contains 'Empty') {
|
||||
if ($_.ComputerSettingsAvailable -eq $false -and $_.UserSettingsAvailable -eq $false) {
|
||||
if ($BackupRequired) {
|
||||
try {
|
||||
Write-Verbose "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName)"
|
||||
$BackupInfo = Backup-GPO -Guid $_.Guid -Domain $_.DomainName -Path $BackupFinalPath -ErrorAction Stop #-Server $QueryServer
|
||||
$BackupInfo
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)"
|
||||
|
||||
}
|
||||
}
|
||||
if (($BackupRequired -and $BackupInfo) -or (-not $BackupRequired)) {
|
||||
try {
|
||||
Write-Verbose "Remove-GPOZaurr - Removing GPO $($_.DisplayName) from $($_.DomainName)"
|
||||
Remove-GPO -Domain $_.DomainName -Guid $_.Guid -ErrorAction Stop #-Server $QueryServer
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurr - Removing GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
$Count++
|
||||
if ($LimitProcessing -eq $Count) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'Unlinked') {
|
||||
if ($_.Linked -eq $false) {
|
||||
if ($BackupRequired) {
|
||||
try {
|
||||
Write-Verbose "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName)"
|
||||
$BackupInfo = Backup-GPO -Guid $_.Guid -Domain $_.DomainName -Path $BackupFinalPath -ErrorAction Stop #-Server $QueryServer
|
||||
$BackupInfo
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
if (($BackupRequired -and $BackupInfo) -or (-not $BackupRequired)) {
|
||||
try {
|
||||
Write-Verbose "Remove-GPOZaurr - Removing GPO $($_.DisplayName) from $($_.DomainName)"
|
||||
Remove-GPO -Domain $_.DomainName -Guid $_.Guid -ErrorAction Stop #-Server $QueryServer
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurr - Removing GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
$Count++
|
||||
if ($LimitProcessing -eq $Count) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
function Remove-GPOZaurrPermission {
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[alias('Unknown', 'Named')][string[]] $Type,
|
||||
[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,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
|
||||
[int] $LimitProcessing
|
||||
)
|
||||
Begin {
|
||||
$Count = 0
|
||||
}
|
||||
Process {
|
||||
if ($Type -contains 'Named' -and $NamedObjects.Count -eq 0) {
|
||||
Write-Warning "Remove-GPOZaurrPermission - When using type Named you need to provide names to remove. Terminating."
|
||||
return
|
||||
}
|
||||
Get-GPOZaurrPermission -IncludeGPOObject -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -ExcludePermissionType $ExcludePermissionType -IncludePermissionType $IncludePermissionType -SkipWellKnown:$SkipWellKnown.IsPresent -SkipAdministrative:$SkipAdministrative.IsPresent | ForEach-Object -Process {
|
||||
$GPOPermission = $_
|
||||
if ($Type -contains 'Unknown') {
|
||||
if ($GPOPermission.SidType -eq 'Unknown') {
|
||||
#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 'Named') {
|
||||
|
||||
if ($Named -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
#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 {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
function Remove-GPOZaurrWMI {
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
Param (
|
||||
[Guid[]] $Guid,
|
||||
[string[]] $Name,
|
||||
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
if (-not $Forest -and -not $ExcludeDomains -and -not $IncludeDomains -and -not $ExtendedForestInformation) {
|
||||
$IncludeDomains = $Env:USERDNSDOMAIN
|
||||
}
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
|
||||
[Array] $Objects = @(
|
||||
if ($Guid) {
|
||||
Get-GPOZaurrWMI -Guid $Guid -ExtendedForestInformation $ForestInformation -IncludeDomains $Domain
|
||||
}
|
||||
if ($Name) {
|
||||
Get-GPOZaurrWMI -Name $Name -ExtendedForestInformation $ForestInformation -IncludeDomains $Domain
|
||||
}
|
||||
)
|
||||
$Objects | ForEach-Object -Process {
|
||||
if ($_.DistinguishedName) {
|
||||
Write-Verbose "Remove-GPOZaurrWMI - Removing WMI Filter $($_.DistinguishedName)"
|
||||
Remove-ADObject $_.DistinguishedName -Confirm:$false -Server $QueryServer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
function Restore-GPOZaurr {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[parameter(Mandatory)][string] $BackupFolder,
|
||||
[alias('Name')][string] $DisplayName,
|
||||
[string] $NewDisplayName,
|
||||
[string] $Domain,
|
||||
[switch] $SkipBackupSummary
|
||||
)
|
||||
if ($BackupFolder) {
|
||||
if (Test-Path -LiteralPath $BackupFolder) {
|
||||
if ($DisplayName) {
|
||||
if (-not $SkipBackupSummary) {
|
||||
$BackupSummary = Get-GPOZaurrBackupInformation -BackupFolder $BackupFolder
|
||||
if ($Domain) {
|
||||
[Array] $FoundGPO = $BackupSummary | Where-Object { $_.DisplayName -eq $DisplayName -and $_.DomainName -eq $Domain }
|
||||
} else {
|
||||
[Array] $FoundGPO = $BackupSummary | Where-Object { $_.DisplayName -eq $DisplayName }
|
||||
}
|
||||
foreach ($GPO in $FoundGPO) {
|
||||
if ($NewDisplayName) {
|
||||
Import-GPO -Path $BackupFolder -BackupID $GPO.ID -Domain $GPO.Domain -TargetName $NewDisplayName -CreateIfNeeded
|
||||
} else {
|
||||
Write-Verbose "Restore-GPOZaurr - Restoring GPO $($GPO.DisplayName) from $($GPO.DomainName) / BackupId: $($GPO.ID)"
|
||||
try {
|
||||
Restore-GPO -Path $BackupFolder -BackupID $GPO.ID -Domain $GPO.DomainName
|
||||
} catch {
|
||||
Write-Warning "Restore-GPOZaurr - Restoring GPO $($GPO.DisplayName) from $($GPO.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($Domain) {
|
||||
Write-Verbose "Restore-GPOZaurr - Restoring GPO $($Name) from $($Domain)"
|
||||
try {
|
||||
Restore-GPO -Path $BackupFolder -Name $Name -Domain $Domain
|
||||
} catch {
|
||||
Write-Warning "Restore-GPOZaurr - Restoring GPO $($Name) from $($Domain) failed: $($_.Exception.Message)"
|
||||
}
|
||||
} else {
|
||||
Write-Verbose "Restore-GPOZaurr - Restoring GPO $($Name)"
|
||||
try {
|
||||
Restore-GPO -Path $BackupFolder -Name $Name
|
||||
} catch {
|
||||
Write-Warning "Restore-GPOZaurr - Restoring GPO $($Name) failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$BackupSummary = Get-GPOZaurrBackupInformation -BackupFolder $BackupFolder
|
||||
foreach ($GPO in $BackupSummary) {
|
||||
Write-Verbose "Restore-GPOZaurr - Restoring GPO $($GPO.DisplayName) from $($GPO.DomainName) / BackupId: $($GPO.ID)"
|
||||
try {
|
||||
Restore-GPO -Path $BackupFolder -Domain $GPO.DomainName -BackupId $GPO.ID
|
||||
} catch {
|
||||
Write-Warning "Restore-GPOZaurr - Restoring GPO $($GPO.DisplayName) from $($GPO.DomainName) failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Restore-GPOZaurr - BackupFolder incorrect ($BackupFolder)"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
[string[]] $GPOPath
|
||||
[string[]] $GPOPath,
|
||||
[switch] $DeleteExisting
|
||||
)
|
||||
if ($GPOPath) {
|
||||
if (-not $ExtendedForestInformation) {
|
||||
@@ -13,8 +14,18 @@
|
||||
} else {
|
||||
$ForestInformation = $ExtendedForestInformation
|
||||
}
|
||||
|
||||
if ($DeleteExisting) {
|
||||
$Test = Test-Path -LiteralPath $GPOPath
|
||||
if ($Test) {
|
||||
Write-Verbose "Save-GPOZaurrFiles - Removing existing content in $GPOPath"
|
||||
Remove-Item -LiteralPath $GPOPath -Recurse
|
||||
}
|
||||
}
|
||||
|
||||
$null = New-Item -ItemType Directory -Path $GPOPath -Force
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
Write-Verbose "Save-GPOZaurrFiles - Processing GPO for $Domain"
|
||||
Get-GPO -All -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain | ForEach-Object {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID.Guid -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain
|
||||
$Path = [io.path]::Combine($GPOPath, "$($_.ID.Guid).xml")
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
function Set-GPOZaurrOwner {
|
||||
[cmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Type')]
|
||||
param(
|
||||
[Parameter(ParameterSetName = 'Type', Mandatory)]
|
||||
[validateset('EmptyOrUnknown', 'NonAdministrative')][string[]] $Type,
|
||||
|
||||
[Parameter(ParameterSetName = 'Named')][string] $GPOName,
|
||||
[Parameter(ParameterSetName = 'Named')][alias('GUID', 'GPOID')][string] $GPOGuid,
|
||||
|
||||
[Parameter(ParameterSetName = 'Type')]
|
||||
[Parameter(ParameterSetName = 'Named')]
|
||||
[alias('ForestName')][string] $Forest,
|
||||
|
||||
[Parameter(ParameterSetName = 'Type')]
|
||||
[Parameter(ParameterSetName = 'Named')]
|
||||
[string[]] $ExcludeDomains,
|
||||
|
||||
[Parameter(ParameterSetName = 'Type')]
|
||||
[Parameter(ParameterSetName = 'Named')]
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
|
||||
[Parameter(ParameterSetName = 'Type')]
|
||||
[Parameter(ParameterSetName = 'Named')]
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
|
||||
[Parameter(Mandatory, ParameterSetName = 'Named')]
|
||||
[string] $Principal,
|
||||
|
||||
[Parameter(ParameterSetName = 'Type')]
|
||||
[Parameter(ParameterSetName = 'Named')]
|
||||
[int] $LimitProcessing
|
||||
)
|
||||
Begin {
|
||||
if ($Type -contains 'NonAdministrative') {
|
||||
$ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
}
|
||||
$Count = 0
|
||||
}
|
||||
Process {
|
||||
if ($Type) {
|
||||
Get-GPOZaurr -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Verbose:$false | ForEach-Object -Process {
|
||||
$GPO = $_
|
||||
if ($Type -contains 'NonAdministrative') {
|
||||
if ($GPO.Owner) {
|
||||
$AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"]
|
||||
$DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins']
|
||||
if ($AdministrativeGroup) {
|
||||
#Write-Verbose "Set-GPOZaurrOwner - Skipping GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName). Already owner $($GPO.Owner)."
|
||||
} else {
|
||||
Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $DefaultPrincipal"
|
||||
Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false
|
||||
$Count++
|
||||
if ($Count -eq $LimitProcessing) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'EmptyOrUnknown') {
|
||||
if ($null -eq $GPO.Owner) {
|
||||
$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
|
||||
$Count++
|
||||
if ($Count -eq $LimitProcessing) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Get-GPOZaurr -GPOName $GPOName -GPOGuid $GPOGUiD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Verbose:$false | ForEach-Object -Process {
|
||||
$GPO = $_
|
||||
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
|
||||
$Count++
|
||||
if ($Count -eq $LimitProcessing) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
function Invoke-GPOZaurr {
|
||||
function Set-GPOZaurrWMI {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
|
||||
Reference in New Issue
Block a user