Compare commits

...

20 Commits

Author SHA1 Message Date
Przemyslaw Klys 4e1f35f433 Version bump 2021-10-18 08:34:47 +02:00
Przemyslaw Klys 74eb14753e Fix when GPO is not linked 2021-10-18 08:33:42 +02:00
Przemyslaw Klys 1a7bb0273f Update changelog 2021-10-17 17:59:29 +02:00
Przemyslaw Klys 65eea07b6f Version bump 2021-10-17 15:08:48 +02:00
Przemyslaw Klys fe917d70b0 Support for new version of ADEssentials 2021-10-17 15:08:25 +02:00
Przemyslaw Klys 9786186a59 Added new function 2021-10-17 14:56:08 +02:00
Przemyslaw Klys b6fc7a676b Internal function 2021-10-17 14:55:59 +02:00
Przemyslaw Klys 46e6815314 internal function to find dates 2021-10-17 14:55:38 +02:00
Przemyslaw Klys b3e9ddeb64 New function, for now internal use 2021-10-17 14:55:27 +02:00
Przemyslaw Klys e5f67d8f2e Update changelog 2021-10-17 14:55:14 +02:00
Przemyslaw Klys 24f81647fa Version bump 2021-10-17 14:55:06 +02:00
Przemyslaw Klys cdeb2b4a2d Added search by dates 2021-10-17 14:54:54 +02:00
Przemyslaw Klys f7cf18500d Version bump 2021-08-24 18:32:48 +02:00
Przemyslaw Klys 1becfbca60 Added changelog entry 2021-08-24 18:32:11 +02:00
Przemysław Kłys 82c21edcc2 Merge pull request #24 from PatrickOnGit/FolderRedirectionType
Added folder redirection type
2021-08-24 18:30:23 +02:00
Przemyslaw Klys e56cf3bde3 Moved ID, added ID to SingleObject 2021-08-24 18:29:11 +02:00
patrick-sczepanski 996139ab4a Added folder redirection type 2021-08-23 11:12:56 +02:00
Przemyslaw Klys 5590e3bf31 Version bump 2021-08-19 11:25:19 +02:00
Przemyslaw Klys 9db54b338b Changelog update 2021-08-19 11:25:12 +02:00
Przemyslaw Klys e79d95c0fd Added root level 2021-08-19 11:24:22 +02:00
10 changed files with 475 additions and 7 deletions
+4 -4
View File
@@ -6,9 +6,9 @@
CompatiblePSEditions = @('Desktop')
Copyright = '(c) 2011 - 2021 Przemyslaw Klys @ Evotec. All rights reserved.'
Description = 'Group Policy Eater is a PowerShell module that aims to gather information about Group Policies but also allows fixing issues that you may find in them.'
FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrBroken', 'Get-GPOZaurrBrokenLink', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrDuplicateObject', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOrganizationalUnit', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionAnalysis', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionIssue', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrContent', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Optimize-GPOZaurr', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrDuplicateObject', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrLinkEmptyOU', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrBrokenLink', 'Repair-GPOZaurrNetLogonOwner', 'Repair-GPOZaurrPermission', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Set-GPOZaurrStatus', 'Skip-GroupPolicy')
FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrBroken', 'Get-GPOZaurrBrokenLink', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrDuplicateObject', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOrganizationalUnit', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionAnalysis', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionIssue', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrUpdates', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrContent', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Optimize-GPOZaurr', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrDuplicateObject', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrLinkEmptyOU', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrBrokenLink', 'Repair-GPOZaurrNetLogonOwner', 'Repair-GPOZaurrPermission', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Set-GPOZaurrStatus', 'Skip-GroupPolicy')
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
ModuleVersion = '0.0.138'
ModuleVersion = '0.0.142'
PowerShellVersion = '5.1'
PrivateData = @{
PSData = @{
@@ -18,11 +18,11 @@
}
}
RequiredModules = @(@{
ModuleVersion = '0.0.210'
ModuleVersion = '0.0.212'
ModuleName = 'PSSharedGoods'
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
}, @{
ModuleVersion = '0.0.130'
ModuleVersion = '0.0.134'
ModuleName = 'ADEssentials'
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
}, @{
@@ -4,6 +4,22 @@
[PSCustomObject] $GPO,
[switch] $SingleObject
)
# Redirection types a stored as GUID in GPOs. This hash is used to translate into readable text.
$FolderID = @{
"{1777F761-68AD-4D8A-87BD-30B759FA33DD}" = "Favorites"
"{FDD39AD0-238F-46AF-ADB4-6C85480369C7}" = "Documents"
"{33E28130-4E1E-4676-835A-98395C3BC3BB}" = "Pictures"
"{4BD8D571-6D19-48D3-BE97-422220080E43}" = "Music"
"{18989B1D-99B5-455B-841C-AB7C74E4DDFC}" = "Videos"
"{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}" = "AppDataRoaming"
"{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}" = "Desktop"
"{625B53C3-AB48-4EC1-BA1F-A1EF4146FC19}" = "StartMenu"
"{374DE290-123F-4565-9164-39C4925E467B}" = "Downloads"
"{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}" = "Saved Games"
"{56784854-C6CB-462B-8169-88E350ACB882}" = "Contacts"
"{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}" = "Searches"
"{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}" = "Links"
}
if ($SingleObject) {
$CreateGPO = [ordered]@{
DisplayName = $GPO.DisplayName
@@ -18,6 +34,8 @@
[Array] $CreateGPO['Settings'] = foreach ($Folder in $GPO.DataSet) {
foreach ($Location in $Folder.Location) {
[PSCustomObject] @{
ID = $Folder.ID
FolderType = $FolderID[$Folder.Id]
DestinationPath = $Location.DestinationPath
SecuritySID = $Location.SecurityGroup.SID.'#text'
SecurityName = $Location.SecurityGroup.Name.'#text'
@@ -47,6 +65,7 @@
GUID = $GPO.GUID
GpoType = $GPO.GpoType
Id = $Folder.Id
FolderType = $FolderID[$Folder.Id]
DestinationPath = $Location.DestinationPath
SecuritySID = $Location.SecurityGroup.SID.'#text'
SecurityName = $Location.SecurityGroup.Name.'#text'
+220
View File
@@ -0,0 +1,220 @@
function Get-ADOrganizationalUnitObject {
<#
.SYNOPSIS
Gets number of objects in a given OU/OUs with ability to find only those being affected by GPOs.
.DESCRIPTION
Gets number of objects in a given OU/OUs with ability to find only those being affected by GPOs.
.PARAMETER OrganizationalUnit
One or more organizational units to get the number of objects in.
.PARAMETER Extended
Adds all objects affected for better understanding
.PARAMETER Summary
Returns only summary for given OU/OUs
.PARAMETER IncludeAffectedOnly
Ignores any object types that are not Users or Computers
.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 AsHashTable
Returns results in form of hashtable
.PARAMETER ExtendedForestInformation
Ability to provide Forest Information from another command to speed up processing
.EXAMPLE
$OUs = @(
'OU=SE,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=US,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=Users,OU=User,OU=SE1,OU=SE,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
)
Get-ADOrganizationalUnitObject -OrganizationalUnit $OUs -IncludeAffectedOnly | Format-Table
.EXAMPLE
$OUs = @(
'OU=SE,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=US,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=Users,OU=User,OU=SE1,OU=SE,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
)
Get-ADOrganizationalUnitObject -OrganizationalUnit $OUs | Format-Table
.EXAMPLE
$OUs = @(
#'OU=SE,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
#'OU=US,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=Users,OU=User,OU=SE1,OU=SE,OU=ITR01,DC=ad,DC=evotec,DC=xyz'
'OU=ITR01,DC=ad,DC=evotec,DC=xyz'
)
Get-ADOrganizationalUnitObject -OrganizationalUnit $OUs -Summary -IncludeAffectedOnly | Format-List
.NOTES
General notes
#>
[cmdletBinding()]
param(
[parameter(Mandatory)][Array] $OrganizationalUnit,
[switch] $Extended,
[switch] $Summary,
[switch] $IncludeAffectedOnly,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[switch] $AsHashTable,
[System.Collections.IDictionary] $ExtendedForestInformation
)
$CachedOu = [ordered] @{}
$ListOU = @(
foreach ($OU in $OrganizationalUnit) {
if ($OU.DistinguishedName) {
$OU.DistinguishedName
} else {
$OU
}
}
)
$ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
$OUCache = Get-GPOBlockedInheritance -AsHashTable -ExtendedForestInformation $ForestInformation
if ($Summary) {
$SummaryData = [ordered] @{
ObjectsClasses = [ordered] @{}
ObjectsTotalCount = 0
ObjectsBlockedInheritanceCount = 0
ObjectsTotal = [ordered] @{}
ObjectsBlockedInheritance = [ordered] @{}
DistinguishedName = [System.Collections.Generic.List[string]]::new()
}
}
foreach ($OU in $ListOU) {
$Domain = ConvertFrom-DistinguishedName -ToDomainCN -DistinguishedName $OU
$ObjectsInOu = Get-ADObject -LDAPFilter "(|(ObjectClass=user)(ObjectClass=contact)(ObjectClass=computer)(ObjectClass=group)(objectClass=inetOrgPerson))" -SearchBase $OU -Server $ForestInformation['QueryServers'][$Domain]['hostname'][0]
#Write-Verbose "Get-GPOZaurrOrganizationalUnit - Processing $($Domain) / $($TOPOU.DistinguishedName) [$CountTop/$($TopOrganizationalUnits.Count)], found $($ObjectsInOu.Count) objects to process."
if (-not $CachedOu[$OU]) {
$CachedOu[$OU] = [ordered] @{
DistinguishedName = $OU
Domain = $Domain
'ObjectsClasses' = [ordered] @{} # only direct, indirect, but not with blocked inheritance
'ObjectsDirectCount' = 0
'ObjectsIndirectCount' = 0
'ObjectsTotalCount' = 0
'ObjectsTotalIncludingBlockedCount' = 0
'ObjectsBlockedInheritanceCount' = 0
}
if ($Extended) {
$CachedOu[$OU]['ObjectsDirect'] = [ordered] @{}
$CachedOu[$OU]['ObjectsIndirect'] = [ordered] @{}
$CachedOu[$OU]['ObjectsTotal'] = [ordered] @{}
$CachedOu[$OU]['ObjectsTotalIncludingBlocked'] = [ordered] @{}
$CachedOu[$OU]['ObjectsBlockedInheritance'] = [ordered] @{}
}
}
foreach ($Object in $ObjectsInOu) {
if ($IncludeAffectedOnly) {
if ($Object.ObjectClass -notin 'User', 'computer') {
continue
}
}
$Place = ConvertFrom-DistinguishedName -ToOrganizationalUnit -DistinguishedName $Object.DistinguishedName
if (-not $Place) {
# Write-Verbose -Message "Get-OrganizationalUnitObject - Processing object in container/root $($Object.DistinguishedName)"
}
if ($Place -and $OUCache[$Place]) {
$BlockedInheritance = $OUCache[$Place].BlockedInheritance
} else {
$BlockedInheritance = $false
}
if ($Summary) {
$SummaryData['DistinguishedName'].Add($OU)
$SummaryData['ObjectsClasses'][$Object.ObjectClass] = ''
if (-not $Place -or $Place -eq $OU) {
$SummaryData['ObjectsTotal'][$Object.DistinguishedName] = $Object
} else {
if ($BlockedInheritance) {
$SummaryData['ObjectsBlockedInheritance'][$Object.DistinguishedName] = $Object
} else {
$SummaryData['ObjectsTotal'][$Object.DistinguishedName] = $Object
}
}
} else {
# This is standard way of finding OU's
if (-not $Place -or $Place -eq $OU) {
$CachedOu[$OU]['ObjectsDirectCount']++
$CachedOu[$OU]['ObjectsTotalCount']++
# using hashtable to avoid duplicates
$CachedOu[$OU]['ObjectsClasses'][$Object.ObjectClass] = ''
# adding all objects to the list, excluding blocked inheritance
if ($Extended) {
$CachedOu[$OU]['ObjectsTotal'][$Object.DistinguishedName] = $Object
$CachedOu[$OU]['ObjectsDirect'][$Object.DistinguishedName] = $Object
}
} else {
if ($BlockedInheritance) {
# We only check for blocked inheritance if the object is not in the same OU
$CachedOu[$OU]['ObjectsBlockedInheritanceCount']++
if ($Extended) {
$CachedOu[$OU]['ObjectsBlockedInheritance'][$Object.DistinguishedName] = $Object
}
} else {
$CachedOu[$OU]['ObjectsIndirectCount']++
$CachedOu[$OU]['ObjectsTotalCount']++
# using hashtable to avoid duplicates
$CachedOu[$OU]['ObjectsClasses'][$Object.ObjectClass] = ''
# adding all objects to the list excluding blocked inheritance
if ($Extended) {
$CachedOu[$OU]['ObjectsTotal'][$Object.DistinguishedName] = $Object
$CachedOu[$OU]['ObjectsIndirect'][$Object.DistinguishedName] = $Object
}
}
}
$CachedOu[$OU]['ObjectsTotalIncludingBlockedCount']++
if ($Extended) {
$CachedOu[$OU]['ObjectsTotalIncludingBlocked'][$Object.DistinguishedName] = $Object
}
}
}
}
if ($Summary) {
foreach ($ObjectDistinguishedName in [string[]] $SummaryData['ObjectsBlockedInheritance'].Keys) {
if ($SummaryData['ObjectsTotal'][$ObjectDistinguishedName]) {
$SummaryData['ObjectsBlockedInheritance'].Remove($ObjectDistinguishedName)
}
}
$SummaryData['ObjectsTotalCount'] = $SummaryData['ObjectsTotal'].Count
$SummaryData['ObjectsBlockedInheritanceCount'] = $SummaryData['ObjectsBlockedInheritance'].Count
if (-not $Extended) {
$SummaryData.Remove('ObjectsTotal')
$SummaryData.Remove('ObjectsBlockedInheritance')
}
[PSCustomObject] $SummaryData
} else {
if ($AsHashTable) {
$CachedOu
} else {
$CachedOu.Values | ForEach-Object { [PSCustomObject] $_ }
}
}
}
+94
View File
@@ -0,0 +1,94 @@
function Get-ChoosenDates {
[CmdletBinding()]
param(
[ValidateSet('Everything', 'PastHour', 'CurrentHour', 'PastDay', 'CurrentDay', 'PastMonth', 'CurrentMonth', 'PastQuarter', 'CurrentQuarter', 'Last14Days', 'Last7Days', 'Last3Days', 'Last1Days')][string] $DateRange
)
#$Dates = @(
# Report Per Hour
if ($DateRange -eq 'PastHour') {
$DatesPastHour = Find-DatesPastHour
if ($DatesPastHour) {
$DatesPastHour
}
}
if ($DateRange -eq 'CurrentHour') {
$DatesCurrentHour = Find-DatesCurrentHour
if ($DatesCurrentHour) {
$DatesCurrentHour
}
}
# Report Per Day
if ($DateRange -eq 'PastDay') {
$DatesDayPrevious = Find-DatesDayPrevious
if ($DatesDayPrevious) {
$DatesDayPrevious
}
}
if ($DateRange -eq 'CurrentDay') {
$DatesDayToday = Find-DatesDayToday
if ($DatesDayToday) {
$DatesDayToday
}
}
# Report Per Month
if ($DateRange -eq 'PastMonth') {
# Find-DatesMonthPast runs only on 1st of the month unless -Force is used
$DatesMonthPrevious = Find-DatesMonthPast -Force $true
if ($DatesMonthPrevious) {
$DatesMonthPrevious
}
}
if ($DateRange -eq 'CurrentMonth') {
$DatesMonthCurrent = Find-DatesMonthCurrent
if ($DatesMonthCurrent) {
$DatesMonthCurrent
}
}
# Report Per Quarter
if ($DateRange -eq 'PastQuarter') {
# Find-DatesMonthPast runs only on 1st of the quarter unless -Force is used
$DatesQuarterLast = Find-DatesQuarterLast -Force $true
if ($DatesQuarterLast) {
$DatesQuarterLast
}
}
if ($DateRange -eq 'CurrentQuarter') {
$DatesQuarterCurrent = Find-DatesQuarterCurrent
if ($DatesQuarterCurrent) {
$DatesQuarterCurrent
}
}
if ($DateRange -eq 'Everything') {
$DatesEverything = @{
DateFrom = Get-Date -Year 1900 -Month 1 -Day 1
DateTo = Get-Date -Year 2300 -Month 1 -Day 1
}
$DatesEverything
}
if ($DateRange -eq 'Last1days') {
$DatesCurrentDayMinusDaysX = Find-DatesCurrentDayMinuxDaysX -days 1
if ($DatesCurrentDayMinusDaysX) {
$DatesCurrentDayMinusDaysX
}
}
if ($DateRange -eq 'Last3days') {
$DatesCurrentDayMinusDaysX = Find-DatesCurrentDayMinuxDaysX -days 3
if ($DatesCurrentDayMinusDaysX) {
$DatesCurrentDayMinusDaysX
}
}
if ($DateRange -eq 'Last7days') {
$DatesCurrentDayMinusDaysX = Find-DatesCurrentDayMinuxDaysX -days 7
if ($DatesCurrentDayMinusDaysX) {
$DatesCurrentDayMinusDaysX
}
}
if ($DateRange -eq 'Last14days') {
$DatesCurrentDayMinusDaysX = Find-DatesCurrentDayMinuxDaysX -days 14
if ($DatesCurrentDayMinusDaysX) {
$DatesCurrentDayMinusDaysX
}
}
#)
#$Dates
}
+30
View File
@@ -0,0 +1,30 @@
function Get-GPOBlockedInheritance {
[cmdletBinding()]
param(
[string] $Filter = '*',
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[switch] $AsHashTable,
[System.Collections.IDictionary] $ExtendedForestInformation
)
$OUCache = [ordered] @{}
$ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
foreach ($Domain in $ForestInformation.Domains) {
$OrganizationalUnits = Get-ADOrganizationalUnit -Filter $Filter -Properties gpOptions, canonicalName -Server $ForestInformation['QueryServers'][$Domain]['HostName'][0] #-SearchScope Subtree
foreach ($OU in $OrganizationalUnits) {
$OUCache[$OU.DistinguishedName] = [PSCustomObject] @{
DistinguishedName = $OU.DistinguishedName
BlockedInheritance = if ($OU.gpOptions -eq 1) { $true } else { $false } # blocked inheritance
}
}
}
if ($AsHashTable) {
$OUCache
} else {
$OUCache.Values
}
}
+22 -2
View File
@@ -10,6 +10,11 @@
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[DateTime] $DateFrom,
[DateTime] $DateTo,
[ValidateSet('PastHour', 'CurrentHour', 'PastDay', 'CurrentDay', 'PastMonth', 'CurrentMonth', 'PastQuarter', 'CurrentQuarter', 'Last14Days', 'Last7Days', 'Last3Days', 'Last1Days')][string] $DateRange,
[ValidateSet('WhenCreated', 'WhenChanged')][string] $DateProperty = 'WhenCreated',
[System.Collections.IDictionary] $ExtendedForestInformation
)
Begin {
@@ -48,7 +53,21 @@
Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
}
}
Get-ADObject @Splat -Properties DisplayName, Name, Created, Modified, gPCFileSysPath, gPCFunctionalityVersion, gPCWQLFilter, gPCMachineExtensionNames, Description, CanonicalName, DistinguishedName | ForEach-Object -Process {
# allows to only get GPOs from a specific date range
if ($PSBoundParameters.ContainsKey('DateRange')) {
$Dates = Get-ChoosenDates -DateRange $DateRange
$DateFrom = $($Dates.DateFrom)
$DateTo = $($Dates.DateTo)
$Splat['Filter'] = -join ($Splat['Filter'], '-and ($DateProperty -ge $DateFrom -and $DateProperty -le $DateTo)')
} elseif ($PSBoundParameters.ContainsKey('DateFrom') -and $PSBoundParameters.ContainsKey('DateTo')) {
# already set $DateFrom,DateTo
$Splat['Filter'] = -join ($Splat['Filter'], '-and ($DateProperty -ge $DateFrom -and $DateProperty -le $DateTo)')
} else {
# not needed
}
Get-ADObject @Splat -Properties DisplayName, Name, Created, Modified, ntSecurityDescriptor, gPCFileSysPath, gPCFunctionalityVersion, gPCWQLFilter, gPCMachineExtensionNames, Description, CanonicalName, DistinguishedName | ForEach-Object -Process {
$DomainCN = ConvertFrom-DistinguishedName -DistinguishedName $_.DistinguishedName -ToDomainCN
$GUID = $_.Name -replace '{' -replace '}'
if (($GUID).Length -ne 36) {
@@ -60,9 +79,10 @@
$Output['Description'] = $_.Description
$Output['GUID'] = $GUID
$Output['Path'] = $_.gPCFileSysPath
$Output['FunctionalityVersion'] = $_.gPCFunctionalityVersion
#$Output['FunctionalityVersion'] = $_.gPCFunctionalityVersion
$Output['Created'] = $_.Created
$Output['Modified'] = $_.Modified
$Output['Owner'] = $_.ntSecurityDescriptor.Owner
$Output['GPOCanonicalName'] = $_.CanonicalName
$Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_.DistinguishedName -ToDC
$Output['GPODistinguishedName'] = $_.DistinguishedName
@@ -39,6 +39,7 @@
'ObjectsCountIndirect' = 0
'ObjectsCountTotal' = 0
'Level' = 'Top'
'RootLevel' = $TopOU.Name
'Domain' = $Domain
}
@@ -61,6 +62,7 @@
'ObjectsCountIndirect' = 0
'ObjectsCountTotal' = 0
'Level' = 'Child'
'RootLevel' = $TopOU.Name
'Domain' = $Domain
}
}
@@ -132,6 +134,7 @@
[PSCustomObject] @{
Organizationalunit = $OU
Level = $CachedOu[$OU]['Level']
RootLevel = $CachedOu[$OU]['RootLevel']
DomainName = $CachedOu[$OU]['Domain']
Status = $Status
GPOCount = $CachedOu[$OU]['LinkedGroupPolicyObjects'].Count
+1 -1
View File
@@ -84,7 +84,7 @@
foreach ($_ in $Objects) {
$Count++
Write-Verbose "Get-GPOZaurrOwner - Processing GPO [$Count/$($Objects.Count)]: $($_.DisplayName) from domain: $($_.DomainName)"
$ACL = Get-ADACLOwner -ADObject $_.GPODistinguishedName -Resolve -ADAdministrativeGroups $ADAdministrativeGroups -Verbose:$false
$ACL = Get-ADACLOwner -ADObject $_.GPODistinguishedName -Resolve -Verbose:$false
$Object = [ordered] @{
DisplayName = $_.DisplayName
DomainName = $_.DomainName
+71
View File
@@ -0,0 +1,71 @@
function Get-GPOZaurrUpdates {
[cmdletBinding()]
param(
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[DateTime] $DateFrom,
[DateTime] $DateTo,
[ValidateSet('PastHour', 'CurrentHour', 'PastDay', 'CurrentDay', 'PastMonth', 'CurrentMonth', 'PastQuarter', 'CurrentQuarter', 'Last14Days', 'Last7Days', 'Last3Days', 'Last1Days')][string] $DateRange,
[ValidateSet('WhenCreated', 'WhenChanged')][string] $DateProperty = 'WhenCreated',
[System.Collections.IDictionary] $ExtendedForestInformation
)
$getGPOZaurrADSplat = @{
Forest = $Forest
IncludeDomains = $IncludeDomains
ExcludeDomains = $ExcludeDomains
ExtendedForestInformation = $ExtendedForestInformation
DateFrom = $DateFrom
DateTo = $DateTo
DateRange = $DateRange
DateProperty = $DateProperty
}
Remove-EmptyValue -Hashtable $getGPOZaurrADSplat
# lets get all the links including sites
Write-Verbose -Message "Get-GPOZaurrUpdates - Get group policies for defined ranges"
$LinksSummaryCache = Get-GPOZaurrLink -AsHashTable -Summary -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
$OUCache = [ordered] @{}
foreach ($Domain in $ForestInformation.Domains) {
$OrganizationalUnits = Get-ADOrganizationalUnit -Filter * -Properties gpOptions, canonicalName -Server $ForestInformation['QueryServers'][$Domain]['HostName'][0]
$OUCache[$OrganizationalUnits.DistinguishedName] = if ($OrganizationalUnits.gpOptions -eq 1) { $true } else { $false } # blocked inheritance
}
$GPOs = Get-GPOZaurrAD @getGPOZaurrADSplat
foreach ($GPO in $GPOs) {
$GPOLinkData = $LinksSummaryCache["$($GPO.DomainName)$($GPO.GUID)"]
#$GPOLinkData
[Array] $LinksDN = if ($GPOLinkData.Links.Count -gt 0) {
foreach ($Link in $GPOLinkData.LinksObjects) {
If ($Link.Enabled -eq $true) {
$Link.DistinguishedName
}
}
}
if ($LinksDN.Count -gt 0) {
$OrganizationalUnitsObjects = Get-ADOrganizationalUnitObject -OrganizationalUnit $LinksDN -Summary -IncludeAffectedOnly
} else {
# GPO is not linked
$OrganizationalUnitsObjects = [PSCUstomObject] @{
ObjectsTotalCount = 0
ObjectsBlockedInheritanceCount = 0
ObjectsClasses = @()
}
}
[PSCustomObject] @{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
Owner = $GPO.Owner
LinksCount = if ($GPOLinkData) { $GPOLinkData.LinksCount } else { 0 }
LinksEnabledCount = if ($GPOLinkData) { $GPOLinkData.LinksEnabledCount } else { 0 }
AffectedCount = $OrganizationalUnitsObjects.ObjectsTotalCount
BlockedInheritanceCount = $OrganizationalUnitsObjects.ObjectsBlockedInheritanceCount
AffectedClasses = $OrganizationalUnitsObjects.ObjectsClasses
Created = $GPO.Created
Changed = $GPO.Modified
LinksEnabled = $LinksDN
}
}
}
+11
View File
@@ -55,6 +55,17 @@ To understand the usage I've created blog post you may find useful
## Changelog
- 0.0.142 - 2021.10.18
- Fixes `Get-GPOZaurrUpdates` when GPO is not linked
- 0.0.141 - 2021.10.17
- Removed property from `Get-GPOZaurrAD` - `FunctionalityVersion`
- Added property to `Get-GPOZaurrAD` - `Owner`
- Added ability to choose date ranges for `Get-GPOZaurrAD`
- Added `Get-GPOZaurrUpdates` which shows last gpos added to forest
- 0.0.140 - 2021.08.24
- ☑ Improved `Invoke-GPOZaurr` - type `GPOAnalysis` - added folder redirection type - [tnx PatrickOnGit](https://github.com/EvotecIT/GPOZaurr/pull/24)
- 0.0.139 - 2021.08.19
- ☑ Improved `Invoke-GPOZaurr` - type `GPOOrganizationalUnit` - adding RootLevel information
- 0.0.138 - 2021.08.18
- 🐛 Fix for exclusions using GUID with brackets for Invoke-GPOZaurr `GPOList` and related options
- 0.0.137 - 2021.08.17