mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 11:49:17 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4acf509e2b | |||
| 4c0647b81f | |||
| 7415386a13 | |||
| db7838fc18 | |||
| 19e6d514a1 | |||
| 3375c10ee7 | |||
| ca030b5fee |
@@ -0,0 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Get-GPOZaurrWMI -Name 'Test - Dual Filter' | Format-Table -AutoSize *
|
||||
@@ -1,3 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Get-GPOZaurrSysvol -VerifyDomainControllers -Verbose | Format-Table
|
||||
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
|
||||
+2
-2
@@ -5,9 +5,9 @@
|
||||
CompatiblePSEditions = 'Desktop'
|
||||
Copyright = '(c) 2011 - 2020 Przemyslaw Klys @ Evotec. All rights reserved.'
|
||||
Description = 'Group Policy Eater'
|
||||
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-GPOZaurrWMI', 'Invoke-GPOZaurrPermission', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', '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.28'
|
||||
ModuleVersion = '0.0.31'
|
||||
PowerShellVersion = '5.1'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
|
||||
@@ -37,11 +37,16 @@
|
||||
$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-WinADGPOSysvolFolders - ACL reading failed for $($SysvolHash[$GPO.Id.GUID].FullName) with error: $($_.Exception.Message)"
|
||||
Write-Warning "Get-GPOZaurrSysvol - ACL reading (1) failed for $FullPath with error: $($_.Exception.Message)"
|
||||
$ACL = $null
|
||||
$Owner = ''
|
||||
$ErrorMessage = $_.Exception.Message
|
||||
}
|
||||
} else {
|
||||
$ACL = $null
|
||||
@@ -58,26 +63,33 @@
|
||||
SysvolServer = $Server
|
||||
SysvolStatus = $SysVolStatus
|
||||
Owner = $GPO.Owner
|
||||
FileOwner = $ACL.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') {
|
||||
|
||||
if ($null -ne $SysvolHash[$_].FullName) {
|
||||
$ACL = Get-Acl -Path $SysvolHash[$_].FullName -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
$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] @{
|
||||
@@ -86,16 +98,18 @@
|
||||
DomainName = $Domain
|
||||
SysvolServer = $Server
|
||||
SysvolStatus = $Differences[$GPO.Id.Guid]
|
||||
Owner = $ACL.Owner
|
||||
FileOwner = $ACL.Owner
|
||||
Owner = ''
|
||||
FileOwner = $Owner
|
||||
Id = $_
|
||||
GpoStatus = 'Orphaned'
|
||||
Path = $FullPath
|
||||
Description = $null
|
||||
CreationTime = $SysvolHash[$_].CreationTime
|
||||
ModificationTime = $SysvolHash[$_].LastWriteTime
|
||||
UserVersion = $null
|
||||
ComputerVersion = $null
|
||||
WmiFilter = $null
|
||||
Error = $ErrorMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,23 +12,26 @@
|
||||
[switch] $VerifyDomainControllers
|
||||
)
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation
|
||||
if (-not $VerifyDomainControllers) {
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
Write-Verbose "Get-WinADGPOSysvolFolders - Processing $Domain"
|
||||
$QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0]
|
||||
[Array]$GPOs = @(Get-GPO -All -Domain $Domain -Server $QueryServer)
|
||||
Test-SysVolFolders -GPOs $GPOs -Server $Domain -Domain $Domain
|
||||
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
|
||||
}
|
||||
} else {
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
Write-Verbose "Get-WinADGPOSysvolFolders - Processing $Domain"
|
||||
$QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0]
|
||||
[Array]$GPOs = @(Get-GPO -All -Domain $Domain -Server $QueryServer)
|
||||
foreach ($Server in $ForestInformation['DomainDomainControllers']["$Domain"]) {
|
||||
Write-Verbose "Get-WinADGPOSysvolFolders - Processing $Domain \ $($Server.HostName.Trim())"
|
||||
Test-SysVolFolders -GPOs $GPOs -Server $Server.Hostname -Domain $Domain
|
||||
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
@@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
<#
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user