Compare commits

...

40 Commits

Author SHA1 Message Date
Przemyslaw Klys e78db61695 Version bump 2021-10-19 17:09:41 +02:00
Przemyslaw Klys 781e95d042 Adding verbose messages 2021-10-19 17:07:36 +02:00
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
Przemyslaw Klys 8c1f95b1b8 Version bump 2021-08-18 19:44:21 +02:00
Przemyslaw Klys 4d9f1e7fba Changelog update 2021-08-18 19:44:13 +02:00
Przemyslaw Klys 88fb1651a9 Fix for exclusions using GUID with brackets 2021-08-18 19:42:57 +02:00
Przemyslaw Klys 9696fb0cab Update example 2021-08-17 10:20:50 +02:00
Przemyslaw Klys bb77785ea8 Update example 2021-08-17 10:20:30 +02:00
Przemyslaw Klys 168919d7d9 BUmp new version 2021-08-17 10:20:06 +02:00
Przemyslaw Klys 5effe5face Make delete OU non-mandatatory 2021-08-17 10:19:57 +02:00
Przemyslaw Klys 6d15363caa bump version 2021-08-17 10:14:22 +02:00
Przemyslaw Klys 6c62a11767 Updated wording 2021-08-17 10:13:46 +02:00
Przemyslaw Klys 61bfe5bd4d Bump version, new release 2021-08-17 08:51:22 +02:00
Przemyslaw Klys 5043767e8d Small adjustment of texts 2021-08-17 08:50:42 +02:00
Przemyslaw Klys e4ecafaea5 Improvements to GPOList to not trigger require changes when excluding GPOs 2021-08-17 08:50:28 +02:00
Przemyslaw Klys 154e3428e6 More changes 2021-08-16 16:39:41 +02:00
Przemyslaw Klys a6c2ac1226 Version bump 2021-08-16 16:21:12 +02:00
Przemyslaw Klys 2b0a395abc Small improvement 2021-08-16 16:20:35 +02:00
Przemyslaw Klys 04b7242bde Version bump 2021-08-16 12:02:24 +02:00
Przemyslaw Klys 48af562bfd Changelog update 2021-08-16 12:01:57 +02:00
Przemyslaw Klys a5d447b28c Improvements to exclusions 2021-08-16 12:01:39 +02:00
16 changed files with 594 additions and 83 deletions
+7 -4
View File
@@ -1,16 +1,19 @@
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
#$Output = Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -PassThru -Type GPOConsistency, GPOList, GPODuplicates, GPOBroken, GPOOwners, NetLogonOwners, GPOPermissionsRead, GPOPermissionsAdministrative,GPOPermissionsUnknown
Invoke-GPOZaurr -Type GPOOrganizationalUnit -Online -FilePath $PSScriptRoot\Reports\GPOZaurr.html
# Shows how to use exclusions (supported only in GPOBlockedInheritance)
Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Type GPOBlockedInheritance -Online -Exclusions @(
'OU=Test,OU=ITR02,DC=ad,DC=evotec,DC=xyz'
)
<#
# different approach to query multiple reports or just one
Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -PassThru -Type GPOConsistency, GPOList, GPODuplicates, GPOBroken, GPOOwners, NetLogonOwners, GPOPermissionsRead, GPOPermissionsAdministrative,GPOPermissionsUnknown
Invoke-GPOZaurr -Type GPOOwners -Online -FilePath $PSScriptRoot\Reports\GPOZaurr.html
# Shows how to use exclusions for GPOList (different way)
Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Type GPOList -Online -Exclusions {
Skip-GroupPolicy -Name 'de14_usr_std'
Skip-GroupPolicy -Name 'ALL | Enable RDP' -DomaiName 'ad.evotec.xyz'
}
#>
}
+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.131'
ModuleVersion = '0.0.143'
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
}
}
+11 -2
View File
@@ -230,9 +230,18 @@
# Mark GPO as excluded
$Exclude = $false
if ($ExcludeGroupPolicies) {
$GUID = $XMLContent.GPO.Identifier.Identifier.'#text'
$GUIDWithOutBrackets = $GUID.Replace('{', '').Replace('}', '')
$PolicyWithDomain = -join ($XMLContent.GPO.Identifier.Domain.'#text', $XMLContent.GPO.Name)
$PolicyWithDomainID = -join ($XMLContent.GPO.Identifier.Domain.'#text', $XMLContent.GPO.Identifier.Identifier.'#text')
if ($ExcludeGroupPolicies[$XMLContent.GPO.Name] -or $ExcludeGroupPolicies[$PolicyWithDomain] -or $ExcludeGroupPolicies[$PolicyWithDomainID] -or $ExcludeGroupPolicies[$XMLContent.GPO.Identifier.Identifier.'#text']) {
$PolicyWithDomainID = -join ($XMLContent.GPO.Identifier.Domain.'#text', $GUID)
$PolicyWithDomainIDWithoutBrackets = -join ($XMLContent.GPO.Identifier.Domain.'#text', $GUIDWithOutBrackets)
if ($ExcludeGroupPolicies[$XMLContent.GPO.Name] -or
$ExcludeGroupPolicies[$PolicyWithDomain] -or
$ExcludeGroupPolicies[$PolicyWithDomainID] -or
$ExcludeGroupPolicies[$GUID] -or
$ExcludeGroupPolicies[$GUIDWithOutBrackets] -or
$ExcludeGroupPolicies[$PolicyWithDomainIDWithoutBrackets]
) {
$Exclude = $true
}
}
@@ -116,10 +116,9 @@
New-HTMLText -Text @(
"While preparing this report following exclusions were defined. "
"Please make sure that when you execute your steps to include those exclusions to prevent any issues. "
) -FontSize 10pt
) -FontSize 10pt -FontWeight bold, normal -Color Red, None -LineBreak
New-HTMLText -LineBreak
New-HTMLText -Text "Code to use: " -LineBreak -FontSize 10pt -FontWeight bold
New-HTMLText -Text "Code to use for exclusions: " -FontSize 10pt -FontWeight bold -LineBreak
$Code = New-GPOZaurrExclusions -ExclusionsArray $Script:Reporting['GPOBlockedInheritance']['Exclusions']
+59 -45
View File
@@ -51,9 +51,17 @@
# Skip GPOS that are younger than 30 days
$Script:Reporting['GPOList']['Variables']['GPOSkip']++
}
if (($GPO.Enabled -eq $false -or $GPO.Empty -eq $true -or $GPO.Linked -eq $false -or $GPO.ApplyPermission -eq $false) -and $GPO.Days -le $Script:Reporting['GPOList']['Variables']['GPOOlderThan']) {
if ($GPO.Exclude -eq $true) {
# Skip GPOS that are excluded
$Script:Reporting['GPOList']['Variables']['GPOSkipExcluded']++
}
if (($GPO.Enabled -eq $false -or $GPO.Empty -eq $true -or $GPO.Linked -eq $false -or $GPO.ApplyPermission -eq $false) -and $GPO.Exclude -eq $true) {
$Script:Reporting['GPOList']['Variables']['GPONotValidButExcluded']++
$Script:Reporting['GPOList']['Variables']['GPONotValidButSkippedOrExcluded']++
} elseif (($GPO.Enabled -eq $false -or $GPO.Empty -eq $true -or $GPO.Linked -eq $false -or $GPO.ApplyPermission -eq $false) -and $GPO.Days -le $Script:Reporting['GPOList']['Variables']['GPOOlderThan']) {
# Skip GPOS that are younger than 30 days
$Script:Reporting['GPOList']['Variables']['GPONotValidButSkip']++
$Script:Reporting['GPOList']['Variables']['GPONotValidButSkippedOrExcluded']++
}
if (($GPO.Enabled -eq $false -or $GPO.Empty -eq $true -or $GPO.Linked -eq $false -or $GPO.ApplyPermission -eq $false) -and $GPO.Days) {
$Script:Reporting['GPOList']['Variables']['GPONotValid']++
@@ -141,52 +149,55 @@
}
}
$Script:Reporting['GPOList']['Variables']['GPOTotal'] = $Script:Reporting['GPOList']['Data'].Count
if ($Script:Reporting['GPOList']['Variables']['GPONotValid'] -gt 0 -and $Script:Reporting['GPOList']['Variables']['GPONotValidButSkip'] -ne $Script:Reporting['GPOList']['Variables']['GPONotValid']) {
if ($Script:Reporting['GPOList']['Variables']['GPONotValid'] -gt 0 -and $Script:Reporting['GPOList']['Variables']['GPONotValidButSkippedOrExcluded'] -ne $Script:Reporting['GPOList']['Variables']['GPONotValid']) {
$Script:Reporting['GPOList']['ActionRequired'] = $true
} else {
$Script:Reporting['GPOList']['ActionRequired'] = $false
}
}
Variables = @{
GPOOlderThan = 30
GPONotValidPerDomain = $null
GPOValidPerDomain = $null
GPONotOptimizedPerDomain = $null
GPOOptimizedPerDomain = $null
GPOProblemPerDomain = $null
GPONoProblemPerDomain = $null
GPOApplyPermissionYesPerDomain = $null
GPOApplyPermissionNoPerDomain = $null
GPOWithProblems = 0
ComputerOptimizedYes = 0
ComputerOptimizedNo = 0
ComputerProblemYes = 0
ComputerProblemNo = 0
UserOptimizedYes = 0
UserOptimizedNo = 0
UserProblemYes = 0
UserProblemNo = 0
GPOOptimized = 0
GPONotOptimized = 0
GPOProblem = 0
GPONoProblem = 0
GPONotLinked = 0
GPOLinked = 0
GPOEmpty = 0
GPONotEmpty = 0
GPOEmptyAndUnlinked = 0
GPOEmptyOrUnlinked = 0
GPOLinkedButEmpty = 0
GPOEnabled = 0
GPODisabled = 0
GPOSkip = 0
GPOValid = 0
GPONotValid = 0
GPONotValidButSkip = 0
GPOLinkedButLinkDisabled = 0
GPOTotal = 0
ApplyPermissionYes = 0
ApplyPermissionNo = 0
GPOOlderThan = 30
GPONotValidPerDomain = $null
GPOValidPerDomain = $null
GPONotOptimizedPerDomain = $null
GPOOptimizedPerDomain = $null
GPOProblemPerDomain = $null
GPONoProblemPerDomain = $null
GPOApplyPermissionYesPerDomain = $null
GPOApplyPermissionNoPerDomain = $null
GPOWithProblems = 0
ComputerOptimizedYes = 0
ComputerOptimizedNo = 0
ComputerProblemYes = 0
ComputerProblemNo = 0
UserOptimizedYes = 0
UserOptimizedNo = 0
UserProblemYes = 0
UserProblemNo = 0
GPOOptimized = 0
GPONotOptimized = 0
GPOProblem = 0
GPONoProblem = 0
GPONotLinked = 0
GPOLinked = 0
GPOEmpty = 0
GPONotEmpty = 0
GPOEmptyAndUnlinked = 0
GPOEmptyOrUnlinked = 0
GPOLinkedButEmpty = 0
GPOEnabled = 0
GPODisabled = 0
GPOSkip = 0
GPOSkipExcluded = 0
GPOValid = 0
GPONotValid = 0
GPONotValidButSkip = 0
GPONotValidButExcluded = 0
GPONotValidButSkippedOrExcluded = 0
GPOLinkedButLinkDisabled = 0
GPOTotal = 0
ApplyPermissionYes = 0
ApplyPermissionNo = 0
}
Overview = {
@@ -202,6 +213,7 @@
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies total: ', $Script:Reporting['GPOList']['Variables']['GPOTotal'] -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies valid: ", $Script:Reporting['GPOList']['Variables']['GPOValid'] -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies exclusions defined: ", $Script:Reporting['GPOList']['Variables']['GPOSkipExcluded'] -FontWeight normal, bold -Color None, DeepSkyBlue
New-HTMLListItem -Text "Group Policies ", "NOT", " valid: ", $Script:Reporting['GPOList']['Variables']['GPONotValid'] -FontWeight normal, bold, normal, bold {
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $Script:Reporting['GPOList']['Variables']['GPONotLinked'] -FontWeight normal, bold
@@ -213,7 +225,10 @@
}
} -Color Black, Red, Black, Red, Black
New-HTMLListItem -Text @(
"Group Policies ", "NOT", " valid, to skip: ", $Script:Reporting['GPOList']['Variables']['GPONotValidButSkip'], " (modified less than $($Script:Reporting['GPOList']['Variables']['GPOOlderThan']) days ago)"
"Group Policies ", "NOT", " valid, to skip (because of age): ", $Script:Reporting['GPOList']['Variables']['GPONotValidButSkip'], " (modified less than $($Script:Reporting['GPOList']['Variables']['GPOOlderThan']) days ago)"
) -FontWeight 'normal', 'bold', 'normal', 'bold', 'normal' -Color 'Black', 'Red', 'Black', 'Red', 'Black'
New-HTMLListItem -Text @(
"Group Policies ", "NOT", " valid, to skip (because of exclusions): ", $Script:Reporting['GPOList']['Variables']['GPONotValidButExcluded']
) -FontWeight 'normal', 'bold', 'normal', 'bold', 'normal' -Color 'Black', 'Red', 'Black', 'Red', 'Black'
New-HTMLListItem -Text "Group Policies recently modified: ", $Script:Reporting['GPOList']['Variables']['GPOSkip'], " (modified less than $($Script:Reporting['GPOList']['Variables']['GPOOlderThan']) days ago)" -FontWeight normal, bold
} -FontSize 10pt
@@ -304,10 +319,9 @@
New-HTMLText -Text @(
"While preparing this report following exclusions were defined. "
"Please make sure that when you execute your steps to include those exclusions to prevent any issues. "
) -FontSize 10pt
) -FontSize 10pt -FontWeight bold, normal -Color Red, None -LineBreak
New-HTMLText -LineBreak
New-HTMLText -Text "Code to use: " -LineBreak -FontSize 10pt -FontWeight bold
New-HTMLText -Text "Code to use for exclusions: " -FontSize 10pt -FontWeight bold -LineBreak
$Code = New-GPOZaurrExclusions -ExclusionsArray $Script:Reporting['GPOList']['Exclusions']
+17 -18
View File
@@ -21,7 +21,7 @@
$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFixPerDomain'][$OU.DomainName] = 0
}
if ($OU.Status -contains 'Unlink GPO' -and $OU.Status -contains 'Delete OU') {
$Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPODeleteOU']++
$Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPOEmpty']++
$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFix']++
$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFixPerDomain'][$OU.DomainName]++
} elseif ($OU.Status -contains 'Unlink GPO') {
@@ -30,8 +30,8 @@
$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFixPerDomain'][$OU.DomainName]++
} elseif ($OU.Status -contains 'Delete OU') {
$Script:Reporting['GPOOrganizationalUnit']['Variables']['DeleteOU']++
$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFix']++
$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFixPerDomain'][$OU.DomainName]++
#$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFix']++
#$Script:Reporting['GPOOrganizationalUnit']['Variables']['WillFixPerDomain'][$OU.DomainName]++
} elseif ($OU.Status -contains 'Excluded') {
$Script:Reporting['GPOOrganizationalUnit']['Variables']['Excluded']++
$Script:Reporting['GPOOrganizationalUnit']['Variables']['ExcludedOU'].Add($OU.Organizationalunit)
@@ -46,15 +46,15 @@
}
}
Variables = @{
TotalOU = 0
UnlinkGPO = 0
UnlinkGPODeleteOU = 0
DeleteOU = 0
Legitimate = 0
Excluded = 0
ExcludedOU = [System.Collections.Generic.List[string]]::new()
WillFix = 0
WillFixPerDomain = $null
TotalOU = 0
UnlinkGPO = 0
UnlinkGPOEmpty = 0
DeleteOU = 0
Legitimate = 0
Excluded = 0
ExcludedOU = [System.Collections.Generic.List[string]]::new()
WillFix = 0
WillFixPerDomain = $null
}
Overview = {
@@ -69,8 +69,8 @@
New-HTMLText -FontSize 10pt -Text "Following can happen: " -FontWeight bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Organizational Units that can have Group Policies unlinked (objects exists): ', $Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPO'] -FontWeight normal, bold
New-HTMLListItem -Text 'Organizational Units that can have Group Policies unlinked and OU removed (be careful!) (no objects): ', $Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPODeleteOU'] -FontWeight normal, bold
New-HTMLListItem -Text "Organizational Units that can be deleted (no objects/no gpos): ", $Script:Reporting['GPOOrganizationalUnit']['Variables']['DeleteOU'] -FontWeight normal, bold
New-HTMLListItem -Text 'Organizational Units that can have Group Policies unlinked (no applicable objects): ', $Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPOEmpty'] -FontWeight normal, bold
New-HTMLListItem -Text "Organizational Units that can be deleted (no objects/no gpos) - ", "optional", ": ", $Script:Reporting['GPOOrganizationalUnit']['Variables']['DeleteOU'] -FontWeight normal, bold, normal, bold -Color None, red, None, None
} -FontSize 10pt
New-HTMLText -Text 'Following domains require actions (permissions required):' -FontSize 10pt -FontWeight bold
New-HTMLList -Type Unordered {
@@ -105,10 +105,9 @@
New-HTMLText -Text @(
"While preparing this report following exclusions were defined. "
"Please make sure that when you execute your steps to include those exclusions to prevent any issues. "
) -FontSize 10pt
) -FontSize 10pt -FontWeight bold, normal -Color Red, None -LineBreak
New-HTMLText -LineBreak
New-HTMLText -Text "Code to use: " -LineBreak -FontSize 10pt -FontWeight bold
New-HTMLText -Text "Code to use for exclusions: " -FontSize 10pt -FontWeight bold -LineBreak
$Code = New-GPOZaurrExclusions -ExclusionsArray $Script:Reporting['GPOOrganizationalUnit']['Exclusions']
@@ -127,7 +126,7 @@
New-ChartBarOptions -Type bar -Distributed
New-ChartAxisY -LabelMaxWidth 200 -LabelAlign left -Show
New-ChartBar -Name "Unlink GPO ($($Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPO']))" -Value $Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPO']
New-ChartBar -Name "Unlink GPO Delete OU ($($Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPODeleteOU']))" -Value $Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPODeleteOU']
New-ChartBar -Name "Unlink GPO Delete OU ($($Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPOEmpty']))" -Value $Script:Reporting['GPOOrganizationalUnit']['Variables']['UnlinkGPOEmpty']
New-ChartBar -Name "Delete OU ($($Script:Reporting['GPOOrganizationalUnit']['Variables']['DeleteOU']))" -Value $Script:Reporting['GPOOrganizationalUnit']['Variables']['DeleteOU']
} -Title 'Organizational Units' -TitleAlignment center
}
+2 -3
View File
@@ -146,10 +146,9 @@
New-HTMLText -Text @(
"While preparing this report following exclusions were defined. "
"Please make sure that when you execute your steps to include those exclusions to prevent any issues. "
) -FontSize 10pt
) -FontSize 10pt -FontWeight bold, normal -Color Red, None -LineBreak
New-HTMLText -LineBreak
New-HTMLText -Text "Code to use: " -LineBreak -FontSize 10pt -FontWeight bold
New-HTMLText -Text "Code to use for exclusions: " -FontSize 10pt -FontWeight bold -LineBreak
$Code = New-GPOZaurrExclusions -ExclusionsArray $Script:Reporting['GPOOwners']['Exclusions']
+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
+75
View File
@@ -0,0 +1,75 @@
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) {
Write-Verbose -Message "Get-GPOZaurrUpdates - Getting OU's for $Domain"
$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
}
$CurrentCount = 0
Write-Verbose -Message "Get-GPOZaurrUpdates - Getting all GPOs for defined ranges"
[Array] $GPOs = Get-GPOZaurrAD @getGPOZaurrADSplat
foreach ($GPO in $GPOs) {
$CurrentCount++
Write-Verbose -Message "Get-GPOZaurrUpdates - Processing $($GPO.DisplayName) / $($GPO.DomainName) [$CurrentCount/$($GPOs.Count)]"
$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
}
}
}
+28 -1
View File
@@ -55,8 +55,35 @@ To understand the usage I've created blog post you may find useful
## Changelog
- 0.0.143 - 2021.10.19
- Improves `Get-GPOZaurrUpdates` with more verbose messages
- 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
- ☑ Improved `Invoke-GPOZaurr` - type `GPOOrganizationalUnit` - moving delete of OU as non-mandatory option
- 0.0.136 - 2021.08.17
- ☑ Improved wording
- 0.0.135 - 2021.08.17
- ☑ Improved exclusions
- 0.0.134 - 2021.08.16
- ☑ Improved exclusions for email use
- 0.0.133 - 2021.08.16
- ☑ Improved exclusions for email use
- 0.0.132 - 2021.08.16
- ☑ Improved exclusions for email use
- 0.0.131 - 2021.08.16
- Improved exclusions for email use
- Improved exclusions for email use
- 0.0.130 - 2021.08.13
- 💡 Updated HTML to new version of `PSWriteHTML` that fixes complains about `SearchBuilder` option
- ☑ Improved `Invoke-GPOZaurr` - type `GPOOrganizationalUnit` with exclusions