mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 11:49:17 +00:00
146 lines
5.9 KiB
PowerShell
146 lines
5.9 KiB
PowerShell
function Get-GPOZaurrOwner {
|
|
<#
|
|
.SYNOPSIS
|
|
Gets owners of GPOs from Active Directory and SYSVOL
|
|
|
|
.DESCRIPTION
|
|
Gets owners of GPOs from Active Directory and SYSVOL
|
|
|
|
.PARAMETER GPOName
|
|
Name of GPO. By default all GPOs are returned
|
|
|
|
.PARAMETER GPOGuid
|
|
GUID of GPO. By default all GPOs are returned
|
|
|
|
.PARAMETER IncludeSysvol
|
|
Includes Owner from SYSVOL as well
|
|
|
|
.PARAMETER SkipBroken
|
|
Doesn't display GPOs that have no SYSVOL content (orphaned GPOs)
|
|
|
|
.PARAMETER Forest
|
|
Target different Forest, by default current forest is used
|
|
|
|
.PARAMETER ExcludeDomains
|
|
Exclude domain from search, by default whole forest is scanned
|
|
|
|
.PARAMETER IncludeDomains
|
|
Include only specific domains, by default whole forest is scanned
|
|
|
|
.PARAMETER ExtendedForestInformation
|
|
Ability to provide Forest Information from another command to speed up processing
|
|
|
|
.PARAMETER ADAdministrativeGroups
|
|
Ability to provide AD Administrative Groups from another command to speed up processing
|
|
|
|
.PARAMETER ApprovedOwner
|
|
Ability to provide different owner (non administrative that still is approved for use)
|
|
|
|
.EXAMPLE
|
|
Get-GPOZaurrOwner -Verbose -IncludeSysvol
|
|
|
|
.EXAMPLE
|
|
Get-GPOZaurrOwner -Verbose -IncludeSysvol -SkipBroken
|
|
|
|
.NOTES
|
|
General notes
|
|
#>
|
|
[cmdletbinding(DefaultParameterSetName = 'Default')]
|
|
param(
|
|
[Parameter(ParameterSetName = 'GPOName')][string] $GPOName,
|
|
[Parameter(ParameterSetName = 'GPOGUID')][alias('GUID', 'GPOID')][string] $GPOGuid,
|
|
|
|
[switch] $IncludeSysvol,
|
|
[switch] $SkipBroken,
|
|
|
|
[alias('ForestName')][string] $Forest,
|
|
[string[]] $ExcludeDomains,
|
|
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
|
[System.Collections.IDictionary] $ExtendedForestInformation,
|
|
[System.Collections.IDictionary] $ADAdministrativeGroups,
|
|
|
|
[alias('Exclusion', 'Exclusions')][string[]] $ApprovedOwner
|
|
)
|
|
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
|
|
}
|
|
$Count = 0
|
|
}
|
|
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) {
|
|
$Count++
|
|
Write-Verbose "Get-GPOZaurrOwner - Processing GPO [$Count/$($Objects.Count)]: $($_.DisplayName) from domain: $($_.DomainName)"
|
|
$ACL = Get-ADACLOwner -ADObject $_.GPODistinguishedName -Resolve -Verbose:$false
|
|
$Object = [ordered] @{
|
|
DisplayName = $_.DisplayName
|
|
DomainName = $_.DomainName
|
|
GUID = $_.GUID
|
|
Status = [System.Collections.Generic.List[string]]::new()
|
|
Owner = $ACL.OwnerName
|
|
OwnerSid = $ACL.OwnerSid
|
|
OwnerType = $ACL.OwnerType
|
|
}
|
|
if ($IncludeSysvol) {
|
|
$FileOwner = Get-FileOwner -JustPath -Path $_.Path -Resolve -Verbose:$false
|
|
$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['IsOwnerAdministrative'] = if ($Object['SysvolType'] -eq 'Administrative' -and $Object['OwnerType'] -eq 'Administrative') { $true } else { $false }
|
|
if (Test-Path -LiteralPath $Object['SysvolPath']) {
|
|
$Object['SysvolExists'] = $true
|
|
} else {
|
|
$Object['SysvolExists'] = $false
|
|
}
|
|
} else {
|
|
$Object['IsOwnerAdministrative'] = if ($Object['OwnerType'] -eq 'Administrative') { $true } else { $false }
|
|
}
|
|
if ($Object['IsOwnerAdministrative'] -eq $true) {
|
|
$Object['Status'].Add('Administrative')
|
|
} else {
|
|
$Object['Status'].Add('NotAdministrative')
|
|
}
|
|
if ($Object['IsOwnerConsistent']) {
|
|
$Object['Status'].Add('Consistent')
|
|
} else {
|
|
$Object['Status'].Add('Inconsistent')
|
|
}
|
|
if ($Object['IsOwnerConsistent'] -eq $true -and $Object['IsOwnerAdministrative'] -eq $false) {
|
|
# We want to approve only OWNER if it's consistent and not administrative, otherwise it makes no sense
|
|
# This is mostly here to allow for use of AGPM or similar approved owner of GPOs
|
|
foreach ($Owner in $ApprovedOwner) {
|
|
if ($Owner -eq $Object['Owner']) {
|
|
$Object['Status'].Add('Approved')
|
|
break
|
|
} elseif ($Owner -eq $Object['OwnerSid']) {
|
|
$Object['Status'].Add('Approved')
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if ($SkipBroken -and $Object['SysvolExists'] -eq $false) {
|
|
continue
|
|
}
|
|
$Object['DistinguishedName'] = $_.GPODistinguishedName
|
|
[PSCUstomObject] $Object
|
|
}
|
|
}
|
|
End {
|
|
|
|
}
|
|
} |