mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 20:00:09 +00:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 295f2e0a48 | |||
| 13e5672b3f | |||
| a0723227c0 | |||
| 72b2d2482b | |||
| 0c12761601 | |||
| 4ca5c8f1e7 | |||
| 53cdbdded7 | |||
| bed9da4367 | |||
| 1226c2758d | |||
| 8b2e655723 | |||
| 1061484247 | |||
| b4f014855b | |||
| 8b1bdfd39b | |||
| 1f43ec4d66 | |||
| f3f5b22090 | |||
| eb47bcd4b0 | |||
| 87a91bd632 | |||
| d0bd7b1cdc | |||
| dfff00d4cf | |||
| ba5a7e1549 | |||
| b126f397f7 | |||
| afd8e052de | |||
| 52edd47532 | |||
| da5fbf8341 | |||
| 6129aa6818 | |||
| 041639f430 | |||
| 12f79247dd | |||
| a957bc6450 | |||
| fb5b9c5024 | |||
| cb2dfe0a0f | |||
| e2950af1b6 | |||
| 1b70d39984 | |||
| 91d3776403 | |||
| b4748918f5 | |||
| a1d8393060 | |||
| 4a519004f5 | |||
| 8234c6cf50 | |||
| f50a495690 | |||
| 6c2e29122e |
@@ -1,4 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$T = Get-GPOZaurrPermission -GPOName 'Default Domain Policy' -Type 'All'
|
||||
$T = Get-GPOZaurrPermission -GPOName 'Default Domain Policy' -Type 'All' -IncludeOwner
|
||||
$T | Format-Table *
|
||||
@@ -1,4 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$T = Get-GPOZaurrPermission -Type Unknown -Verbose
|
||||
$T | Format-Table *
|
||||
$T | Out-HtmlView -ScrollX -Filtering -DisablePaging -ScrollY -Online
|
||||
@@ -1,14 +1,14 @@
|
||||
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
|
||||
# This Example shows how to deal with GPOs that have owner that doesn't exists anymore (deleted userr or diff domain) - Unknown
|
||||
# And also can fix at the same time NotAdministrative - 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-GPOZaurrOwner -IncludeSysvol #-GPOName
|
||||
$GPOs | Format-Table DisplayName, Owner, OwnerSID, OwnerType, SysvolOwner, SysvolSID, SysvolType
|
||||
$GPOs | Format-Table DisplayName, Owner, OwnerSID, OwnerType, SysvolOwner, SysvolSID, SysvolType
|
||||
|
||||
#Set-GPOZaurrOwner -Type Unknown -Verbose #-LimitProcessing 2 -WhatIf
|
||||
Set-GPOZaurrOwner -Type NotAdministrative -Verbose -LimitProcessing 2 -WhatIf
|
||||
Set-GPOZaurrOwner -Type NotAdministrative -Verbose -LimitProcessing 2 -WhatIf
|
||||
#Set-GPOZaurrOwner -Type NotMatching -Verbose -LimitProcessing 2 -WhatIf
|
||||
|
||||
#Set-GPOZaurrOwner -GPOName 'COMPUTERS | Enable Sets' -Verbose -Principal 'przemyslaw.klys' -WhatIf #-SkipSysvol
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
Get-GPOZaurrPermissionConsistency -GPOName 'Default Domain Controllers Policy' -IncludeDomains 'ad.evotec.xyz'
|
||||
|
||||
Repair-GPOZaurrPermissionConsistency -GPOName 'Default Domain Controllers Policy' -IncludeDomains 'ad.evotec.xyz' -Verbose #-WhatIf -Verbose
|
||||
Repair-GPOZaurrPermissionConsistency -GPOName 'Default Domain Controllers Policy' -IncludeDomains 'ad.evotec.xyz' -Verbose -WhatIf
|
||||
@@ -1,5 +1,5 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Get-GPOZaurrPermissionConsistency -Type All | Format-Table
|
||||
Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance | Format-Table
|
||||
|
||||
Repair-GPOZaurrPermissionConsistency -LimitProcessing 2 -WhatIf -Verbose
|
||||
@@ -1,3 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Get-GPOZaurrSysvol -Verbose | Format-Table
|
||||
Get-GPOZaurrSysvol -Verbose | Format-Table
|
||||
#Get-GPOZaurrSysvol | Out-HtmlView -ScrollX
|
||||
@@ -1,7 +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 -IncludeDomains 'ad.evotec.xyz'
|
||||
Remove-GPOZaurrOrphaned -Verbose -WhatIf -IncludeDomains 'ad.evotec.xyz' #-LimitProcessing 2
|
||||
|
||||
# this runs for whole SYSVOL and checks things against GPOS
|
||||
Remove-GPOZaurrOrphanedSysvolFolders -Verbose -IncludeDomains 'ad.evotec.xyz' -BackupPath $Env:UserProfile\Desktop\MyBackup1 #-WhatIf
|
||||
Remove-GPOZaurrOrphaned -Verbose -IncludeDomains 'ad.evotec.xyz' -BackupPath $Env:UserProfile\Desktop\MyBackup1 -WhatIf
|
||||
@@ -1,4 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
#Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExport -DeleteExisting
|
||||
Save-GPOZaurrFiles -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportEvotec' #-DeleteExisting
|
||||
Save-GPOZaurrFiles -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportEvotec' -DeleteExisting -Verbose
|
||||
@@ -1,12 +0,0 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# Asses GPO based on exported data
|
||||
$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport -Verbose
|
||||
#$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportTest' -Verbose
|
||||
$Output | Format-Table *
|
||||
|
||||
# Export to Excel
|
||||
foreach ($Key in $Output.Reports.Keys) {
|
||||
$Output.Reports[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
|
||||
}
|
||||
Start-Process "$Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx"
|
||||
@@ -1,20 +1,22 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExportEvotec1'
|
||||
#$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPODefender'
|
||||
$Output = Invoke-GPOZaurr -GPOPath 'C:\Support\GitHub\GpoZaurr\Ignore\GPOExport' -Type WindowsHelloForBusiness
|
||||
$Output | Format-Table
|
||||
$Output.Reports.RegistrySettings | Format-Table *
|
||||
$Output.Reports.InternetExplorerZones | Format-Table *
|
||||
$Output.WindowsDefenderExploitGuard | Format-Table
|
||||
$Output.Reports.RegistrySetting | Format-Table
|
||||
|
||||
# Report to Excel of translated reports
|
||||
foreach ($Key in $Output.Reports.Keys) {
|
||||
$Output.Reports[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\GPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
|
||||
foreach ($Key in $Output.Keys) {
|
||||
$Output[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\GPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
|
||||
}
|
||||
|
||||
# Report to HTML of translated reports
|
||||
New-HTML {
|
||||
foreach ($Key in $Output.Reports.Keys) {
|
||||
New-HTMLTableOption -DataStore JavaScript
|
||||
foreach ($Key in $Output.Keys) {
|
||||
New-HTMLTab -Name $Key {
|
||||
New-HTMLTable -DataTable $Output.Reports[$Key] -Filtering
|
||||
New-HTMLTable -DataTable $Output[$Key] -Filtering -Title $Key
|
||||
}
|
||||
}
|
||||
} -FilePath $Env:USERPROFILE\Desktop\GPOAnalysis.html -ShowHTML -Online
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# This gets the same thing as earlier examples
|
||||
# with a difference where one entry per gpo and all settings for that GPO is stored under settings property.
|
||||
$Output = Invoke-GPOZaurr -SingleObject
|
||||
$Output = Invoke-GPOZaurr -SingleObject -Verbose
|
||||
$Output | Format-Table
|
||||
$Output.Reports.RegistrySettings | Format-Table *
|
||||
$Output.Reports.RegistrySettings[0].Settings | Format-Table *
|
||||
@@ -1,9 +1,11 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# Use Save-GPOZaurrFiles -GPOPath $ENV:USERPROFILE\Desktop\GPOExportAudit
|
||||
$Output = Invoke-GPOZaurr -GPOPath $ENV:USERPROFILE\Desktop\GPOExportAudit -Verbose #-SkipCleanup #-Type PoliciesPrinters, Policies
|
||||
$Output | Format-Table *
|
||||
|
||||
# This will allow you to process offline data more than once
|
||||
# It's useful for when you want to request different types
|
||||
$Output = Invoke-GPOZaurr -GPOPath $ENV:USERPROFILE\Desktop\GPOExportAudit -Extended -Verbose
|
||||
$Output | Format-Table *
|
||||
$Output.Reports | Format-Table
|
||||
|
||||
# Export to Excel
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$Output = Invoke-GPOZaurr -Verbose -OutputType HTML, Object -Open
|
||||
$Output | Format-Table
|
||||
@@ -0,0 +1,23 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# Asses GPO based on exported data
|
||||
$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport_2020.10.12 -Verbose -Type RegistrySetting
|
||||
$Output | Format-Table *
|
||||
|
||||
|
||||
# Export to Excel
|
||||
foreach ($Key in $Output.Keys) {
|
||||
$Output[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
|
||||
}
|
||||
# Show the Excel
|
||||
Start-Process "$Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx"
|
||||
|
||||
# Show HTML
|
||||
New-HTML {
|
||||
New-HTMLTableOption -DataStore JavaScript
|
||||
foreach ($Key in $Output.Keys) {
|
||||
New-HTMLTab -Name $Key {
|
||||
New-HTMLTable -DataTable $Output[$Key] -Filtering -Title $Key
|
||||
}
|
||||
}
|
||||
} -FilePath $Env:USERPROFILE\Desktop\EFGPOAnalysis.html -ShowHTML -Online
|
||||
@@ -0,0 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$Output = Invoke-GPOZaurr -GPOPath $ENV:USERPROFILE\Desktop\GPOTestingUserAccess -Verbose
|
||||
$Output | Format-Table *
|
||||
@@ -1,5 +1,81 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Invoke-GPOZaurrSupport -ComputerName 'AD1' -UserName 'przemyslaw.klys' -Type HTML
|
||||
#$Support
|
||||
# $Support.ComputerResults.GPO | select name, @{LABEL=”LinkOrder“;EXPRESSION={$_.link.linkorder}} | sort linkorder
|
||||
Invoke-GPOZaurrSupport -ComputerName 'ad1.ad.evotec.xyz' -UserName 'EVOTEC\przemyslaw.klys' -Type NativeHTML -ForceGPResult -Verbose
|
||||
|
||||
return
|
||||
#$Support1 = Invoke-GPOZaurrSupport -ComputerName 'AD1' -UserName 'przemyslaw.klys' -Type Object
|
||||
#$Support = Invoke-GPOZaurrSupport -ComputerName 'AD1' -UserName 'EVOTEC\Administrator' -Type Object
|
||||
#$Support.ComputerResults.ExtensionData
|
||||
|
||||
|
||||
foreach ($GpoType in @('UserResults', 'ComputerResults')) {
|
||||
if ($Support.$GpoType.ExtensionData) {
|
||||
foreach ($Extension in $Support.$GpoType.ExtensionData) {
|
||||
$GPOSettingTypeSplit = ($Extension.type -split ':')
|
||||
#$Extension
|
||||
#$Extension | Get-Member -MemberType Properties -ErrorAction Stop
|
||||
$KeysToLoop = $Extension | Get-Member -MemberType Properties -ErrorAction Stop | Where-Object { $_.Name -notin @($GPOSettingTypeSplit[0], 'xmlns', 'blocked', 'type') }
|
||||
foreach ($GpoSettings in $KeysToLoop.Name) {
|
||||
$Extension.$GpoSettings | Format-Table
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# $env:LOGONSERVER
|
||||
# if($env:LOGONSERVER -match "MicrosoftAccount") {"Logged on with Windows account"}
|
||||
|
||||
# If it reports \\MicrosoftAccount, they are using their Windows account to sign in instead of domain credentials.
|
||||
#You can check this by using the IF statement as shown here:
|
||||
|
||||
|
||||
#[System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
|
||||
|
||||
#[System.DirectoryServices.ActiveDirectory.DomainController]::
|
||||
|
||||
# https://concurrency.com/blog/may-2018/domain-controller-selection
|
||||
#echo %logonserver% - This shows the DC that was used to authenticate and log in the current user
|
||||
#nltest /dsgetsite - This shows the AD site that the current server has detected that it's in
|
||||
#nltest /dclist: (include the colon at the end) - This shows the list of DCs in the current domain, including which site each is in.
|
||||
# nslookup -type=srv _ldap._tcp.mydomain.local. - This will query the primary DNS server for all domain controller SRV records. This should return all of the DCs in the domain. In this example, MGLABDC4 and MGLABDC5 are returned.
|
||||
# nslookup -type=srv _ldap._tcp.mysitename._sites.dc._msdcs.mydomain.local. - This will query the primary DNS server for domain controllers that are registered in "mysitename". In this example, only MGLABDC4 is in the site that was queried, which matches the information we found with nltest /dclist: previously.
|
||||
|
||||
|
||||
# Windows 10
|
||||
|
||||
#Add-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'
|
||||
#Add-WindowsCapability -Online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0'
|
||||
#Remove-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'
|
||||
|
||||
Write-Output %logonserver%
|
||||
nltest /dsgetsite
|
||||
nltest /dclist:
|
||||
|
||||
$env:LOGONSERVER
|
||||
[System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
|
||||
nslookup -type=srv _ldap._tcp.ad.colmore.com.
|
||||
nslookup -type=srv _ldap._tcp.birmingham._sites.dc._msdcs.ad.colmore.com.
|
||||
|
||||
|
||||
function Get-PreData {
|
||||
param(
|
||||
|
||||
)
|
||||
[PSCustomObject] @{
|
||||
Site = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ComputerDataInformation {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[string] $ComputerName = $Env:COMPUTERNAME
|
||||
)
|
||||
[PSCustomObject] @{
|
||||
Bios = Get-ComputerBios -ComputerName $ComputerName
|
||||
Network = Get-ComputerNetwork -ComputerName $ComputerName
|
||||
NetworkCard = Get-ComputerNetworkCard -ComputerName $ComputerName
|
||||
}
|
||||
}
|
||||
Get-ComputerDataInformation -ComputerName 'AD1.AD.EVOTEC.XYZ'
|
||||
#Get-ComputerNetwork -ComputerName 'AD1.AD.EVOTEC.XYZ' #| Format-Table
|
||||
@@ -0,0 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
ConvertFrom-CSExtension -CSE '{FC715823-C5FB-11D1-9EEF-00A0C90347FF}'
|
||||
ConvertFrom-CSExtension -CSE '{A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B}'
|
||||
@@ -0,0 +1,10 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# Default Permissions:
|
||||
# 'GpoApply', 'GpoEdit', 'GPOCustom', 'GpoEditDeleteModifySecurity', 'GPORead'
|
||||
# If you want to see also owners
|
||||
# 'GpoOwner'
|
||||
# If you want to include Root Level Permissions
|
||||
# 'GpoRootCreate', 'GpoRootOwner'
|
||||
$SummaryPermission = Get-GPOZaurrPermissionSummary -IncludePermissionType 'GpoCustom', 'GpoEdit', 'GpoEditDeleteModifySecurity', 'GpoOwner', 'GpoRootCreate', 'GpoRootOwner'
|
||||
$SummaryPermission | Sort-Object -Property Permission | Format-Table
|
||||
@@ -0,0 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Get-GPOZaurrPermissionRoot -Verbose | Format-Table *
|
||||
@@ -0,0 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$FilesAll = Get-GPOZaurrNetlogon
|
||||
$FilesAll | Format-Table -a *
|
||||
+20
-15
@@ -1,29 +1,34 @@
|
||||
@{
|
||||
AliasesToExport = 'Get-GPOZaurrFilesPolicyDefinitions', 'Find-GPO'
|
||||
AliasesToExport = @('Get-GPOZaurrFilesPolicyDefinitions', 'Find-GPO')
|
||||
Author = 'Przemyslaw Klys'
|
||||
CmdletsToExport = @()
|
||||
CompanyName = 'Evotec'
|
||||
CompatiblePSEditions = 'Desktop'
|
||||
CompatiblePSEditions = @('Desktop')
|
||||
Copyright = '(c) 2011 - 2020 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-GPOZaurrDictionary', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvol', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrOrphanedSysvolFolders', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner'
|
||||
FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvol', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrOrphaned', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Show-GPOZaurr')
|
||||
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
|
||||
ModuleVersion = '0.0.57'
|
||||
ModuleVersion = '0.0.63'
|
||||
PowerShellVersion = '5.1'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = 'Windows', 'ActiveDirectory', 'GPO', 'GroupPolicy'
|
||||
Tags = @('Windows', 'ActiveDirectory', 'GPO', 'GroupPolicy')
|
||||
ProjectUri = 'https://github.com/EvotecIT/GPOZaurr'
|
||||
ExternalModuleDependencies = 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility'
|
||||
ExternalModuleDependencies = @('CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility')
|
||||
}
|
||||
}
|
||||
RequiredModules = @{
|
||||
ModuleVersion = '0.0.168'
|
||||
ModuleName = 'PSSharedGoods'
|
||||
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
|
||||
}, @{
|
||||
ModuleVersion = '0.0.67'
|
||||
ModuleName = 'ADEssentials'
|
||||
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
|
||||
}, 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility'
|
||||
RequiredModules = @(@{
|
||||
ModuleVersion = '0.0.183'
|
||||
ModuleName = 'PSSharedGoods'
|
||||
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
|
||||
}, @{
|
||||
ModuleVersion = '0.0.99'
|
||||
ModuleName = 'ADEssentials'
|
||||
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
|
||||
}, @{
|
||||
ModuleVersion = '0.0.112'
|
||||
ModuleName = 'PSWriteHTML'
|
||||
Guid = 'a7bdf640-f5cb-4acf-9de0-365b322d245c'
|
||||
}, 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility')
|
||||
RootModule = 'GPOZaurr.psm1'
|
||||
}
|
||||
@@ -1,39 +1,95 @@
|
||||
function ConvertTo-XMLAccountPolicy {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[PSCustomObject] $GPO
|
||||
[PSCustomObject] $GPO,
|
||||
[switch] $SingleObject
|
||||
)
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
ClearTextPassword = 'Not Set'
|
||||
LockoutBadCount = 'Not Set'
|
||||
LockoutDuration = 'Not Set'
|
||||
MaximumPasswordAge = 'Not Set'
|
||||
MinimumPasswordAge = 'Not Set'
|
||||
MinimumPasswordLength = 'Not Set'
|
||||
PasswordComplexity = 'Not Set'
|
||||
PasswordHistorySize = 'Not Set'
|
||||
ResetLockoutCount = 'Not Set'
|
||||
MaxClockSkew = 'Not Set'
|
||||
MaxRenewAge = 'Not Set'
|
||||
MaxServiceAge = 'Not Set'
|
||||
MaxTicketAge = 'Not Set'
|
||||
TicketValidateClient = 'Not Set'
|
||||
}
|
||||
foreach ($GPOEntry in $GPO.DataSet) {
|
||||
if ($GPOEntry.SettingBoolean) {
|
||||
$CreateGPO[$($GPOEntry.Name)] = if ($GPOEntry.SettingBoolean -eq 'true') { 'Enabled' } elseif ($GPOEntry.SettingBoolean -eq 'false') { 'Disabled' } else { 'Not set' };
|
||||
} elseif ($GPOEntry.SettingNumber) {
|
||||
$CreateGPO[$($GPOEntry.Name)] = [int] $GPOEntry.SettingNumber
|
||||
if ($SingleObject) {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
Count = 0
|
||||
Settings = $null
|
||||
}
|
||||
[Array] $CreateGPO['Settings'] = @(
|
||||
$Settings = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
ClearTextPassword = 'Not Set'
|
||||
LockoutBadCount = 'Not Set'
|
||||
LockoutDuration = 'Not Set'
|
||||
MaximumPasswordAge = 'Not Set'
|
||||
MinimumPasswordAge = 'Not Set'
|
||||
MinimumPasswordLength = 'Not Set'
|
||||
PasswordComplexity = 'Not Set'
|
||||
PasswordHistorySize = 'Not Set'
|
||||
ResetLockoutCount = 'Not Set'
|
||||
MaxClockSkew = 'Not Set'
|
||||
MaxRenewAge = 'Not Set'
|
||||
MaxServiceAge = 'Not Set'
|
||||
MaxTicketAge = 'Not Set'
|
||||
TicketValidateClient = 'Not Set'
|
||||
}
|
||||
foreach ($GPOEntry in $GPO.DataSet) {
|
||||
if ($GPOEntry.SettingBoolean) {
|
||||
$Settings[$($GPOEntry.Name)] = if ($GPOEntry.SettingBoolean -eq 'true') { 'Enabled' } elseif ($GPOEntry.SettingBoolean -eq 'false') { 'Disabled' } else { 'Not set' };
|
||||
} elseif ($GPOEntry.SettingNumber) {
|
||||
$Settings[$($GPOEntry.Name)] = [int] $GPOEntry.SettingNumber
|
||||
}
|
||||
}
|
||||
[PSCustomObject] $Settings
|
||||
)
|
||||
|
||||
|
||||
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
ClearTextPassword = 'Not Set'
|
||||
LockoutBadCount = 'Not Set'
|
||||
LockoutDuration = 'Not Set'
|
||||
MaximumPasswordAge = 'Not Set'
|
||||
MinimumPasswordAge = 'Not Set'
|
||||
MinimumPasswordLength = 'Not Set'
|
||||
PasswordComplexity = 'Not Set'
|
||||
PasswordHistorySize = 'Not Set'
|
||||
ResetLockoutCount = 'Not Set'
|
||||
MaxClockSkew = 'Not Set'
|
||||
MaxRenewAge = 'Not Set'
|
||||
MaxServiceAge = 'Not Set'
|
||||
MaxTicketAge = 'Not Set'
|
||||
TicketValidateClient = 'Not Set'
|
||||
}
|
||||
foreach ($GPOEntry in $GPO.DataSet) {
|
||||
if ($GPOEntry.SettingBoolean) {
|
||||
$CreateGPO[$($GPOEntry.Name)] = if ($GPOEntry.SettingBoolean -eq 'true') { 'Enabled' } elseif ($GPOEntry.SettingBoolean -eq 'false') { 'Disabled' } else { 'Not set' };
|
||||
} elseif ($GPOEntry.SettingNumber) {
|
||||
$CreateGPO[$($GPOEntry.Name)] = [int] $GPOEntry.SettingNumber
|
||||
}
|
||||
}
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
}
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
}
|
||||
+217
-102
@@ -2,7 +2,7 @@
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[PSCustomObject] $GPO,
|
||||
[switch] $FullObject
|
||||
[switch] $SingleObject
|
||||
)
|
||||
$SettingType = @{
|
||||
'0' = 'No Auditing'
|
||||
@@ -10,107 +10,222 @@
|
||||
'2' = 'Failure'
|
||||
'3' = 'Success, Failure'
|
||||
}
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
AuditAccountLogon = 'Not configured'
|
||||
AuditAccountManage = 'Not configured'
|
||||
AuditDSAccess = 'Not configured'
|
||||
AuditLogonEvents = 'Not configured'
|
||||
AuditObjectAccess = 'Not configured'
|
||||
AuditPolicyChange = 'Not configured'
|
||||
AuditPrivilegeUse = 'Not configured'
|
||||
AuditProcessTracking = 'Not configured'
|
||||
AuditSystemEvents = 'Not configured'
|
||||
# Advanced Policies
|
||||
AuditAccountLockout = 'Not configured'
|
||||
AuditApplicationGenerated = 'Not configured'
|
||||
AuditApplicationGroupManagement = 'Not configured'
|
||||
AuditAuditPolicyChange = 'Not configured'
|
||||
AuditAuthenticationPolicyChange = 'Not configured'
|
||||
AuditAuthorizationPolicyChange = 'Not configured'
|
||||
AuditCentralAccessPolicyStaging = 'Not configured'
|
||||
AuditCertificationServices = 'Not configured'
|
||||
AuditComputerAccountManagement = 'Not configured'
|
||||
AuditCredentialValidation = 'Not configured'
|
||||
AuditDetailedDirectoryServiceReplication = 'Not configured'
|
||||
AuditDetailedFileShare = 'Not configured'
|
||||
AuditDirectoryServiceAccess = 'Not configured'
|
||||
AuditDirectoryServiceChanges = 'Not configured'
|
||||
AuditDirectoryServiceReplication = 'Not configured'
|
||||
AuditDistributionGroupManagement = 'Not configured'
|
||||
AuditDPAPIActivity = 'Not configured'
|
||||
AuditFileShare = 'Not configured'
|
||||
AuditFileSystem = 'Not configured'
|
||||
AuditFilteringPlatformConnection = 'Not configured'
|
||||
AuditFilteringPlatformPacketDrop = 'Not configured'
|
||||
AuditFilteringPlatformPolicyChange = 'Not configured'
|
||||
AuditGroupMembership = 'Not configured'
|
||||
AuditHandleManipulation = 'Not configured'
|
||||
AuditIPsecDriver = 'Not configured'
|
||||
AuditIPsecExtendedMode = 'Not configured'
|
||||
AuditIPsecMainMode = 'Not configured'
|
||||
AuditIPsecQuickMode = 'Not configured'
|
||||
AuditKerberosAuthenticationService = 'Not configured'
|
||||
AuditKerberosServiceTicketOperations = 'Not configured'
|
||||
AuditKernelObject = 'Not configured'
|
||||
AuditLogoff = 'Not configured'
|
||||
AuditLogon = 'Not configured'
|
||||
AuditMPSSVCRuleLevelPolicyChange = 'Not configured'
|
||||
AuditNetworkPolicyServer = 'Not configured'
|
||||
AuditNonSensitivePrivilegeUse = 'Not configured'
|
||||
AuditOtherAccountLogonEvents = 'Not configured'
|
||||
AuditOtherAccountManagementEvents = 'Not configured'
|
||||
AuditOtherLogonLogoffEvents = 'Not configured'
|
||||
AuditOtherObjectAccessEvents = 'Not configured'
|
||||
AuditOtherPolicyChangeEvents = 'Not configured'
|
||||
AuditOtherPrivilegeUseEvents = 'Not configured'
|
||||
AuditOtherSystemEvents = 'Not configured'
|
||||
AuditPNPActivity = 'Not configured'
|
||||
AuditProcessCreation = 'Not configured'
|
||||
AuditProcessTermination = 'Not configured'
|
||||
AuditRegistry = 'Not configured'
|
||||
AuditRemovableStorage = 'Not configured'
|
||||
AuditRPCEvents = 'Not configured'
|
||||
AuditSAM = 'Not configured'
|
||||
AuditSecurityGroupManagement = 'Not configured'
|
||||
AuditSecurityStateChange = 'Not configured'
|
||||
AuditSecuritySystemExtension = 'Not configured'
|
||||
AuditSensitivePrivilegeUse = 'Not configured'
|
||||
AuditSpecialLogon = 'Not configured'
|
||||
AuditSystemIntegrity = 'Not configured'
|
||||
AuditUserDeviceClaims = 'Not configured'
|
||||
AuditUserAccountManagement = 'Not configured'
|
||||
}
|
||||
foreach ($GPOEntry in $GPO.DataSet) {
|
||||
if ($GPOEntry.PolicyTarget) {
|
||||
# Category = 'AuditSettings', Settings = 'AuditSetting'
|
||||
$Category = $GPOEntry.SubcategoryName -replace ' ', '' -replace '-', '' -replace '/', ''
|
||||
if ($CreateGPO["$($Category)"]) {
|
||||
$CreateGPO["$($Category)"] = $SettingType["$($GPOEntry.SettingValue)"]
|
||||
}
|
||||
} else {
|
||||
# Category = 'SecuritySettings', Settings = 'Audit'
|
||||
$SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null };
|
||||
$FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null };
|
||||
if ($SuccessAttempts -and $FailureAttempts) {
|
||||
$Setting = 'Success, Failure'
|
||||
} elseif ($SuccessAttempts) {
|
||||
$Setting = 'Success'
|
||||
} elseif ($FailureAttempts) {
|
||||
$Setting = 'Failure'
|
||||
} else {
|
||||
$Setting = 'Not configured'
|
||||
}
|
||||
$CreateGPO["$($GPOEntry.Name)"] = $Setting
|
||||
if ($SingleObject) {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
Count = 0
|
||||
Settings = $null
|
||||
}
|
||||
[Array] $CreateGPO['Settings'] = @(
|
||||
$Settings = [ordered]@{
|
||||
AuditAccountLogon = 'Not configured'
|
||||
AuditAccountManage = 'Not configured'
|
||||
AuditDSAccess = 'Not configured'
|
||||
AuditLogonEvents = 'Not configured'
|
||||
AuditObjectAccess = 'Not configured'
|
||||
AuditPolicyChange = 'Not configured'
|
||||
AuditPrivilegeUse = 'Not configured'
|
||||
AuditProcessTracking = 'Not configured'
|
||||
AuditSystemEvents = 'Not configured'
|
||||
# Advanced Policies
|
||||
AuditAccountLockout = 'Not configured'
|
||||
AuditApplicationGenerated = 'Not configured'
|
||||
AuditApplicationGroupManagement = 'Not configured'
|
||||
AuditAuditPolicyChange = 'Not configured'
|
||||
AuditAuthenticationPolicyChange = 'Not configured'
|
||||
AuditAuthorizationPolicyChange = 'Not configured'
|
||||
AuditCentralAccessPolicyStaging = 'Not configured'
|
||||
AuditCertificationServices = 'Not configured'
|
||||
AuditComputerAccountManagement = 'Not configured'
|
||||
AuditCredentialValidation = 'Not configured'
|
||||
AuditDetailedDirectoryServiceReplication = 'Not configured'
|
||||
AuditDetailedFileShare = 'Not configured'
|
||||
AuditDirectoryServiceAccess = 'Not configured'
|
||||
AuditDirectoryServiceChanges = 'Not configured'
|
||||
AuditDirectoryServiceReplication = 'Not configured'
|
||||
AuditDistributionGroupManagement = 'Not configured'
|
||||
AuditDPAPIActivity = 'Not configured'
|
||||
AuditFileShare = 'Not configured'
|
||||
AuditFileSystem = 'Not configured'
|
||||
AuditFilteringPlatformConnection = 'Not configured'
|
||||
AuditFilteringPlatformPacketDrop = 'Not configured'
|
||||
AuditFilteringPlatformPolicyChange = 'Not configured'
|
||||
AuditGroupMembership = 'Not configured'
|
||||
AuditHandleManipulation = 'Not configured'
|
||||
AuditIPsecDriver = 'Not configured'
|
||||
AuditIPsecExtendedMode = 'Not configured'
|
||||
AuditIPsecMainMode = 'Not configured'
|
||||
AuditIPsecQuickMode = 'Not configured'
|
||||
AuditKerberosAuthenticationService = 'Not configured'
|
||||
AuditKerberosServiceTicketOperations = 'Not configured'
|
||||
AuditKernelObject = 'Not configured'
|
||||
AuditLogoff = 'Not configured'
|
||||
AuditLogon = 'Not configured'
|
||||
AuditMPSSVCRuleLevelPolicyChange = 'Not configured'
|
||||
AuditNetworkPolicyServer = 'Not configured'
|
||||
AuditNonSensitivePrivilegeUse = 'Not configured'
|
||||
AuditOtherAccountLogonEvents = 'Not configured'
|
||||
AuditOtherAccountManagementEvents = 'Not configured'
|
||||
AuditOtherLogonLogoffEvents = 'Not configured'
|
||||
AuditOtherObjectAccessEvents = 'Not configured'
|
||||
AuditOtherPolicyChangeEvents = 'Not configured'
|
||||
AuditOtherPrivilegeUseEvents = 'Not configured'
|
||||
AuditOtherSystemEvents = 'Not configured'
|
||||
AuditPNPActivity = 'Not configured'
|
||||
AuditProcessCreation = 'Not configured'
|
||||
AuditProcessTermination = 'Not configured'
|
||||
AuditRegistry = 'Not configured'
|
||||
AuditRemovableStorage = 'Not configured'
|
||||
AuditRPCEvents = 'Not configured'
|
||||
AuditSAM = 'Not configured'
|
||||
AuditSecurityGroupManagement = 'Not configured'
|
||||
AuditSecurityStateChange = 'Not configured'
|
||||
AuditSecuritySystemExtension = 'Not configured'
|
||||
AuditSensitivePrivilegeUse = 'Not configured'
|
||||
AuditSpecialLogon = 'Not configured'
|
||||
AuditSystemIntegrity = 'Not configured'
|
||||
AuditUserDeviceClaims = 'Not configured'
|
||||
AuditUserAccountManagement = 'Not configured'
|
||||
}
|
||||
foreach ($GPOEntry in $GPO.DataSet) {
|
||||
if ($GPOEntry.PolicyTarget) {
|
||||
# Category = 'AuditSettings', Settings = 'AuditSetting'
|
||||
$Category = $GPOEntry.SubcategoryName -replace ' ', '' -replace '-', '' -replace '/', ''
|
||||
if ($Settings["$($Category)"]) {
|
||||
$Settings["$($Category)"] = $SettingType["$($GPOEntry.SettingValue)"]
|
||||
}
|
||||
} else {
|
||||
# Category = 'SecuritySettings', Settings = 'Audit'
|
||||
$SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null };
|
||||
$FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null };
|
||||
if ($SuccessAttempts -and $FailureAttempts) {
|
||||
$Setting = 'Success, Failure'
|
||||
} elseif ($SuccessAttempts) {
|
||||
$Setting = 'Success'
|
||||
} elseif ($FailureAttempts) {
|
||||
$Setting = 'Failure'
|
||||
} else {
|
||||
$Setting = 'Not configured'
|
||||
}
|
||||
$Settings["$($GPOEntry.Name)"] = $Setting
|
||||
}
|
||||
}
|
||||
[PSCustomObject] $Settings
|
||||
)
|
||||
|
||||
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
} else {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
AuditAccountLogon = 'Not configured'
|
||||
AuditAccountManage = 'Not configured'
|
||||
AuditDSAccess = 'Not configured'
|
||||
AuditLogonEvents = 'Not configured'
|
||||
AuditObjectAccess = 'Not configured'
|
||||
AuditPolicyChange = 'Not configured'
|
||||
AuditPrivilegeUse = 'Not configured'
|
||||
AuditProcessTracking = 'Not configured'
|
||||
AuditSystemEvents = 'Not configured'
|
||||
# Advanced Policies
|
||||
AuditAccountLockout = 'Not configured'
|
||||
AuditApplicationGenerated = 'Not configured'
|
||||
AuditApplicationGroupManagement = 'Not configured'
|
||||
AuditAuditPolicyChange = 'Not configured'
|
||||
AuditAuthenticationPolicyChange = 'Not configured'
|
||||
AuditAuthorizationPolicyChange = 'Not configured'
|
||||
AuditCentralAccessPolicyStaging = 'Not configured'
|
||||
AuditCertificationServices = 'Not configured'
|
||||
AuditComputerAccountManagement = 'Not configured'
|
||||
AuditCredentialValidation = 'Not configured'
|
||||
AuditDetailedDirectoryServiceReplication = 'Not configured'
|
||||
AuditDetailedFileShare = 'Not configured'
|
||||
AuditDirectoryServiceAccess = 'Not configured'
|
||||
AuditDirectoryServiceChanges = 'Not configured'
|
||||
AuditDirectoryServiceReplication = 'Not configured'
|
||||
AuditDistributionGroupManagement = 'Not configured'
|
||||
AuditDPAPIActivity = 'Not configured'
|
||||
AuditFileShare = 'Not configured'
|
||||
AuditFileSystem = 'Not configured'
|
||||
AuditFilteringPlatformConnection = 'Not configured'
|
||||
AuditFilteringPlatformPacketDrop = 'Not configured'
|
||||
AuditFilteringPlatformPolicyChange = 'Not configured'
|
||||
AuditGroupMembership = 'Not configured'
|
||||
AuditHandleManipulation = 'Not configured'
|
||||
AuditIPsecDriver = 'Not configured'
|
||||
AuditIPsecExtendedMode = 'Not configured'
|
||||
AuditIPsecMainMode = 'Not configured'
|
||||
AuditIPsecQuickMode = 'Not configured'
|
||||
AuditKerberosAuthenticationService = 'Not configured'
|
||||
AuditKerberosServiceTicketOperations = 'Not configured'
|
||||
AuditKernelObject = 'Not configured'
|
||||
AuditLogoff = 'Not configured'
|
||||
AuditLogon = 'Not configured'
|
||||
AuditMPSSVCRuleLevelPolicyChange = 'Not configured'
|
||||
AuditNetworkPolicyServer = 'Not configured'
|
||||
AuditNonSensitivePrivilegeUse = 'Not configured'
|
||||
AuditOtherAccountLogonEvents = 'Not configured'
|
||||
AuditOtherAccountManagementEvents = 'Not configured'
|
||||
AuditOtherLogonLogoffEvents = 'Not configured'
|
||||
AuditOtherObjectAccessEvents = 'Not configured'
|
||||
AuditOtherPolicyChangeEvents = 'Not configured'
|
||||
AuditOtherPrivilegeUseEvents = 'Not configured'
|
||||
AuditOtherSystemEvents = 'Not configured'
|
||||
AuditPNPActivity = 'Not configured'
|
||||
AuditProcessCreation = 'Not configured'
|
||||
AuditProcessTermination = 'Not configured'
|
||||
AuditRegistry = 'Not configured'
|
||||
AuditRemovableStorage = 'Not configured'
|
||||
AuditRPCEvents = 'Not configured'
|
||||
AuditSAM = 'Not configured'
|
||||
AuditSecurityGroupManagement = 'Not configured'
|
||||
AuditSecurityStateChange = 'Not configured'
|
||||
AuditSecuritySystemExtension = 'Not configured'
|
||||
AuditSensitivePrivilegeUse = 'Not configured'
|
||||
AuditSpecialLogon = 'Not configured'
|
||||
AuditSystemIntegrity = 'Not configured'
|
||||
AuditUserDeviceClaims = 'Not configured'
|
||||
AuditUserAccountManagement = 'Not configured'
|
||||
}
|
||||
foreach ($GPOEntry in $GPO.DataSet) {
|
||||
if ($GPOEntry.PolicyTarget) {
|
||||
# Category = 'AuditSettings', Settings = 'AuditSetting'
|
||||
$Category = $GPOEntry.SubcategoryName -replace ' ', '' -replace '-', '' -replace '/', ''
|
||||
if ($CreateGPO["$($Category)"]) {
|
||||
$CreateGPO["$($Category)"] = $SettingType["$($GPOEntry.SettingValue)"]
|
||||
}
|
||||
} else {
|
||||
# Category = 'SecuritySettings', Settings = 'Audit'
|
||||
$SuccessAttempts = try { [bool]::Parse($GPOEntry.SuccessAttempts) } catch { $null };
|
||||
$FailureAttempts = try { [bool]::Parse($GPOEntry.FailureAttempts) } catch { $null };
|
||||
if ($SuccessAttempts -and $FailureAttempts) {
|
||||
$Setting = 'Success, Failure'
|
||||
} elseif ($SuccessAttempts) {
|
||||
$Setting = 'Success'
|
||||
} elseif ($FailureAttempts) {
|
||||
$Setting = 'Failure'
|
||||
} else {
|
||||
$Setting = 'Not configured'
|
||||
}
|
||||
$CreateGPO["$($GPOEntry.Name)"] = $Setting
|
||||
}
|
||||
}
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
}
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
}
|
||||
@@ -2,52 +2,141 @@ function ConvertTo-XMLGenericPolicy {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[PSCustomObject] $GPO,
|
||||
[string[]] $Category
|
||||
[string[]] $Category,
|
||||
[switch] $SingleObject
|
||||
)
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
}
|
||||
$UsedNames = [System.Collections.Generic.List[string]]::new()
|
||||
|
||||
[Array] $Policies = foreach ($Cat in $Category) {
|
||||
$GPO.DataSet | Where-Object { $_.Category -like $Cat }
|
||||
}
|
||||
if ($Policies.Count -gt 0) {
|
||||
foreach ($Policy in $Policies) {
|
||||
#if ($Policy.Category -notlike $Category) {
|
||||
# We check again for Category because one GPO can have multiple categories
|
||||
# First check checks GPO globally,
|
||||
# continue
|
||||
#}
|
||||
$Name = Format-ToTitleCase -Text $Policy.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$CreateGPO[$Name] = $Policy.State
|
||||
if ($SingleObject) {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
Count = 0
|
||||
Settings = $null
|
||||
}
|
||||
|
||||
foreach ($Setting in @('DropDownList', 'Numeric', 'EditText', 'Text', 'CheckBox', 'ListBox')) {
|
||||
if ($Policy.$Setting) {
|
||||
foreach ($Value in $Policy.$Setting) {
|
||||
if ($Value.Name) {
|
||||
$SubName = Format-ToTitleCase -Text $Value.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$SubName = -join ($Name, $SubName)
|
||||
if ($SubName -notin $UsedNames) {
|
||||
$UsedNames.Add($SubName)
|
||||
[Array] $CreateGPO['Settings'] = @(
|
||||
$Settings = [ordered] @{}
|
||||
foreach ($Policy in $Policies) {
|
||||
#if ($Policy.Category -notlike $Category) {
|
||||
# We check again for Category because one GPO can have multiple categories
|
||||
# First check checks GPO globally,
|
||||
# continue
|
||||
#}
|
||||
|
||||
$Name = Format-ToTitleCase -Text $Policy.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$Settings[$Name] = $Policy.State
|
||||
|
||||
foreach ($Setting in @('DropDownList', 'Numeric', 'EditText', 'Text', 'CheckBox', 'ListBox')) {
|
||||
if ($Policy.$Setting) {
|
||||
foreach ($Value in $Policy.$Setting) {
|
||||
if ($Value.Name) {
|
||||
$SubName = Format-ToTitleCase -Text $Value.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$SubName = -join ($Name, $SubName)
|
||||
if ($SubName -notin $UsedNames) {
|
||||
$UsedNames.Add($SubName)
|
||||
} else {
|
||||
$TimesUsed = $UsedNames | Group-Object | Where-Object { $_.Name -eq $SubName }
|
||||
$NumberToUse = $TimesUsed.Count + 1
|
||||
# We add same name 2nd and 3rd time to make sure we count properly
|
||||
$UsedNames.Add($SubName)
|
||||
# We now build property name based on amnount of times
|
||||
$SubName = -join ($SubName, "$NumberToUse")
|
||||
}
|
||||
if ($Value.Value -is [string]) {
|
||||
$Settings["$SubName"] = $Value.Value
|
||||
} elseif ($Value.Value -is [System.Xml.XmlElement]) {
|
||||
|
||||
<#
|
||||
if ($null -eq $Value.Value.Name) {
|
||||
# Shouldn't happen but lets see
|
||||
Write-Verbose $Value
|
||||
} else {
|
||||
$TimesUsed = $UsedNames | Group-Object | Where-Object { $_.Name -eq $SubName }
|
||||
$NumberToUse = $TimesUsed.Count + 1
|
||||
# We add same name 2nd and 3rd time to make sure we count properly
|
||||
$UsedNames.Add($SubName)
|
||||
# We now build property name based on amnount of times
|
||||
$SubName = -join ($SubName, "$NumberToUse")
|
||||
$CreateGPO["$SubName"] = $Value.Value.Name
|
||||
}
|
||||
if ($Value.Value -is [string]) {
|
||||
$CreateGPO["$SubName"] = $Value.Value
|
||||
} elseif ($Value.Value -is [System.Xml.XmlElement]) {
|
||||
|
||||
<#
|
||||
#>
|
||||
if ($Value.Value.Element) {
|
||||
$Settings["$SubName"] = $Value.Value.Element.Data -join '; '
|
||||
} elseif ($null -eq $Value.Value.Name) {
|
||||
# Shouldn't happen but lets see
|
||||
Write-Verbose "Tracking $Value"
|
||||
} else {
|
||||
$Settings["$SubName"] = $Value.Value.Name
|
||||
}
|
||||
|
||||
} elseif ($Value.State) {
|
||||
$Settings["$SubName"] = $Value.State
|
||||
} elseif ($null -eq $Value.Value) {
|
||||
# This is most likely Setting 'Text
|
||||
# Do nothing, usually it's just a text to display
|
||||
#Write-Verbose "Skipping value for display because it's empty. Name: $($Value.Name)"
|
||||
} else {
|
||||
# shouldn't happen
|
||||
Write-Verbose $Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
[PSCustomObject] $Settings
|
||||
)
|
||||
|
||||
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
} else {
|
||||
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
}
|
||||
foreach ($Policy in $Policies) {
|
||||
#if ($Policy.Category -notlike $Category) {
|
||||
# We check again for Category because one GPO can have multiple categories
|
||||
# First check checks GPO globally,
|
||||
# continue
|
||||
#}
|
||||
$Name = Format-ToTitleCase -Text $Policy.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$CreateGPO[$Name] = $Policy.State
|
||||
|
||||
foreach ($Setting in @('DropDownList', 'Numeric', 'EditText', 'Text', 'CheckBox', 'ListBox')) {
|
||||
if ($Policy.$Setting) {
|
||||
foreach ($Value in $Policy.$Setting) {
|
||||
if ($Value.Name) {
|
||||
$SubName = Format-ToTitleCase -Text $Value.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$SubName = -join ($Name, $SubName)
|
||||
if ($SubName -notin $UsedNames) {
|
||||
$UsedNames.Add($SubName)
|
||||
} else {
|
||||
$TimesUsed = $UsedNames | Group-Object | Where-Object { $_.Name -eq $SubName }
|
||||
$NumberToUse = $TimesUsed.Count + 1
|
||||
# We add same name 2nd and 3rd time to make sure we count properly
|
||||
$UsedNames.Add($SubName)
|
||||
# We now build property name based on amnount of times
|
||||
$SubName = -join ($SubName, "$NumberToUse")
|
||||
}
|
||||
if ($Value.Value -is [string]) {
|
||||
$CreateGPO["$SubName"] = $Value.Value
|
||||
} elseif ($Value.Value -is [System.Xml.XmlElement]) {
|
||||
|
||||
<#
|
||||
if ($null -eq $Value.Value.Name) {
|
||||
# Shouldn't happen but lets see
|
||||
Write-Verbose $Value
|
||||
@@ -56,34 +145,35 @@ function ConvertTo-XMLGenericPolicy {
|
||||
}
|
||||
|
||||
#>
|
||||
if ($Value.Value.Element) {
|
||||
$CreateGPO["$SubName"] = $Value.Value.Element.Data -join '; '
|
||||
} elseif ($null -eq $Value.Value.Name) {
|
||||
# Shouldn't happen but lets see
|
||||
Write-Verbose "Tracking $Value"
|
||||
} else {
|
||||
$CreateGPO["$SubName"] = $Value.Value.Name
|
||||
}
|
||||
if ($Value.Value.Element) {
|
||||
$CreateGPO["$SubName"] = $Value.Value.Element.Data -join '; '
|
||||
} elseif ($null -eq $Value.Value.Name) {
|
||||
# Shouldn't happen but lets see
|
||||
Write-Verbose "Tracking $Value"
|
||||
} else {
|
||||
$CreateGPO["$SubName"] = $Value.Value.Name
|
||||
}
|
||||
|
||||
} elseif ($Value.State) {
|
||||
$CreateGPO["$SubName"] = $Value.State
|
||||
} elseif ($null -eq $Value.Value) {
|
||||
# This is most likely Setting 'Text
|
||||
# Do nothing, usually it's just a text to display
|
||||
#Write-Verbose "Skipping value for display because it's empty. Name: $($Value.Name)"
|
||||
} else {
|
||||
# shouldn't happen
|
||||
Write-Verbose $Value
|
||||
} elseif ($Value.State) {
|
||||
$CreateGPO["$SubName"] = $Value.State
|
||||
} elseif ($null -eq $Value.Value) {
|
||||
# This is most likely Setting 'Text
|
||||
# Do nothing, usually it's just a text to display
|
||||
#Write-Verbose "Skipping value for display because it's empty. Name: $($Value.Name)"
|
||||
} else {
|
||||
# shouldn't happen
|
||||
Write-Verbose $Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
#}
|
||||
}
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
#}
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,11 @@ function ConvertTo-XMLGenericPublicKey {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[PSCustomObject] $GPO,
|
||||
[string[]] $Category
|
||||
[string[]] $Category,
|
||||
[switch] $SingleObject
|
||||
)
|
||||
|
||||
$SkipNames = ('Name', 'LocalName', 'NamespaceURI', 'Prefix', 'NodeType', 'ParentNode', 'OwnerDocument', 'IsEmpty', 'Attributes', 'HasAttributes', 'SchemaInfo', 'InnerXml', 'InnerText', 'NextSibling', 'PreviousSibling', 'ChildNodes', 'FirstChild', 'LastChild', 'HasChildNodes', 'IsReadOnly', 'OuterXml', 'BaseURI', 'PreviousText')
|
||||
foreach ($Setting in $GPO.DataSet) {
|
||||
if ($SingleObject) {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
@@ -14,23 +14,57 @@ function ConvertTo-XMLGenericPublicKey {
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
Count = 0
|
||||
Settings = $null
|
||||
}
|
||||
$SettingName = $Setting.Name -split ":"
|
||||
$CreateGPO['CreatedTime'] = $GPO.CreatedTime # : 06.06.2020 18:03:36
|
||||
$CreateGPO['ModifiedTime'] = $GPO.ModifiedTime # : 17.06.2020 16:08:10
|
||||
$CreateGPO['ReadTime'] = $GPO.ReadTime # : 13.08.2020 10:15:37
|
||||
$CreateGPO['SecurityDescriptor'] = $GPO.SecurityDescriptor # : SecurityDescriptor
|
||||
$CreateGPO['FilterDataAvailable'] = $GPO.FilterDataAvailable # : True
|
||||
[Array] $CreateGPO['Settings'] = foreach ($Setting in $GPO.DataSet) {
|
||||
$SettingName = $Setting.Name -split ":"
|
||||
$MySettings = [ordered] @{
|
||||
CreatedTime = $GPO.CreatedTime # : 06.06.2020 18:03:36
|
||||
ModifiedTime = $GPO.ModifiedTime # : 17.06.2020 16:08:10
|
||||
ReadTime = $GPO.ReadTime # : 13.08.2020 10:15:37
|
||||
SecurityDescriptor = $GPO.SecurityDescriptor # : SecurityDescriptor
|
||||
FilterDataAvailable = $GPO.FilterDataAvailable # : True
|
||||
}
|
||||
$Name = $SettingName[1]
|
||||
#$Name = Format-ToTitleCase -Text $Setting.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$MySettings['Name'] = $Name # $Setting.Name
|
||||
|
||||
$Name = $SettingName[1]
|
||||
#$Name = Format-ToTitleCase -Text $Setting.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$CreateGPO['Name'] = $Name # $Setting.Name
|
||||
#$CreateGPO['GPOSettingOrder'] = $Setting.GPOSettingOrder
|
||||
ConvertTo-XMLNested -CreateGPO $MySettings -Setting $Setting -SkipNames $SkipNames #-Name $Name
|
||||
[PSCustomObject] $MySettings
|
||||
}
|
||||
|
||||
#foreach ($Property in ($Setting.Properties | Get-Member -MemberType Properties).Name) {
|
||||
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
} else {
|
||||
foreach ($Setting in $GPO.DataSet) {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
}
|
||||
$SettingName = $Setting.Name -split ":"
|
||||
$CreateGPO['CreatedTime'] = $GPO.CreatedTime # : 06.06.2020 18:03:36
|
||||
$CreateGPO['ModifiedTime'] = $GPO.ModifiedTime # : 17.06.2020 16:08:10
|
||||
$CreateGPO['ReadTime'] = $GPO.ReadTime # : 13.08.2020 10:15:37
|
||||
$CreateGPO['SecurityDescriptor'] = $GPO.SecurityDescriptor # : SecurityDescriptor
|
||||
$CreateGPO['FilterDataAvailable'] = $GPO.FilterDataAvailable # : True
|
||||
|
||||
ConvertTo-XMLNested -CreateGPO $CreateGPO -Setting $Setting -SkipNames $SkipNames #-Name $Name
|
||||
<#
|
||||
$Name = $SettingName[1]
|
||||
#$Name = Format-ToTitleCase -Text $Setting.Name -RemoveWhiteSpace -RemoveChar ',', '-', "'", '\(', '\)', ':'
|
||||
$CreateGPO['Name'] = $Name # $Setting.Name
|
||||
#$CreateGPO['GPOSettingOrder'] = $Setting.GPOSettingOrder
|
||||
|
||||
#foreach ($Property in ($Setting.Properties | Get-Member -MemberType Properties).Name) {
|
||||
|
||||
ConvertTo-XMLNested -CreateGPO $CreateGPO -Setting $Setting -SkipNames $SkipNames #-Name $Name
|
||||
<#
|
||||
$Properties = $Setting.PSObject.Properties.Name | Where-Object { $_ -notin $SkipNames }
|
||||
foreach ($Property in $Properties) {
|
||||
If ($Property -eq 'Value') {
|
||||
@@ -62,13 +96,11 @@ function ConvertTo-XMLGenericPublicKey {
|
||||
}
|
||||
}
|
||||
#>
|
||||
|
||||
|
||||
$CreateGPO['Filters'] = $Setting.Filters
|
||||
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
$CreateGPO['Filters'] = $Setting.Filters
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ function ConvertTo-XMLGenericSecuritySettings {
|
||||
[string[]] $Category
|
||||
)
|
||||
$SkipNames = ('Name', 'LocalName', 'NamespaceURI', 'Prefix', 'NodeType', 'ParentNode', 'OwnerDocument', 'IsEmpty', 'Attributes', 'HasAttributes', 'SchemaInfo', 'InnerXml', 'InnerText', 'NextSibling', 'PreviousSibling', 'Value', 'ChildNodes', 'FirstChild', 'LastChild', 'HasChildNodes', 'IsReadOnly', 'OuterXml', 'BaseURI', 'PreviousText')
|
||||
$UsedNames = [System.Collections.Generic.List[string]]::new()
|
||||
#$UsedNames = [System.Collections.Generic.List[string]]::new()
|
||||
[Array] $Settings = foreach ($Cat in $Category) {
|
||||
$GPO.DataSet | Where-Object { $null -ne $_.$Cat }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
function ConvertTo-XMLUserRightsAssignment {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[PSCustomObject] $GPO,
|
||||
[switch] $SingleObject
|
||||
)
|
||||
|
||||
$UserRightsTranslation = @{
|
||||
SeNetworkLogonRight = 'Access this computer from the network'
|
||||
SeMachineAccountPrivilege = 'Add workstations to domain'
|
||||
SeIncreaseQuotaPrivilege = 'Adjust memory quotas for a process'
|
||||
SeInteractiveLogonRight = 'Allow log on locally'
|
||||
SeBackupPrivilege = 'Back up files and directories'
|
||||
SeChangeNotifyPrivilege = 'Bypass traverse checking Everyone'
|
||||
SeSystemTimePrivilege = 'Change the system time'
|
||||
SeCreatePagefilePrivilege = 'Create a pagefile'
|
||||
SeDebugPrivilege = 'Debug programs'
|
||||
SeEnableDelegationPrivilege = 'Enable computer and user accounts to be trusted for delegation'
|
||||
SeRemoteShutdownPrivilege = 'Force shutdown from a remote system'
|
||||
SeAuditPrivilege = 'Generate security audits'
|
||||
SeIncreaseBasePriorityPrivilege = 'Increase scheduling priority'
|
||||
SeLoadDriverPrivilege = 'Load and unload device drivers'
|
||||
SeBatchLogonRight = 'Log on as a batch job'
|
||||
SeSecurityPrivilege = 'Manage auditing and security log'
|
||||
SeSystemEnvironmentPrivilege = 'Modify firmware environment values'
|
||||
SeProfileSingleProcessPrivilege = 'Profile single process'
|
||||
SeSystemProfilePrivilege = 'Profile system performance'
|
||||
SeUndockPrivilege = 'Remove computer from docking station'
|
||||
SeAssignPrimaryTokenPrivilege = 'Replace a process level token'
|
||||
SeRestorePrivilege = 'Restore files and directories'
|
||||
SeShutdownPrivilege = 'Shut down the system'
|
||||
SeTakeOwnershipPrivilege = 'Take ownership of files or other objects'
|
||||
}
|
||||
|
||||
if ($SingleObject) {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
Count = 0
|
||||
Settings = $null
|
||||
}
|
||||
[Array] $CreateGPO['Settings'] = foreach ($Entry in $GPO.DataSet) {
|
||||
foreach ($Member in $Entry.Member) {
|
||||
[PSCustomObject]@{
|
||||
'UserRightsAssignment' = $Entry.Name
|
||||
'UserRightsAssignmentDescription' = $UserRightsTranslation[$Entry.Name]
|
||||
'Name' = $Member.Name.'#text'
|
||||
'Sid' = $Member.SID.'#text'
|
||||
}
|
||||
}
|
||||
}
|
||||
$CreateGPO['Count'] = $CreateGPO['Settings'].Count
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
} else {
|
||||
foreach ($Entry in $GPO.DataSet) {
|
||||
foreach ($Member in $Entry.Member) {
|
||||
$CreateGPO = [ordered]@{
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
GpoType = $GPO.GpoType
|
||||
#GpoCategory = $GPOEntry.GpoCategory
|
||||
#GpoSettings = $GPOEntry.GpoSettings
|
||||
}
|
||||
$CreateGPO['UserRightsAssignment'] = $Entry.Name
|
||||
$CreateGPO['UserRightsAssignmentDescription'] = $UserRightsTranslation[$Entry.Name]
|
||||
$CreateGPO['Name'] = $Member.Name.'#text'
|
||||
$CreateGPO['Sid'] = $Member.SID.'#text'
|
||||
#$CreateGPO['CreatedTime'] = $GPO.CreatedTime # : 06.06.2020 18:03:36
|
||||
#$CreateGPO['ModifiedTime'] = $GPO.ModifiedTime # : 17.06.2020 16:08:10
|
||||
#$CreateGPO['ReadTime'] = $GPO.ReadTime # : 13.08.2020 10:15:37
|
||||
$CreateGPO['Linked'] = $GPO.Linked
|
||||
$CreateGPO['LinksCount'] = $GPO.LinksCount
|
||||
$CreateGPO['Links'] = $GPO.Links
|
||||
[PSCustomObject] $CreateGPO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+196
-98
@@ -5,7 +5,7 @@
|
||||
[Object] $SecurityRights,
|
||||
|
||||
[string[]] $Principal,
|
||||
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
|
||||
[validateset('DistinguishedName', 'Name', 'NetbiosName', 'Sid')][string] $PrincipalType = 'Sid',
|
||||
|
||||
[switch] $SkipWellKnown,
|
||||
[switch] $SkipAdministrative,
|
||||
@@ -20,7 +20,7 @@
|
||||
[switch] $IncludeGPOObject,
|
||||
[System.Collections.IDictionary] $ADAdministrativeGroups,
|
||||
[validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All',
|
||||
[System.Collections.IDictionary] $Accounts,
|
||||
#[System.Collections.IDictionary] $Accounts,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
Begin {
|
||||
@@ -100,6 +100,11 @@
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($GPOPermission.Trustee.Domain) {
|
||||
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
|
||||
} else {
|
||||
$UserMerge = $null
|
||||
}
|
||||
if ($Principal) {
|
||||
if ($PrincipalType -eq 'Sid') {
|
||||
if ($Principal -notcontains $GPOPermission.Trustee.Sid.Value) {
|
||||
@@ -110,8 +115,11 @@
|
||||
return
|
||||
}
|
||||
} elseif ($PrincipalType -eq 'Name') {
|
||||
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
|
||||
if ($Principal -notcontains $UserMerge -and $Principal -notcontains $GPOPermission.Trustee.Name) {
|
||||
if ($Principal -notcontains $GPOPermission.Trustee.Name) {
|
||||
return
|
||||
}
|
||||
} elseif ($PrincipalType -eq 'NetbiosName') {
|
||||
if ($Principal -notcontains $UserMerge) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -126,56 +134,76 @@
|
||||
return
|
||||
}
|
||||
} elseif ($ExcludePrincipalType -eq 'Name') {
|
||||
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
|
||||
if ($ExcludePrincipal -contains $UserMerge -or $ExcludePrincipal -contains $GPOPermission.Trustee.Name) {
|
||||
if ($ExcludePrincipal -contains $GPOPermission.Trustee.Name) {
|
||||
return
|
||||
}
|
||||
} elseif ($ExcludePrincipalType -eq 'NetbiosName') {
|
||||
if ($ExcludePrincipal -contains $UserMerge) {
|
||||
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
|
||||
PermissionType = if ($GPOPermission.Denied -eq $true) { 'Deny' } else { 'Allow' }
|
||||
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 ($Accounts) {
|
||||
$A = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
|
||||
if ($A -and $Accounts[$A]) {
|
||||
$ReturnObject['UserPrincipalName'] = $Accounts[$A].UserPrincipalName
|
||||
$ReturnObject['AccountEnabled'] = $Accounts[$A].Enabled
|
||||
$ReturnObject['DistinguishedName'] = $Accounts[$A].DistinguishedName
|
||||
$ReturnObject['PasswordLastSet'] = if ($Accounts[$A].PasswordLastSet) { $Accounts[$A].PasswordLastSet } else { '' }
|
||||
$ReturnObject['LastLogonDate'] = if ($Accounts[$A].LastLogonDate ) { $Accounts[$A].LastLogonDate } else { '' }
|
||||
if (-not $ReturnObject['Sid']) {
|
||||
$ReturnObject['Sid'] = $Accounts[$A].Sid.Value
|
||||
}
|
||||
if ($Accounts[$A].ObjectClass -eq 'group') {
|
||||
$ReturnObject['SidType'] = 'Group'
|
||||
} elseif ($Accounts[$A].ObjectClass -eq 'user') {
|
||||
$ReturnObject['SidType'] = 'User'
|
||||
} elseif ($Accounts[$A].ObjectClass -eq 'computer') {
|
||||
$ReturnObject['SidType'] = 'Computer'
|
||||
} else {
|
||||
$ReturnObject['SidType'] = 'EmptyOrUnknown'
|
||||
|
||||
<#
|
||||
# Sets permissions name, domain, distinguishedname to proper values
|
||||
if ($GPOPermission.Trustee.Name) {
|
||||
$DomainPlusName = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
|
||||
if ($GPOPermission.Trustee.DSPath) {
|
||||
$NetbiosConversion = ConvertFrom-NetbiosName -Identity $DomainPlusName
|
||||
if ($NetbiosConversion.DomainName) {
|
||||
$UserNameDomain = $NetbiosConversion.DomainName
|
||||
$UserName = $NetbiosConversion.Name
|
||||
}
|
||||
} else {
|
||||
$ReturnObject['UserPrincipalName'] = ''
|
||||
$ReturnObject['AccountEnabled'] = ''
|
||||
$ReturnObject['PasswordLastSet'] = ''
|
||||
$ReturnObject['LastLogonDate'] = ''
|
||||
$UserNameDomain = ''
|
||||
$Username = $DomainPlusName
|
||||
}
|
||||
} else {
|
||||
$DomainPlusName = ''
|
||||
$UserNameDomain = ''
|
||||
$Username = ''
|
||||
}
|
||||
#>
|
||||
|
||||
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
|
||||
$PermissionAccount = Get-WinADObject -Identity $GPOPermission.Trustee.Sid.Value -AddType -Cache
|
||||
if ($PermissionAccount) {
|
||||
$UserNameDomain = $PermissionAccount.DomainName
|
||||
$UserName = $PermissionAccount.Name
|
||||
$SidType = $PermissionAccount.Type
|
||||
$ObjectClass = $PermissionAccount.ObjectClass
|
||||
} else {
|
||||
$ConvertFromSID = ConvertFrom-SID -SID $GPOPermission.Trustee.Sid.Value
|
||||
$UserNameDomain = ''
|
||||
$Username = $ConvertFromSID.Name
|
||||
$SidType = $ConvertFromSID.Type
|
||||
if ($SidType -eq 'Unknown') {
|
||||
$ObjectClass = 'unknown'
|
||||
} else {
|
||||
$ObjectClass = 'foreignSecurityPrincipal'
|
||||
}
|
||||
}
|
||||
$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
|
||||
PermissionType = if ($GPOPermission.Denied -eq $true) { 'Deny' } else { 'Allow' }
|
||||
Permission = $GPOPermission.Permission # : GpoEditDeleteModifySecurity
|
||||
Inherited = $GPOPermission.Inherited # : False
|
||||
PrincipalNetBiosName = $UserMerge
|
||||
PrincipalDistinguishedName = $GPOPermission.Trustee.DSPath #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
|
||||
PrincipalDomainName = $UserNameDomain #: EVOTEC
|
||||
PrincipalName = $UserName #: Domain Admins
|
||||
PrincipalSid = $GPOPermission.Trustee.Sid.Value #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
|
||||
PrincipalSidType = $SidType #$GPOPermission.Trustee.SidType #: Group
|
||||
PrincipalObjectClass = $ObjectClass
|
||||
}
|
||||
|
||||
|
||||
if ($IncludeGPOObject) {
|
||||
$ReturnObject['GPOObject'] = $GPO
|
||||
$ReturnObject['GPOSecurity'] = $SecurityRights
|
||||
@@ -183,69 +211,139 @@
|
||||
}
|
||||
[PSCustomObject] $ReturnObject
|
||||
}
|
||||
if ($IncludeOwner.IsPresent) {
|
||||
if ($IncludeOwner) {
|
||||
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
|
||||
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
|
||||
$OwnerAccount = Get-WinADObject -Identity $GPO.Owner -AddType -Cache
|
||||
if ($OwnerAccount) {
|
||||
$UserNameDomain = $OwnerAccount.DomainName
|
||||
$UserName = $OwnerAccount.Name
|
||||
$SidType = $OwnerAccount.Type
|
||||
$OwnerObjectClass = $OwnerAccount.ObjectClass
|
||||
$SID = $OwnerAccount.ObjectSID
|
||||
} else {
|
||||
$SIDType = ''
|
||||
$DistinguishedName = ''
|
||||
$ConvertFromSID = ConvertFrom-SID -SID $GPO.Owner
|
||||
$UserNameDomain = ''
|
||||
$Username = $ConvertFromSID.Name
|
||||
$SidType = $ConvertFromSID.Type
|
||||
if ($SidType -eq 'Unknown') {
|
||||
$OwnerObjectClass = 'unknown'
|
||||
} else {
|
||||
$OwnerObjectClass = 'foreignSecurityPrincipal'
|
||||
}
|
||||
$SID = $ConvertFromSID.SID
|
||||
}
|
||||
} else {
|
||||
$DomainOwner = $GPO.Owner
|
||||
$DomainUserName = ''
|
||||
$UserName = ''
|
||||
$UserNameDomain = ''
|
||||
$SID = ''
|
||||
$SIDType = 'EmptyOrUnknown'
|
||||
$SIDType = 'Unknown'
|
||||
$DistinguishedName = ''
|
||||
$OwnerObjectClass = 'unknown'
|
||||
}
|
||||
$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 = '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 ($Accounts) {
|
||||
$A = $GPO.Owner
|
||||
if ($A -and $Accounts[$A]) {
|
||||
$ReturnObject['UserPrincipalName'] = $Accounts[$A].UserPrincipalName
|
||||
$ReturnObject['AccountEnabled'] = $Accounts[$A].Enabled
|
||||
$ReturnObject['DistinguishedName'] = $Accounts[$A].DistinguishedName
|
||||
$ReturnObject['PasswordLastSet'] = if ($Accounts[$A].PasswordLastSet) { $Accounts[$A].PasswordLastSet } else { '' }
|
||||
$ReturnObject['LastLogonDate'] = if ($Accounts[$A].LastLogonDate ) { $Accounts[$A].LastLogonDate } else { '' }
|
||||
if (-not $ReturnObject['Sid']) {
|
||||
$ReturnObject['Sid'] = $Accounts[$A].Sid.Value
|
||||
}
|
||||
if ($Accounts[$A].ObjectClass -eq 'group') {
|
||||
$ReturnObject['SidType'] = 'Group'
|
||||
} elseif ($Accounts[$A].ObjectClass -eq 'user') {
|
||||
$ReturnObject['SidType'] = 'User'
|
||||
} elseif ($Accounts[$A].ObjectClass -eq 'computer') {
|
||||
$ReturnObject['SidType'] = 'Computer'
|
||||
} else {
|
||||
$ReturnObject['SidType'] = 'EmptyOrUnknown'
|
||||
# We have to process it for owners after querying user because $Owners are not as established as standard permissions so we don't know a lot
|
||||
|
||||
if ($Type -contains 'Administrative' -and $Type -notcontains 'All') {
|
||||
if ($SID) {
|
||||
$IsAdministrative = $ADAdministrativeGroups['BySID'][$SID]
|
||||
if (-not $IsAdministrative) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
$ReturnObject['UserPrincipalName'] = ''
|
||||
$ReturnObject['AccountEnabled'] = ''
|
||||
$ReturnObject['PasswordLastSet'] = ''
|
||||
$ReturnObject['LastLogonDate'] = ''
|
||||
# if there is no SID, it's not administrative
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'NotWellKnownAdministrative' -and $Type -notcontains 'All') {
|
||||
# We check for SYSTEM account
|
||||
# Maybe we should make it a function and provide more
|
||||
if ($SID -eq 'S-1-5-18') {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'WellKnownAdministrative' -and $Type -notcontains 'All') {
|
||||
# We check for SYSTEM account
|
||||
# Maybe we should make it a function and provide more
|
||||
if ($SID -ne 'S-1-5-18') {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'Unknown' -and $Type -notcontains 'All') {
|
||||
# May need updates if there's more types
|
||||
if ($SidType -ne 'Unknown') {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'AuthenticatedUsers' -and $Type -notcontains 'All') {
|
||||
if ($SID -ne 'S-1-5-11') {
|
||||
return
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'DomainComputers' -and $Type -notcontains 'All') {
|
||||
$DomainComputersSID = -join ($ExtendedForestInformation['DomainsExtended'][$GPO.DomainName].DomainSID, '-515')
|
||||
if ($SID -ne $DomainComputersSID) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ($Principal) {
|
||||
if ($PrincipalType -eq 'Sid') {
|
||||
if ($Principal -notcontains $SID) {
|
||||
return
|
||||
}
|
||||
} elseif ($PrincipalType -eq 'DistinguishedName') {
|
||||
if ($Principal -notcontains $DistinguishedName) {
|
||||
return
|
||||
}
|
||||
} elseif ($PrincipalType -eq 'Name') {
|
||||
if ($Principal -notcontains $UserName) {
|
||||
return
|
||||
}
|
||||
} elseif ($PrincipalType -eq 'NetbiosName') {
|
||||
if ($Principal -notcontains $GPO.Owner) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($ExcludePrincipal) {
|
||||
if ($ExcludePrincipalType -eq 'Sid') {
|
||||
if ($ExcludePrincipal -contains $SID) {
|
||||
return
|
||||
}
|
||||
} elseif ($ExcludePrincipalType -eq 'DistinguishedName') {
|
||||
if ($ExcludePrincipal -contains $DistinguishedName) {
|
||||
return
|
||||
}
|
||||
} elseif ($ExcludePrincipalType -eq 'Name') {
|
||||
if ($ExcludePrincipal -contains $UserName) {
|
||||
return
|
||||
}
|
||||
} elseif ($ExcludePrincipalType -eq 'NetbiosName') {
|
||||
if ($ExcludePrincipal -contains $GPO.Owner) {
|
||||
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
|
||||
PermissionType = 'Allow'
|
||||
Permission = 'GpoOwner' # : GpoEditDeleteModifySecurity
|
||||
Inherited = $false # : False
|
||||
PrincipalNetBiosName = $GPO.Owner
|
||||
PrincipalDistinguishedName = $DistinguishedName #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
|
||||
PrincipalDomainName = $UserNameDomain
|
||||
PrincipalName = $UserName
|
||||
PrincipalSid = $SID #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
|
||||
PrincipalSidType = $SIDType # #: Group
|
||||
PrincipalObjectClass = $OwnerObjectClass
|
||||
}
|
||||
if ($IncludeGPOObject) {
|
||||
$ReturnObject['GPOObject'] = $GPO
|
||||
$ReturnObject['GPOSecurity'] = $SecurityRights
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
$OwnerType = 'NotAdministrative'
|
||||
}
|
||||
} else {
|
||||
$OwnerType = 'EmptyOrUnknown'
|
||||
$OwnerType = 'Unknown'
|
||||
}
|
||||
}
|
||||
if ($PermissionsOnly) {
|
||||
|
||||
+573
-256
File diff suppressed because it is too large
Load Diff
@@ -3,14 +3,17 @@
|
||||
param(
|
||||
[Array] $GPOs,
|
||||
[string] $Server,
|
||||
[string] $Domain
|
||||
[string] $Domain,
|
||||
[System.Collections.IDictionary] $PoliciesAD,
|
||||
[string] $PoliciesSearchBase
|
||||
)
|
||||
$Differences = @{ }
|
||||
$SysvolHash = @{ }
|
||||
|
||||
$GPOGUIDS = $GPOs.ID.GUID
|
||||
$SysVolPath = "\\$($Server)\SYSVOL\$Domain\Policies"
|
||||
try {
|
||||
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -ErrorAction Stop
|
||||
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -Exclude 'PolicyDefinitions' -ErrorAction Stop
|
||||
} catch {
|
||||
$Sysvol = $Null
|
||||
}
|
||||
@@ -22,12 +25,20 @@
|
||||
if ($Files) {
|
||||
$Comparing = Compare-Object -ReferenceObject $GPOGUIDS -DifferenceObject $Files -IncludeEqual
|
||||
foreach ($_ in $Comparing) {
|
||||
if ($_.InputObject -eq 'PolicyDefinitions') {
|
||||
# we skip policy definitions
|
||||
continue
|
||||
}
|
||||
if ($_.SideIndicator -eq '==') {
|
||||
$Found = 'Exists'
|
||||
} elseif ($_.SideIndicator -eq '<=') {
|
||||
$Found = 'Not available on SYSVOL'
|
||||
} elseif ($_.SideIndicator -eq '=>') {
|
||||
$Found = 'Orphaned GPO'
|
||||
if ($PoliciesAD[$_.InputObject]) {
|
||||
$Found = $PoliciesAD[$_.InputObject]
|
||||
} else {
|
||||
$Found = 'Not available in AD'
|
||||
}
|
||||
} else {
|
||||
$Found = 'Orphaned GPO'
|
||||
}
|
||||
@@ -49,68 +60,71 @@
|
||||
$ErrorMessage = $_.Exception.Message
|
||||
}
|
||||
} else {
|
||||
$FullPath = -join ($SysVolPath, "\{$($GPO.Id.Guid)}")
|
||||
$ACL = $null
|
||||
$Owner = ''
|
||||
$ErrorMessage = 'Not found on SYSVOL'
|
||||
}
|
||||
if ($null -eq $Differences[$GPO.Id.Guid]) {
|
||||
$SysVolStatus = 'Not available on SYSVOL'
|
||||
$SysVolStatus = 'Unknown Issue'
|
||||
} else {
|
||||
$SysVolStatus = $Differences[$GPO.Id.Guid]
|
||||
}
|
||||
[PSCustomObject] @{
|
||||
DisplayName = $GPO.DisplayName
|
||||
Status = $Differences[$GPO.Id.Guid]
|
||||
DomainName = $GPO.DomainName
|
||||
SysvolServer = $Server
|
||||
SysvolStatus = $SysVolStatus
|
||||
Owner = $GPO.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
|
||||
DisplayName = $GPO.DisplayName
|
||||
Status = $SysVolStatus
|
||||
DomainName = $GPO.DomainName
|
||||
SysvolServer = $Server
|
||||
SysvolStatus = $SysVolStatus
|
||||
GpoStatus = $GPO.GpoStatus
|
||||
Owner = $GPO.Owner
|
||||
FileOwner = $Owner
|
||||
Id = $GPO.Id.Guid
|
||||
Path = $FullPath
|
||||
DistinguishedName = -join ("CN={", $GPO.Id.Guid, "},", $PoliciesSearchBase)
|
||||
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') {
|
||||
$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
|
||||
}
|
||||
if ($Differences[$_] -in 'Not available in AD', 'Permissions issue') {
|
||||
$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] @{
|
||||
DisplayName = $SysvolHash[$_].BaseName
|
||||
Status = 'Orphaned GPO'
|
||||
DomainName = $Domain
|
||||
SysvolServer = $Server
|
||||
SysvolStatus = $Differences[$GPO.Id.Guid]
|
||||
Owner = ''
|
||||
FileOwner = $Owner
|
||||
Id = $_
|
||||
GpoStatus = 'Orphaned'
|
||||
Path = $FullPath
|
||||
Description = $null
|
||||
CreationTime = $SysvolHash[$_].CreationTime
|
||||
ModificationTime = $SysvolHash[$_].LastWriteTime
|
||||
UserVersion = $null
|
||||
ComputerVersion = $null
|
||||
WmiFilter = $null
|
||||
Error = $ErrorMessage
|
||||
}
|
||||
[PSCustomObject] @{
|
||||
DisplayName = $SysvolHash[$_].BaseName
|
||||
Status = $Differences[$_]
|
||||
DomainName = $Domain
|
||||
SysvolServer = $Server
|
||||
SysvolStatus = 'Exists' #$Differences[$GPO.Id.Guid]
|
||||
GpoStatus = $Differences[$_]
|
||||
Owner = ''
|
||||
FileOwner = $Owner
|
||||
Id = $_
|
||||
Path = $FullPath
|
||||
DistinguishedName = -join ("CN={", $_, "},", $PoliciesSearchBase)
|
||||
Description = $null
|
||||
CreationTime = $SysvolHash[$_].CreationTime
|
||||
ModificationTime = $SysvolHash[$_].LastWriteTime
|
||||
UserVersion = $null
|
||||
ComputerVersion = $null
|
||||
WmiFilter = $null
|
||||
Error = $ErrorMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ function ConvertFrom-CSExtension {
|
||||
'{D76B9641-3288-4f75-942D-087DE603E3EA}' = 'AdmPwd'
|
||||
'{9650FDBC-053A-4715-AD14-FC2DC65E8330}' = 'Unknown'
|
||||
'{B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A}' = 'EFS Recovery'
|
||||
'{A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B}' = 'Internet Explorer Settings'
|
||||
'{A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B}' = 'Internet Explorer Maintenance Policy Processing'
|
||||
'{FC715823-C5FB-11D1-9EEF-00A0C90347FF}' = 'Internet Explorer Maintenance Extension Protocol' # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpie/f566a58a-4114-4981-b1e2-30b9d1a3c0e6
|
||||
}
|
||||
foreach ($C in $CSE) {
|
||||
if (-not $Limited) {
|
||||
|
||||
@@ -9,7 +9,7 @@ function Find-CSExtension {
|
||||
foreach ($Key in $Keys.PSSubKeys) {
|
||||
$RegistryKey = Get-PSRegistry -RegistryPath "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\$Key" -ComputerName $ComputerName
|
||||
if ($CSE) {
|
||||
foreach ($C in CSE) {
|
||||
foreach ($C in $CSE) {
|
||||
if ($RegistryKey.DefaultKey -eq $Key) {
|
||||
[PSCustomObject] @{ Name = $Key; Description = $RegistryKey.DefaultKey }
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
[ValidateSet('All', 'Netlogon', 'Sysvol')][string[]] $Type = 'All',
|
||||
[ValidateSet('None', 'MACTripleDES', 'MD5', 'RIPEMD160', 'SHA1', 'SHA256', 'SHA384', 'SHA512')][string] $HashAlgorithm = 'None',
|
||||
[switch] $Signature,
|
||||
[switch] $Limited,
|
||||
[switch] $AsHashTable,
|
||||
[switch] $Extended,
|
||||
[switch] $ExtendedMetaData,
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
@@ -265,7 +265,7 @@
|
||||
$SuggestedAction = 'Requires verification'
|
||||
$SuggestedActionComment = 'Not able to auto asses'
|
||||
}
|
||||
if ($Limited) {
|
||||
if (-not $ExtendedMetaData) {
|
||||
$MetaData = [ordered] @{
|
||||
LocationType = $FileType.Name
|
||||
FullName = $_.FullName
|
||||
@@ -282,18 +282,39 @@
|
||||
}
|
||||
} else {
|
||||
$MetaData = Get-FileMetaData -File $_ -AsHashTable
|
||||
$MetaData['SuggestedAction'] = $SuggestedAction
|
||||
$MetaData['SuggestedActionComment'] = $SuggestedActionComment
|
||||
$MetaData['BelongsToGPO'] = $BelongsToGPO
|
||||
$MetaData['GPODisplayName'] = $GPODisplayName
|
||||
}
|
||||
if ($Signature) {
|
||||
$DigitalSignature = Get-AuthenticodeSignature -FilePath $_.Fullname
|
||||
$MetaData['SignatureStatus'] = $DigitalSignature.Status
|
||||
$MetaData['IsOSBinary'] = $DigitalSignature.IsOSBinary
|
||||
$MetaData['SignatureCertificateSubject'] = $DigitalSignature.SignerCertificate.Subject
|
||||
if ($Extended) {
|
||||
$MetaData['SignatureCertificateIssuer'] = $DigitalSignature.SignerCertificate.Issuer
|
||||
$MetaData['SignatureCertificateSerialNumber'] = $DigitalSignature.SignerCertificate.SerialNumber
|
||||
$MetaData['SignatureCertificateNotBefore'] = $DigitalSignature.SignerCertificate.NotBefore
|
||||
$MetaData['SignatureCertificateNotAfter'] = $DigitalSignature.SignerCertificate.NotAfter
|
||||
$MetaData['SignatureCertificateThumbprint'] = $DigitalSignature.SignerCertificate.Thumbprint
|
||||
try {
|
||||
$DigitalSignature = Get-AuthenticodeSignature -FilePath $_.Fullname -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Warning "Get-GPOZaurrFiles - Error when reading signature: $($_.Exception.Message)"
|
||||
}
|
||||
if ($DigitalSignature) {
|
||||
$MetaData['SignatureStatus'] = $DigitalSignature.Status
|
||||
$MetaData['IsOSBinary'] = $DigitalSignature.IsOSBinary
|
||||
$MetaData['SignatureCertificateSubject'] = $DigitalSignature.SignerCertificate.Subject
|
||||
if ($Extended) {
|
||||
$MetaData['SignatureCertificateIssuer'] = $DigitalSignature.SignerCertificate.Issuer
|
||||
$MetaData['SignatureCertificateSerialNumber'] = $DigitalSignature.SignerCertificate.SerialNumber
|
||||
$MetaData['SignatureCertificateNotBefore'] = $DigitalSignature.SignerCertificate.NotBefore
|
||||
$MetaData['SignatureCertificateNotAfter'] = $DigitalSignature.SignerCertificate.NotAfter
|
||||
$MetaData['SignatureCertificateThumbprint'] = $DigitalSignature.SignerCertificate.Thumbprint
|
||||
}
|
||||
} else {
|
||||
$MetaData['SignatureStatus'] = 'Not available'
|
||||
$MetaData['IsOSBinary'] = $null
|
||||
$MetaData['SignatureCertificateSubject'] = $null
|
||||
if ($Extended) {
|
||||
$MetaData['SignatureCertificateIssuer'] = $null
|
||||
$MetaData['SignatureCertificateSerialNumber'] = $null
|
||||
$MetaData['SignatureCertificateNotBefore'] = $null
|
||||
$MetaData['SignatureCertificateNotAfter'] = $null
|
||||
$MetaData['SignatureCertificateThumbprint'] = $null
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($HashAlgorithm -ne 'None') {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
function Get-GPOZaurrNetLogon {
|
||||
[cmdletBinding(DefaultParameterSetName = 'Default')]
|
||||
param(
|
||||
[parameter(ParameterSetName = 'OwnerOnly')][switch] $OwnerOnly,
|
||||
[parameter(ParameterSetName = 'SkipOwner')][switch] $SkipOwner
|
||||
)
|
||||
$ForestInformation = Get-WinADForestDetails -Extended
|
||||
$FilesAll = foreach ($Domain in $ForestInformation.Domains) {
|
||||
$Path = -join ("\\", $Domain, '\Netlogon')
|
||||
$Files = Get-ChildItem -LiteralPath $Path -Recurse
|
||||
foreach ($_ in $Files) {
|
||||
$ACL = Get-Acl -Path $_.FullName
|
||||
if ($ACL.Owner) {
|
||||
$IdentityOwner = Convert-Identity -Identity $ACL.Owner
|
||||
} else {
|
||||
$IdentityOwner = [PSCustomObject] @{ SID = ''; Type = 'Uknown' }
|
||||
}
|
||||
if (-not $OwnerOnly) {
|
||||
if (-not $SkipOwner) {
|
||||
[PSCustomObject] @{
|
||||
FullName = $_.FullName
|
||||
Extension = $_.Extension
|
||||
CreationTime = $_.CreationTime
|
||||
LastAccessTime = $_.LastAccessTime
|
||||
LastWriteTime = $_.LastWriteTime
|
||||
Attributes = $_.Attributes
|
||||
AccessControlType = 'Allow' # : Allow
|
||||
Principal = $IdentityOwner.Name # : BUILTIN\Administrators
|
||||
PrincipalSid = $IdentityOwner.SID
|
||||
PrincipalType = $IdentityOwner.Type
|
||||
FileSystemRights = 'Owner' # : FullControl
|
||||
IsInherited = $false
|
||||
#Owner = $ACL.Owner
|
||||
}
|
||||
}
|
||||
$FilePermission = Get-FilePermissions -Path $_.FullName -ACLS $ACL
|
||||
foreach ($Perm in $FilePermission) {
|
||||
$Identity = Convert-Identity -Identity $Perm.Principal
|
||||
[PSCustomObject] @{
|
||||
FullName = $_.FullName
|
||||
Extension = $_.Extension
|
||||
CreationTime = $_.CreationTime
|
||||
LastAccessTime = $_.LastAccessTime
|
||||
LastWriteTime = $_.LastWriteTime
|
||||
Attributes = $_.Attributes
|
||||
AccessControlType = $Perm.AccessControlType # : Allow
|
||||
Principal = $Identity.Name # : BUILTIN\Administrators
|
||||
PrincipalSid = $Identity.SID
|
||||
PrincipalType = $Identity.Type
|
||||
FileSystemRights = $Perm.FileSystemRights # : FullControl
|
||||
IsInherited = $Perm.IsInherited # : True
|
||||
}
|
||||
}
|
||||
} else {
|
||||
[PSCustomObject] @{
|
||||
FullName = $_.FullName
|
||||
Extension = $_.Extension
|
||||
CreationTime = $_.CreationTime
|
||||
LastAccessTime = $_.LastAccessTime
|
||||
LastWriteTime = $_.LastWriteTime
|
||||
Attributes = $_.Attributes
|
||||
Owner = $IdentityOwner.Name
|
||||
OwnerSid = $IdentityOwner.SID
|
||||
OwnerType = $IdentityOwner.Type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$FilesAll
|
||||
}
|
||||
@@ -49,6 +49,9 @@
|
||||
$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 }
|
||||
} else {
|
||||
$Object['IsOwnerAdministrative'] = if ($Object['OwnerType'] -eq 'Administrative') { $true } else { $false }
|
||||
}
|
||||
$Object['DistinguishedName'] = $_.GPODistinguishedName
|
||||
[PSCUstomObject] $Object
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
[alias('GUID', 'GPOID')][string] $GPOGuid,
|
||||
|
||||
[string[]] $Principal,
|
||||
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
|
||||
[validateset('DistinguishedName', 'Name', 'NetbiosName', 'Sid')][string] $PrincipalType = 'Sid',
|
||||
|
||||
[validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All',
|
||||
|
||||
[switch] $SkipWellKnown,
|
||||
[switch] $SkipAdministrative,
|
||||
[switch] $ResolveAccounts,
|
||||
#[switch] $ResolveAccounts,
|
||||
|
||||
[switch] $IncludeOwner,
|
||||
[Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
|
||||
@@ -43,6 +43,7 @@
|
||||
Write-Warning "Get-GPOZaurrPermission - Using SkipAdministrative or SkipWellKnown while looking for Unknown doesn't make sense as only Unknown will be displayed."
|
||||
}
|
||||
}
|
||||
<#
|
||||
if ($ResolveAccounts) {
|
||||
$Accounts = @{ }
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
@@ -60,6 +61,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#>
|
||||
}
|
||||
Process {
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
@@ -96,7 +98,7 @@
|
||||
Principal = $Principal
|
||||
PrincipalType = $PrincipalType
|
||||
PermitType = $PermitType
|
||||
Accounts = $Accounts
|
||||
#Accounts = $Accounts
|
||||
Type = $Type
|
||||
GPO = $_
|
||||
SkipWellKnown = $SkipWellKnown.IsPresent
|
||||
|
||||
@@ -46,23 +46,25 @@
|
||||
} catch {
|
||||
$ErrorMessage = $_.Exception.Message
|
||||
Write-Warning "Get-GPOZaurrPermissionConsistency - Failed to get consistency: $($_.Exception.Message)."
|
||||
$IsConsistent = 'Not available.'
|
||||
$IsConsistent = 'Not available'
|
||||
}
|
||||
$SysVolpath = -join ('\\', $Domain, '\sysvol\', $Domain, '\Policies\{', $_.ID.GUID, '}')
|
||||
if ($VerifyInheritance) {
|
||||
$FolderPermissions = Get-WinADSharePermission -Path $SysVolpath
|
||||
[Array] $NotInheritedPermissions = foreach ($File in $FolderPermissions) {
|
||||
if ($File.Path -ne $SysVolpath -and $File.IsInherited -eq $false) {
|
||||
$File
|
||||
if ($FolderPermissions) {
|
||||
[Array] $NotInheritedPermissions = foreach ($File in $FolderPermissions) {
|
||||
if ($File.Path -ne $SysVolpath -and $File.IsInherited -eq $false) {
|
||||
$File
|
||||
}
|
||||
}
|
||||
if ($NotInheritedPermissions.Count -eq 0) {
|
||||
$ACLConsistentInside = $true
|
||||
} else {
|
||||
$ACLConsistentInside = $false
|
||||
}
|
||||
}
|
||||
if ($NotInheritedPermissions.Count -eq 0) {
|
||||
$ACLConsistentInside = $true
|
||||
} else {
|
||||
$ACLConsistentInside = $false
|
||||
$ACLConsistentInside = 'Not available'
|
||||
}
|
||||
} else {
|
||||
$ACLConsistentInside = $null
|
||||
}
|
||||
$Object = [ordered] @{
|
||||
DisplayName = $_.DisplayName # : New Group Policy Object
|
||||
@@ -94,21 +96,21 @@
|
||||
[PSCustomObject] $Object
|
||||
} elseif ($Type -eq 'Inconsistent') {
|
||||
if ($VerifyInheritance) {
|
||||
if (-not $IsConsistent -or -not $ACLConsistentInside) {
|
||||
if (-not ($IsConsistent -eq $true) -or (-not $ACLConsistentInside -eq $true)) {
|
||||
[PSCustomObject] $Object
|
||||
}
|
||||
} else {
|
||||
if (-not $IsConsistent) {
|
||||
if (-not ($IsConsistent -eq $true)) {
|
||||
[PSCustomObject] $Object
|
||||
}
|
||||
}
|
||||
} elseif ($Type -eq 'Consistent') {
|
||||
if ($VerifyInheritance) {
|
||||
if ($IsConsistent -and $ACLConsistentInside) {
|
||||
if ($IsConsistent -eq $true -and $ACLConsistentInside -eq $true) {
|
||||
[PSCustomObject] $Object
|
||||
}
|
||||
} else {
|
||||
if ($IsConsistent) {
|
||||
if ($IsConsistent -eq $true) {
|
||||
[PSCustomObject] $Object
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
function Get-GPOZaurrPermissionRoot {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('GpoRootCreate', 'GpoRootOwner')][string[]] $IncludePermissionType,
|
||||
[ValidateSet('GpoRootCreate', 'GpoRootOwner')][string[]] $ExcludePermissionType,
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
Begin {
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Extended
|
||||
}
|
||||
Process {
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
$DomainDistinguishedName = $ForestInformation['DomainsExtended'][$Domain].DistinguishedName
|
||||
$QueryServer = $ForestInformation['QueryServers'][$Domain].HostName[0]
|
||||
$getADACLSplat = @{
|
||||
ADObject = "CN=Policies,CN=System,$DomainDistinguishedName"
|
||||
IncludeActiveDirectoryRights = 'GenericAll', 'CreateChild', 'WriteOwner', 'WriteDACL'
|
||||
IncludeObjectTypeName = 'All', 'Group-Policy-Container'
|
||||
IncludeInheritedObjectTypeName = 'All', 'Group-Policy-Container'
|
||||
ADRightsAsArray = $true
|
||||
ResolveTypes = $true
|
||||
}
|
||||
$GPOPermissionsGlobal = Get-ADACL @getADACLSplat #-Verbose
|
||||
|
||||
$GPOs = Get-ADObject -SearchBase "CN=Policies,CN=System,$DomainDistinguishedName" -SearchScope OneLevel -Filter * -Properties DisplayName -Server $QueryServer
|
||||
foreach ($Permission in $GPOPermissionsGlobal) {
|
||||
$CustomPermission = foreach ($_ in $Permission.ActiveDirectoryRights) {
|
||||
if ($_ -in 'WriteDACL', 'WriteOwner', 'GenericAll' ) {
|
||||
'GpoRootOwner'
|
||||
}
|
||||
if ($_ -in 'CreateChild', 'GenericAll') {
|
||||
'GpoRootCreate'
|
||||
}
|
||||
}
|
||||
$CustomPermission = $CustomPermission | Sort-Object -Unique
|
||||
foreach ($SinglePermission in $CustomPermission) {
|
||||
if ($SinglePermission -in $ExcludePermissionType) {
|
||||
continue
|
||||
}
|
||||
if ($IncludePermissionType.Count -gt 0 -and $SinglePermission -notin $IncludePermissionType) {
|
||||
continue
|
||||
}
|
||||
[PSCustomObject] @{
|
||||
PrincipalName = $Permission.Principal
|
||||
Permission = $SinglePermission
|
||||
PermissionType = $Permission.AccessControlType
|
||||
PrincipalSidType = $Permission.PrincipalType
|
||||
PrincipalObjectClass = $Permission.PrincipalObjectType
|
||||
PrincipalDomainName = $Permission.PrincipalObjectDomain
|
||||
PrincipalSid = $Permission.PrincipalObjectSid
|
||||
GPOCount = $GPOs.Count
|
||||
GPONames = $GPOs.DisplayName
|
||||
DomainName = $Domain
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
|
||||
if ($Permission.ActiveDirectoryRights | ForEach-Object {
|
||||
$_
|
||||
}) {
|
||||
|
||||
[PSCustomObject] @{
|
||||
PrincipalName = $Permission.Principal
|
||||
Permission = 'GpoCustomOwner'
|
||||
PermissionType = $Permission.AccessControlType
|
||||
PrincipalSidType = $Permission.PrincipalType
|
||||
PrincipalObjectClass = $Permission.PrincipalObjectType
|
||||
PrincipalDomainName = $Permission.PrincipalObjectDomain
|
||||
PrincipalSid = $Permission.PrincipalObjectSid
|
||||
GPOCount = 'N/A'
|
||||
GPONames = -join ("All-", $Domain.ToUpper())
|
||||
DomainName = $Domain
|
||||
}
|
||||
}
|
||||
if ($Permission.ActiveDirectoryRights | ForEach-Object {
|
||||
$_ -in 'CreateChild', 'GenericAll'
|
||||
}) {
|
||||
[PSCustomObject] @{
|
||||
PrincipalName = $Permission.Principal
|
||||
Permission = 'GpoCustomCreate'
|
||||
PermissionType = $Permission.AccessControlType
|
||||
PrincipalSidType = $Permission.PrincipalType
|
||||
PrincipalObjectClass = $Permission.PrincipalObjectType
|
||||
PrincipalDomainName = $Permission.PrincipalObjectDomain
|
||||
PrincipalSid = $Permission.PrincipalObjectSid
|
||||
GPOCount = 'N/A'
|
||||
GPONames = -join ("All-", $Domain.ToUpper())
|
||||
DomainName = $Domain
|
||||
}
|
||||
|
||||
}
|
||||
#>
|
||||
}
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
@@ -3,10 +3,8 @@
|
||||
param(
|
||||
[validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All',
|
||||
[validateSet('Allow', 'Deny', 'All')][string] $PermitType = 'All',
|
||||
[Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
|
||||
[Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType,
|
||||
[switch] $IncludeOwner,
|
||||
|
||||
[ValidateSet('GpoApply', 'GpoEdit', 'GpoCustom', 'GpoEditDeleteModifySecurity', 'GpoRead', 'GpoOwner', 'GpoRootCreate', 'GpoRootOwner')][string[]] $IncludePermissionType,
|
||||
[ValidateSet('GpoApply', 'GpoEdit', 'GpoCustom', 'GpoEditDeleteModifySecurity', 'GpoRead', 'GpoOwner', 'GpoRootCreate', 'GpoRootOwner')][string[]] $ExcludePermissionType,
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
@@ -15,28 +13,118 @@
|
||||
[string] $Separator
|
||||
)
|
||||
|
||||
$Permissions = Get-GPOZaurrPermission -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -IncludePermissionType $IncludePermissionType -ExcludePermissionType $ExcludePermissionType -Type $Type -PermitType $PermitType -IncludeOwner:$IncludeOwner
|
||||
$Entries = foreach ($Permission in $Permissions) {
|
||||
[PSCustomObject] @{
|
||||
Name = $Permission.Name
|
||||
Permission = $Permission.Permission
|
||||
PermissionType = $Permission.PermissionType
|
||||
Sid = $Permission.Sid
|
||||
SidType = $Permission.SidType
|
||||
DisplayName = $Permission.DisplayName
|
||||
DomainName = $Permission.DomainName
|
||||
Domain = $Domain
|
||||
$IncludePermTypes = [System.Collections.Generic.List[Microsoft.GroupPolicy.GPPermissionType]]::new()
|
||||
$ExcludePermTypes = [System.Collections.Generic.List[Microsoft.GroupPolicy.GPPermissionType]]::new()
|
||||
$CustomPermissions = [System.Collections.Generic.List[string]]::new()
|
||||
foreach ($PermType in $IncludePermissionType) {
|
||||
if ($PermType -in 'GpoApply', 'GpoEdit', 'GPOCustom', 'GpoEditDeleteModifySecurity', 'GPORead') {
|
||||
$IncludePermTypes.Add([Microsoft.GroupPolicy.GPPermissionType]::$PermType)
|
||||
} elseif ($PermType -in 'GpoOwner') {
|
||||
$IncludeOwner = $true
|
||||
} elseif ($PermType -in 'GpoRootCreate', 'GpoRootOwner') {
|
||||
$CustomPermissions.Add($PermType)
|
||||
}
|
||||
}
|
||||
$Entries | Group-Object -Property Permission, Name, DomainName, PermissionType | ForEach-Object {
|
||||
foreach ($PermType in $ExcludePermissionType) {
|
||||
if ($PermType -in 'GpoApply', 'GpoEdit', 'GPOCustom', 'GpoEditDeleteModifySecurity', 'GPORead') {
|
||||
$ExcludePermTypes.Add([Microsoft.GroupPolicy.GPPermissionType]::$PermType)
|
||||
} elseif ($PermType -in 'GpoOwner') {
|
||||
$IncludeOwner = $false
|
||||
} elseif ($PermType -in 'GpoRootCreate', 'GpoRootOwner') {
|
||||
$CustomPermissions.Add($PermType)
|
||||
}
|
||||
}
|
||||
|
||||
$RootPermissions = Get-GPOZaurrPermissionRoot -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
$Permissions = Get-GPOZaurrPermission -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -IncludePermissionType $IncludePermTypes -ExcludePermissionType $ExcludePermissionType -Type $Type -PermitType $PermitType -IncludeOwner:$IncludeOwner
|
||||
$Entries = @(
|
||||
foreach ($Permission in $Permissions) {
|
||||
[PSCustomObject] @{
|
||||
PrincipalName = $Permission.PrincipalName
|
||||
PrincipalDomainName = $Permission.PrincipalDomainName
|
||||
Permission = $Permission.Permission
|
||||
PermissionType = $Permission.PermissionType
|
||||
PrincipalSid = $Permission.PrincipalSid
|
||||
PrincipalSidType = $Permission.PrincipalSidType
|
||||
PrincipalObjectClass = $Permission.PrincipalObjectClass
|
||||
DisplayName = $Permission.DisplayName
|
||||
DomainName = $Permission.DomainName
|
||||
}
|
||||
}
|
||||
foreach ($RootPermission in $RootPermissions) {
|
||||
[PSCustomObject] @{
|
||||
PrincipalName = $RootPermission.PrincipalName
|
||||
PrincipalDomainName = $RootPermission.PrincipalDomainName
|
||||
Permission = $RootPermission.Permission
|
||||
PermissionType = $RootPermission.PermissionType
|
||||
PrincipalSid = $RootPermission.PrincipalSid
|
||||
PrincipalSidType = $RootPermission.PrincipalSidType
|
||||
PrincipalObjectClass = $RootPermission.PrincipalObjectClass
|
||||
DisplayName = $RootPermission.GPONames
|
||||
DomainName = $RootPermission.DomainName
|
||||
}
|
||||
}
|
||||
)
|
||||
$PermissionsData = [ordered] @{}
|
||||
foreach ($Entry in $Entries) {
|
||||
$Key = -join ($Entry.Permission, $Entry.PrincipalName, $Entry.PrincipalDomainName)
|
||||
if (-not $PermissionsData[$Key]) {
|
||||
$PermissionsData[$Key] = [PSCustomObject] @{
|
||||
Permission = $Entry.Permission
|
||||
PrincipalName = $Entry.PrincipalName
|
||||
PrincipalDomainName = $Entry.PrincipalDomainName
|
||||
PrincipalSidType = $Entry.PrincipalSidType
|
||||
DomainName = $Entry.DomainName
|
||||
PermissionType = $Entry.PermissionType
|
||||
GPOCOunt = 0
|
||||
GPONames = [System.Collections.Generic.List[string]]::new()
|
||||
}
|
||||
}
|
||||
#if ($IncludeNames) {
|
||||
$PermissionsData[$Key].GPONames.Add($Entry.DisplayName)
|
||||
#}
|
||||
$PermissionsData[$Key].GPOCOunt = $PermissionsData[$Key].GPOCOunt + ($Entry.DisplayName).Count
|
||||
}
|
||||
$PermissionsData.Values
|
||||
|
||||
<#
|
||||
($Entries | Group-Object -Property Permission, PrincipalSidType, PrincipalName, PrincipalDomainName, DomainName, PermissionType) | ForEach-Object {
|
||||
$Property = $_.Name -split ', '
|
||||
[PSCustomObject] @{
|
||||
Permission = $Property[0]
|
||||
Name = $Property[1]
|
||||
DomainName = $Property[2]
|
||||
PermissionType = if ($Property[3]) { $Property[3] } else { 'Owner' }
|
||||
GPOCount = $_.Count
|
||||
GPONames = if ($Separator) { $_.Group.DisplayName -join $Separator } else { $_.Group.DisplayName }
|
||||
Write-Verbose "$Property - $($Property.Count)"
|
||||
if ($Property[0] -eq 'GpoOwner') {
|
||||
[PSCustomObject] @{
|
||||
Permission = $Property[0]
|
||||
PrincipalSidType = $Property[1]
|
||||
PrincipalName = $Property[2]
|
||||
PrincipalDomainName = $Property[3]
|
||||
DomainName = $Property[4]
|
||||
PermissionType = 'Allow'
|
||||
GPOCount = $_.Count
|
||||
GPONames = if ($Separator) { $_.Group.DisplayName -join $Separator } else { $_.Group.DisplayName }
|
||||
}
|
||||
} elseif ($Property.Count -eq 5) {
|
||||
[PSCustomObject] @{
|
||||
Permission = $Property[0]
|
||||
PrincipalSidType = $Property[1]
|
||||
PrincipalName = $Property[2]
|
||||
PrincipalDomainName = $Property[3]
|
||||
DomainName = $Property[4]
|
||||
PermissionType = if ($Property[5]) { $Property[5] } else { 'Owner' }
|
||||
GPOCount = $_.Count
|
||||
GPONames = if ($Separator) { $_.Group.DisplayName -join $Separator } else { $_.Group.DisplayName }
|
||||
}
|
||||
} else {
|
||||
[PSCustomObject] @{
|
||||
Permission = $Property[0]
|
||||
PrincipalSidType = $Property[1]
|
||||
PrincipalName = ''
|
||||
PrincipalDomainName = ''
|
||||
DomainName = $Property[2]
|
||||
PermissionType = if ($Property[3]) { $Property[3] } else { 'Owner' }
|
||||
GPOCount = $_.Count
|
||||
GPONames = if ($Separator) { $_.Group.DisplayName -join $Separator } else { $_.Group.DisplayName }
|
||||
}
|
||||
}
|
||||
}
|
||||
#>
|
||||
}
|
||||
@@ -11,10 +11,26 @@
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
[switch] $VerifyDomainControllers
|
||||
)
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation -Extended
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
Write-Verbose "Get-WinADGPOSysvolFolders - Processing $Domain"
|
||||
$QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0]
|
||||
$SystemsContainer = $ForestInformation['DomainsExtended'][$Domain].SystemsContainer
|
||||
$PoliciesAD = @{}
|
||||
if ($SystemsContainer) {
|
||||
$PoliciesSearchBase = -join ("CN=Policies,", $SystemsContainer)
|
||||
$PoliciesInAD = Get-ADObject -SearchBase $PoliciesSearchBase -SearchScope OneLevel -Filter * -Server $QueryServer
|
||||
foreach ($Policy in $PoliciesInAD) {
|
||||
$GUIDFromDN = ConvertFrom-DistinguishedName -DistinguishedName $Policy.DistinguishedName
|
||||
$GUIDFromDN = $GUIDFromDN -replace '{' -replace '}'
|
||||
$GUID = $Policy.Name -replace '{' -replace '}'
|
||||
if ($GUID -and $GUIDFromDN) {
|
||||
$PoliciesAD[$GUIDFromDN] = 'Exists'
|
||||
} else {
|
||||
$PoliciesAD[$GUIDFromDN] = 'Permissions issue'
|
||||
}
|
||||
}
|
||||
}
|
||||
Try {
|
||||
[Array]$GPOs = Get-GPO -All -Domain $Domain -Server $QueryServer
|
||||
} catch {
|
||||
@@ -23,11 +39,11 @@
|
||||
}
|
||||
if ($GPOs.Count -ge 2) {
|
||||
if (-not $VerifyDomainControllers) {
|
||||
Test-SysVolFolders -GPOs $GPOs -Server $Domain -Domain $Domain
|
||||
Test-SysVolFolders -GPOs $GPOs -Server $Domain -Domain $Domain -PoliciesAD $PoliciesAD -PoliciesSearchBase $PoliciesSearchBase
|
||||
} 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
|
||||
Test-SysVolFolders -GPOs $GPOs -Server $Server.Hostname -Domain $Domain -PoliciesAD $PoliciesAD -PoliciesSearchBase $PoliciesSearchBase
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -21,11 +21,9 @@
|
||||
[Parameter(ParameterSetName = 'Local')]
|
||||
[switch] $FullObjects,
|
||||
|
||||
<#
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'Local')]
|
||||
[ValidateSet('HTML', 'Object', 'Excel')][string[]] $OutputType = 'Object',
|
||||
|
||||
[ValidateSet('HTML', 'Object')][string[]] $OutputType = 'Object',
|
||||
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'Local')]
|
||||
@@ -34,7 +32,10 @@
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'Local')]
|
||||
[switch] $Open,
|
||||
#>
|
||||
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'Local')]
|
||||
[switch] $Online,
|
||||
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'Local')]
|
||||
@@ -50,12 +51,15 @@
|
||||
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'Local')]
|
||||
[switch] $SkipCleanup
|
||||
[switch] $SkipCleanup,
|
||||
|
||||
[switch] $Extended
|
||||
)
|
||||
if ($Type.Count -eq 0) {
|
||||
$Type = $Script:GPODitionary.Keys
|
||||
}
|
||||
if ($GPOPath) {
|
||||
Write-Verbose "Invoke-GPOZaurr - Reading GPOs from $GPOPath"
|
||||
if (Test-Path -LiteralPath $GPOPath) {
|
||||
$GPOFiles = Get-ChildItem -LiteralPath $GPOPath -Recurse -File -Filter *.xml
|
||||
[Array] $GPOs = foreach ($File in $GPOFiles) {
|
||||
@@ -79,6 +83,7 @@
|
||||
return
|
||||
}
|
||||
} else {
|
||||
Write-Verbose "Invoke-GPOZaurr - Query AD for GPOs"
|
||||
[Array] $GPOs = Get-GPOZaurrAD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
}
|
||||
# This caches single reports.
|
||||
@@ -89,6 +94,7 @@
|
||||
$Output['Reports'] = [ordered] @{}
|
||||
$Output['CategoriesFull'] = [ordered] @{}
|
||||
|
||||
Write-Verbose "Invoke-GPOZaurr - Loading GPO Report to Categories"
|
||||
[Array] $GPOCategories = foreach ($GPO in $GPOs) {
|
||||
if ($GPOPath) {
|
||||
$GPOOutput = $GPO.GPOOutput
|
||||
@@ -109,6 +115,7 @@
|
||||
# Build reports based on categories
|
||||
if ($Output['CategoriesFull'].Count -gt 0) {
|
||||
foreach ($Report in $Type) {
|
||||
Write-Verbose "Invoke-GPOZaurr - Processing report type $Report"
|
||||
foreach ($CategoryType in $Script:GPODitionary[$Report].Types) {
|
||||
$Category = $CategoryType.Category
|
||||
$Settings = $CategoryType.Settings
|
||||
@@ -142,6 +149,7 @@
|
||||
}
|
||||
}
|
||||
if ($Script:GPODitionary[$Report]['CodeSingle']) {
|
||||
#Write-Verbose "Invoke-GPOZaurr - Processing $Report single entry mode"
|
||||
$TranslatedGpo = Invoke-Command -ScriptBlock $Script:GPODitionary[$Report]['CodeSingle']
|
||||
if ($Report -in $FindRequiredSingle) {
|
||||
foreach ($T in $TranslatedGpo) {
|
||||
@@ -160,6 +168,7 @@
|
||||
# think drive mapping - showing 1 mapping of a drive per object even if there are 50 drive mappings within 1 gpo
|
||||
# this would result in 50 objects created
|
||||
if ($Script:GPODitionary[$Report]['Code']) {
|
||||
#Write-Verbose "Invoke-GPOZaurr - Processing $Report multi entry mode"
|
||||
$TranslatedGpo = Invoke-Command -ScriptBlock $Script:GPODitionary[$Report]['Code']
|
||||
foreach ($T in $TranslatedGpo) {
|
||||
$Output['Reports'][$Report].Add($T)
|
||||
@@ -178,6 +187,7 @@
|
||||
$Output['Reports'][$Report] = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
}
|
||||
$FindReport = $ReportType.Report
|
||||
Write-Verbose "Invoke-GPOZaurr - Processing reports based on other report $Report ($FindReport)"
|
||||
foreach ($GPO in $TemporaryCachedSingleReports['ReportsSingle'][$FindReport]) {
|
||||
$TranslatedGpo = Invoke-Command -ScriptBlock $Script:GPODitionary[$Report]['CodeReport']
|
||||
foreach ($T in $TranslatedGpo) {
|
||||
@@ -193,7 +203,8 @@
|
||||
if (-not $SkipNormalize) {
|
||||
foreach ($Report in [string[]] $Output['Reports'].Keys) {
|
||||
$FirstProperties = 'DisplayName', 'DomainName', 'GUID', 'GpoType'
|
||||
$EndProperties = 'CreatedTime', 'ModifiedTime', 'ReadTime', 'Filters', 'Linked', 'LinksCount', 'Links'
|
||||
#$EndProperties = 'CreatedTime', 'ModifiedTime', 'ReadTime', 'Filters', 'Linked', 'LinksCount', 'Links'
|
||||
$EndProperties = 'Filters', 'Linked', 'LinksCount', 'Links'
|
||||
$Properties = $Output['Reports'][$Report] | Select-Properties -ExcludeProperty ($FirstProperties + $EndProperties) -AllProperties -WarningAction SilentlyContinue
|
||||
$DisplayProperties = @(
|
||||
$FirstProperties
|
||||
@@ -210,9 +221,38 @@
|
||||
#$Output['PoliciesTotal'] = $Output.Reports.Policies.PolicyCategory | Group-Object | Select-Object Name, Count | Sort-Object -Property Count -Descending
|
||||
|
||||
if (-not $SkipCleanup) {
|
||||
Write-Verbose "Invoke-GPOZaurr - Cleaning up output"
|
||||
Remove-EmptyValue -Hashtable $Output -Recursive
|
||||
}
|
||||
return $Output
|
||||
if ($Extended) {
|
||||
$Output
|
||||
} else {
|
||||
if ($Output.Reports) {
|
||||
if ($OutputType -eq 'Object') {
|
||||
$Output.Reports
|
||||
}
|
||||
if ($OutputType -eq 'HTML') {
|
||||
if (-not $OutputPath) {
|
||||
$OutputPath = Get-FileName -Extension 'html' -Temporary
|
||||
Write-Warning "Invoke-GPOZaurr - OutputPath not given. Using $OutputPath"
|
||||
}
|
||||
Write-Verbose "Invoke-GPOZaurr - Generating HTML output"
|
||||
New-HTML {
|
||||
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
|
||||
New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
|
||||
New-HTMLTableOption -DataStore JavaScript
|
||||
foreach ($Key in $Output.Reports.Keys) {
|
||||
New-HTMLTab -Name $Key {
|
||||
Write-Verbose "Invoke-GPOZaurr - Generating HTML Table for $Key"
|
||||
New-HTMLTable -DataTable $Output.Reports[$Key] -Filtering -Title $Key
|
||||
}
|
||||
}
|
||||
} -FilePath $OutputPath -ShowHTML:$Open -Online:$Online
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Invoke-GPOZaurr - There was no data output for requested types."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[scriptblock] $SourcesAutoCompleter = {
|
||||
|
||||
@@ -7,26 +7,30 @@
|
||||
[string] $Path,
|
||||
[string] $Splitter = [System.Environment]::NewLine,
|
||||
[switch] $PreventShow,
|
||||
[switch] $Offline
|
||||
[switch] $Offline,
|
||||
[switch] $ForceGPResult
|
||||
)
|
||||
# if user didn't choose anything, lets run as currently logged in user locally
|
||||
if (-not $UserName -and -not $ComputerName) {
|
||||
$UserName = $Env:USERNAME
|
||||
|
||||
# we can also check if the session is Administrative and if so request computer policies
|
||||
if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
|
||||
$ComputerName = $Env:COMPUTERNAME
|
||||
}
|
||||
}
|
||||
|
||||
If ($Type -eq 'HTML') {
|
||||
$Exists = Get-Command -Name 'New-HTML' -ErrorAction SilentlyContinue
|
||||
if (-not $Exists) {
|
||||
Write-Warning "Request-GPOZaurr - PSWriteHTML module is required for HTML functionality. Use XML, Object or NativeHTML option instead."
|
||||
Write-Warning "Invoke-GPOZaurrSupport - PSWriteHTML module is required for HTML functionality. Use XML, Object or NativeHTML option instead."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$Command = Get-Command -Name 'Get-GPResultantSetOfPolicy' -ErrorAction SilentlyContinue
|
||||
$NativeCommand = Get-Command -Name 'gpresult' -ErrorAction SilentlyContinue
|
||||
if (-not $Command -and -not $NativeCommand) {
|
||||
Write-Warning "Invoke-GPOZaurrSupport - Neither gpresult or Get-GPResultantSetOfPolicy are available. Terminating."
|
||||
return
|
||||
}
|
||||
|
||||
$SplatPolicy = @{}
|
||||
if ($Type -in 'Object', 'XML', 'HTML') {
|
||||
@@ -50,22 +54,42 @@
|
||||
if ($UserName) {
|
||||
$SplatPolicy['User'] = $UserName
|
||||
}
|
||||
try {
|
||||
#Write-Verbose "Request-GPOZaurr - ComputerName: $($SplatPolicy['Computer']) UserName: $($SplatPolicy['User'])"
|
||||
$ResultantSetPolicy = Get-GPResultantSetOfPolicy @SplatPolicy -ErrorAction Stop
|
||||
} catch {
|
||||
if ($_.Exception.Message -eq 'Exception from HRESULT: 0x80041003') {
|
||||
Write-Warning "Request-GPOZaurr - Are you running as admin? $($_.Exception.Message)"
|
||||
return
|
||||
} else {
|
||||
$ErrorMessage = $($_.Exception.Message).Replace([Environment]::NewLine, ' ')
|
||||
Write-Warning "Request-GPOZaurr - Error: $ErrorMessage"
|
||||
return
|
||||
if ($Command -and -not $ForceGPResult) {
|
||||
try {
|
||||
#Write-Verbose "Request-GPOZaurr - ComputerName: $($SplatPolicy['Computer']) UserName: $($SplatPolicy['User'])"
|
||||
$ResultantSetPolicy = Get-GPResultantSetOfPolicy @SplatPolicy -ErrorAction Stop
|
||||
} catch {
|
||||
if ($_.Exception.Message -eq 'Exception from HRESULT: 0x80041003') {
|
||||
Write-Warning "Request-GPOZaurr - Are you running as admin? $($_.Exception.Message)"
|
||||
return
|
||||
} else {
|
||||
$ErrorMessage = $($_.Exception.Message).Replace([Environment]::NewLine, ' ')
|
||||
Write-Warning "Request-GPOZaurr - Error: $ErrorMessage"
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$Arguments = @(
|
||||
if ($SplatPolicy['Computer']) {
|
||||
"/S $ComputerName"
|
||||
}
|
||||
if ($SplatPolicy['User']) {
|
||||
"/USER $($SplatPolicy['User'])"
|
||||
}
|
||||
if ($SplatPolicy['ReportType'] -eq 'HTML') {
|
||||
'/H'
|
||||
} elseif ($SplatPolicy['ReportType'] -eq 'XML') {
|
||||
'/X'
|
||||
}
|
||||
$SplatPolicy['Path']
|
||||
"/F"
|
||||
)
|
||||
Write-Verbose "Invoke-GPOZaurrSupport - GPResult Arguments: $Arguments"
|
||||
Start-Process -NoNewWindow -FilePath 'gpresult' -ArgumentList $Arguments -Wait
|
||||
}
|
||||
if ($Type -eq 'NativeHTML') {
|
||||
if (-not $PreventShow) {
|
||||
Write-Verbose "Invoke-GPOZaurrSupport - Opening up file $SplatPolicy['Path']"
|
||||
Write-Verbose "Invoke-GPOZaurrSupport - Opening up file $($SplatPolicy['Path'])"
|
||||
Start-Process -FilePath $SplatPolicy['Path']
|
||||
}
|
||||
return
|
||||
@@ -109,4 +133,72 @@
|
||||
New-GPOZaurrReportHTML -Path $Path -Offline:$Offline -Open:(-not $PreventShow) -Support $Output
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
|
||||
|
||||
GPRESULT [/S system [/U username [/P [password]]]] [/SCOPE scope]
|
||||
[/USER targetusername] [/R | /V | /Z] [(/X | /H) <filename> [/F]]
|
||||
|
||||
Description:
|
||||
This command line tool displays the Resultant Set of Policy (RSoP)
|
||||
information for a target user and computer.
|
||||
|
||||
Parameter List:
|
||||
/S system Specifies the remote system to connect to.
|
||||
|
||||
/U [domain\]user Specifies the user context under which the
|
||||
command should run.
|
||||
Can not be used with /X, /H.
|
||||
|
||||
/P [password] Specifies the password for the given user
|
||||
context. Prompts for input if omitted.
|
||||
Cannot be used with /X, /H.
|
||||
|
||||
/SCOPE scope Specifies whether the user or the
|
||||
computer settings need to be displayed.
|
||||
Valid values: "USER", "COMPUTER".
|
||||
|
||||
/USER [domain\]user Specifies the user name for which the
|
||||
RSoP data is to be displayed.
|
||||
|
||||
/X <filename> Saves the report in XML format at the
|
||||
location and with the file name specified
|
||||
by the <filename> parameter. (valid in Windows
|
||||
Vista SP1 and later and Windows Server 2008 and later)
|
||||
|
||||
/H <filename> Saves the report in HTML format at the
|
||||
location and with the file name specified by
|
||||
the <filename> parameter. (valid in Windows
|
||||
at least Vista SP1 and at least Windows Server 2008)
|
||||
|
||||
/F Forces Gpresult to overwrite the file name
|
||||
specified in the /X or /H command.
|
||||
|
||||
/R Displays RSoP summary data.
|
||||
|
||||
/V Specifies that verbose information should
|
||||
be displayed. Verbose information provides
|
||||
additional detailed settings that have
|
||||
been applied with a precedence of 1.
|
||||
|
||||
/Z Specifies that the super-verbose
|
||||
information should be displayed. Super-
|
||||
verbose information provides additional
|
||||
detailed settings that have been applied
|
||||
with a precedence of 1 and higher. This
|
||||
allows you to see if a setting was set in
|
||||
multiple places. See the Group Policy
|
||||
online help topic for more information.
|
||||
|
||||
/? Displays this help message.
|
||||
|
||||
|
||||
Examples:
|
||||
GPRESULT /R
|
||||
GPRESULT /H GPReport.html
|
||||
GPRESULT /USER targetusername /V
|
||||
GPRESULT /S system /USER targetusername /SCOPE COMPUTER /Z
|
||||
GPRESULT /S system /U username /P password /SCOPE USER /V
|
||||
#>
|
||||
@@ -0,0 +1,74 @@
|
||||
function Remove-GPOZaurrOrphaned {
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[ValidateSet('SYSVOL', 'AD')][string[]] $Type = @('SYSVOL', 'AD'),
|
||||
[string] $BackupPath,
|
||||
[switch] $BackupDated,
|
||||
[int] $LimitProcessing = [int32]::MaxValue,
|
||||
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
if ($BackupPath) {
|
||||
if ($BackupDated) {
|
||||
$BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))"
|
||||
} else {
|
||||
$BackupFinalPath = $BackupPath
|
||||
}
|
||||
} else {
|
||||
$BackupFinalPath = ''
|
||||
}
|
||||
Get-GPOZaurrSysvol -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation | Where-Object {
|
||||
if ($Type -contains 'SYSVOL') {
|
||||
if ($_.Status -eq 'Not available in AD') {
|
||||
$_
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'AD') {
|
||||
if ($_.Status -eq 'Not available on SYSVOL') {
|
||||
$_
|
||||
}
|
||||
}
|
||||
} | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object {
|
||||
if ($_.Status -eq 'Not available in AD') {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Processing $($_.Path)"
|
||||
if ($BackupFinalPath) {
|
||||
Try {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Backing up $($_.Path)"
|
||||
Copy-Item -LiteralPath $_.Path -Recurse -Destination $BackupFinalPath -ErrorAction Stop
|
||||
$BackupWorked = $true
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Error backing up error: $($_.Exception.Message)"
|
||||
$BackupWorked = $false
|
||||
}
|
||||
}
|
||||
if ($BackupWorked -or $BackupFinalPath -eq '') {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Deleting $($_.Path)"
|
||||
try {
|
||||
Remove-Item -Recurse -Force -LiteralPath $_.Path
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Failed to remove file $($_.Path): $($_.Exception.Message)."
|
||||
}
|
||||
}
|
||||
} elseif ($_.Status -eq 'Not available on SYSVOL') {
|
||||
try {
|
||||
$ExistingObject = Get-ADObject -Identity $_.DistinguishedName -Server $_.DomainName -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Error getting $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
|
||||
$ExistingObject = $null
|
||||
}
|
||||
if ($ExistingObject -and $ExistingObject.ObjectClass -eq 'groupPolicyContainer') {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Removing DN: $($_.DistinguishedName) / ObjectClass: $($ExistingObject.ObjectClass)"
|
||||
try {
|
||||
Remove-ADObject -Server $_.DomainName -Identity $_.DistinguishedName -Recursive -Confirm:$false
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Failed to remove $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - DistinguishedName $($_.DistinguishedName) not found or ObjectClass is not groupPolicyContainer ($($ExistingObject.ObjectClass))"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
function Remove-GPOZaurrOrphanedSysvolFolders {
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[string] $BackupPath,
|
||||
[switch] $BackupDated,
|
||||
[int] $LimitProcessing = [int32]::MaxValue,
|
||||
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
if ($BackupPath) {
|
||||
if ($BackupDated) {
|
||||
$BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))"
|
||||
} else {
|
||||
$BackupFinalPath = $BackupPath
|
||||
}
|
||||
} else {
|
||||
$BackupFinalPath = ''
|
||||
}
|
||||
Get-GPOZaurrSysvol -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation | Where-Object {
|
||||
if ($_.Status -eq 'Orphaned GPO') {
|
||||
$_
|
||||
}
|
||||
} | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object {
|
||||
Write-Verbose "Remove-GPOZaurrOrphanedSysvolFolders - Processing $($_.Path)"
|
||||
if ($BackupFinalPath) {
|
||||
Try {
|
||||
Write-Verbose "Remove-GPOZaurrOrphanedSysvolFolders - Backing up $($_.Path)"
|
||||
Copy-Item -LiteralPath $_.Path -Recurse -Destination $BackupFinalPath -ErrorAction Stop
|
||||
$BackupWorked = $true
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphanedSysvolFolders - Error backing up error: $($_.Exception.Message)"
|
||||
$BackupWorked = $false
|
||||
}
|
||||
}
|
||||
if ($BackupWorked -or $BackupFinalPath -eq '') {
|
||||
Write-Verbose "Remove-GPOZaurrOrphanedSysvolFolders - Deleting $($_.Path)"
|
||||
try {
|
||||
Remove-Item -Recurse -Force -LiteralPath $_.Path
|
||||
} catch {
|
||||
$ErrorMessage = $_.Exception.Message
|
||||
Write-Warning "Remove-GPOZaurrOrphanedSysvolFolders - Failed to remove file $($_.Path): $($ErrorMessage)."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
[alias('GUID', 'GPOID')][string] $GPOGuid,
|
||||
|
||||
[string[]] $Principal,
|
||||
[validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid',
|
||||
[validateset('DistinguishedName', 'Name', 'NetbiosName', 'Sid')][string] $PrincipalType = 'Sid',
|
||||
|
||||
[validateset('Unknown', 'NotAdministrative', 'Default')][string[]] $Type = 'Default',
|
||||
|
||||
|
||||
@@ -17,8 +17,12 @@
|
||||
}
|
||||
}
|
||||
$null = New-Item -ItemType Directory -Path $GPOPath -Force
|
||||
Write-Verbose "Save-GPOZaurrFiles - Gathering GPO data"
|
||||
$Count = 0
|
||||
$GPOs = Get-GPOZaurrAD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
foreach ($GPO in $GPOS) {
|
||||
$Count++
|
||||
Write-Verbose "Save-GPOZaurrFiles - Processing GPO ($Count/$($GPOS.Count)) $($GPO.DomainName) | $($GPO.DisplayName)"
|
||||
$XMLContent = Get-GPOReport -ID $GPO.Guid -ReportType XML -Domain $GPO.DomainName
|
||||
$GPODOmainFolder = [io.path]::Combine($GPOPath, $GPO.DomainName)
|
||||
if (-not (Test-Path -Path $GPODOmainFolder)) {
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
function Show-GPOZaurr {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[string] $FilePath,
|
||||
[ValidateSet(
|
||||
'GPOList', 'GPOOrphans', 'GPOPermissions', 'GPOPermissionsRoot',
|
||||
'GPOConsistency', 'GPOOwners', 'GPOAnalysis', 'NetLogon'
|
||||
)][string[]] $Type
|
||||
)
|
||||
if ($Type -contains 'GPOList' -or $null -eq $Type) {
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO List"
|
||||
$GPOSummary = Get-GPOZaurr
|
||||
$GPOLinked = $GPOSummary.Where( { $_.Linked -eq $true }, 'split')
|
||||
$GPOEmpty = $GPOSummary.Where( { $_.Empty -eq $true, 'split' })
|
||||
$GPOTotal = $GPOSummary.Count
|
||||
}
|
||||
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Sysvol"
|
||||
$GPOOrphans = Get-GPOZaurrSysvol
|
||||
}
|
||||
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions"
|
||||
$GPOPermissions = Get-GPOZaurrPermission -Type All -IncludePermissionType GpoEditDeleteModifySecurity, GpoEdit, GpoCustom -IncludeOwner
|
||||
}
|
||||
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Consistency"
|
||||
$GPOPermissionsConsistency = Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance
|
||||
[Array] $Inconsistent = $GPOPermissionsConsistency.Where( { $_.ACLConsistent -eq $true } , 'split' )
|
||||
[Array] $InconsistentInside = $GPOPermissionsConsistency.Where( { $_.ACLConsistentInside -eq $true }, 'split' )
|
||||
}
|
||||
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Root"
|
||||
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot
|
||||
}
|
||||
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
|
||||
Write-Verbose "Show-GPOZaurr - Processing GPO Owners"
|
||||
$GPOOwners = Get-GPOZaurrOwner -IncludeSysvol
|
||||
$IsOwnerConsistent = $GPOOwners.Where( { $_.IsOwnerConsistent -eq $true } , 'split' )
|
||||
$IsOwnerAdministrative = $GPOOwners.Where( { $_.IsOwnerAdministrative -eq $true } , 'split' )
|
||||
}
|
||||
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
|
||||
Write-Verbose "Get-GPOZaurrNetLogon - Processing NETLOGON Share"
|
||||
$Netlogon = Get-GPOZaurrNetlogon
|
||||
}
|
||||
if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
|
||||
Write-Verbose "Show-GPOZaurr - Processing GPO Analysis"
|
||||
$GPOContent = Invoke-GPOZaurr
|
||||
}
|
||||
|
||||
Write-Verbose "Show-GPOZaurr - Generating HTML"
|
||||
New-HTML {
|
||||
New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
|
||||
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
|
||||
New-HTMLTableOption -DataStore JavaScript
|
||||
New-HTMLTab -Name 'Overview' {
|
||||
if ($Type -contains 'GPOConsistency' -or $Type -contains 'GPOList' -or $null -eq $Type) {
|
||||
New-HTMLSection -Invisible {
|
||||
if ($Type -contains 'GPOList' -or $null -eq $Type) {
|
||||
New-HTMLPanel {
|
||||
New-HTMLChart -Title 'Group Policies Summary' {
|
||||
New-ChartLegend -Names 'Unlinked', 'Linked', 'Empty', 'Total' -Color Salmon, PaleGreen, PaleVioletRed, PaleTurquoise
|
||||
New-ChartBar -Name 'Group Policies' -Value $GPOLinked[1].Count, $GPOLinked[0].Count, $GPOEmpty[1].Count, $GPOTotal
|
||||
} -TitleAlignment center
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
|
||||
New-HTMLPanel {
|
||||
New-HTMLChart {
|
||||
New-ChartBarOptions -Type barStacked
|
||||
New-ChartLegend -Name 'Consistent', 'Inconsistent'
|
||||
New-ChartBar -Name 'TopLevel' -Value $Inconsistent[0].Count, $Inconsistent[1].Count
|
||||
New-ChartBar -Name 'Inherited' -Value $InconsistentInside[0].Count, $InconsistentInside[1].Count
|
||||
} -Title 'Permissions Consistency' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOOwners' -or $Type -contains 'GPOOwners' -or $null -eq $Type) {
|
||||
New-HTMLSection -Invisible {
|
||||
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
|
||||
New-HTMLPanel {
|
||||
New-HTMLText -Text 'Following chart presents Group Policy owners and whether they are administrative and consistent. By design an owner of Group Policy should be Domain Admins or Enterprise Admins group only to prevent malicious takeover. ', `
|
||||
"It's also important that owner in Active Directory matches owner on SYSVOL (file system)."
|
||||
New-HTMLChart {
|
||||
New-ChartBarOptions -Type barStacked
|
||||
New-ChartLegend -Name 'Yes', 'No' -Color PaleGreen, Orchid
|
||||
New-ChartBar -Name 'Is administrative' -Value $IsOwnerAdministrative[0].Count, $IsOwnerAdministrative[1].Count
|
||||
New-ChartBar -Name 'Is consistent' -Value $IsOwnerConsistent[0].Count, $IsOwnerConsistent[1].Count
|
||||
} -Title 'Group Policy Owners'
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
|
||||
New-HTMLPanel {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOList' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Group Policies Summary' {
|
||||
New-HTMLTable -DataTable $GPOSummary -Filtering {
|
||||
New-HTMLTableCondition -Name 'Empty' -Value $true -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
|
||||
New-HTMLTableCondition -Name 'Linked' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Sysvol' {
|
||||
New-HTMLTable -DataTable $GPOOrphans -Filtering {
|
||||
New-HTMLTableCondition -Name 'Status' -Value "Not available in AD" -BackgroundColor Salmon -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'Status' -Value "Not available on SYSVOL" -BackgroundColor Salmon -ComparisonType string
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'NetLogon' {
|
||||
New-HTMLTable -DataTable $Netlogon -Filtering
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOPermissionsRoot' -or $Type -contains 'GPOOwners' -or
|
||||
$Type -contains 'GPOPermissions' -or $Type -contains 'GPOConsistency' -or
|
||||
$null -eq $Type
|
||||
) {
|
||||
New-HTMLTab -Name 'Permissions' {
|
||||
if ($Type -contains 'GPOPermissionsRoot' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Root' {
|
||||
New-HTMLTable -DataTable $GPOPermissionsRoot -Filtering
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Owners' {
|
||||
New-HTMLTable -DataTable $GPOOwners -Filtering
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Edit & Modify' {
|
||||
New-HTMLTable -DataTable $GPOPermissions -Filtering
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Permissions Consistency' {
|
||||
New-HTMLTable -DataTable $GPOPermissionsConsistency -Filtering {
|
||||
New-HTMLTableCondition -Name 'ACLConsistent' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
|
||||
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Analysis' {
|
||||
foreach ($Key in $GPOContent.Keys) {
|
||||
New-HTMLTab -Name $Key {
|
||||
New-HTMLTable -DataTable $GPOContent[$Key] -Filtering -Title $Key
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} -Online -ShowHTML -FilePath $FilePath
|
||||
}
|
||||
@@ -49,6 +49,35 @@ That's it. Whenever there's a new version, you run the command, and you can enjo
|
||||
|
||||
## Changelog
|
||||
|
||||
- 0.0.63 - 19.10.2020
|
||||
- Renamed `Invoke-GPOZaurrContent` back to `Invoke-GPOZaurr`
|
||||
- Added `Show-GPOZaurr` (WIP)
|
||||
- Added `OutputType`,`OutputType`,`Open`,`Online` parameters to `Invoke-GPOZaurr`
|
||||
- Added `Get-GPOZaurrNetLogon`
|
||||
- Improved `Get-GPOZaurrOwner`
|
||||
- Fixes `Get-GPOZaurrSysvol`
|
||||
- 0.0.62 - 14.10.2020
|
||||
- Renamed `Invoke-GPOZaurr` to `Invoke-GPOZaurrContent` - I want to use `Invoke-GPOZaurr` for something else
|
||||
- Improvements to `Get-GPOZaurrPermissionConsistency` for GPOs without SYSVOL to be reported properly
|
||||
- Added `Get-GPOZaurrPermissionRoot`
|
||||
- Renamed `Remove-GPOZaurrOrphanedSysvolFolders` to `Remove-GPOZaurrOrphaned`
|
||||
- Improved `Remove-GPOZaurrOrphaned` to deal with orphaned folders but also orphaned AD GPO (No sysvol data)
|
||||
- Improved `Get-GPOZaurrSysVol` to detect orphaned SYSVOL or AD GPO objects
|
||||
- Improved `Get-GPOZaurrSysVol` to detect permissions issue when reading AD GPO objects
|
||||
- Added `Get-GPOZaurrPermissionRoot` to show which users/groups have control over all GPOs (allowed to create/modify)
|
||||
- Improved `Get-GPOZaurrPermissionSummary` to include `Get-GPOZaurrPermissionRoot` custom permissions
|
||||
- Updated `Remove-GPOZaurrPermission`
|
||||
- Updated `Get-GpoZaurrPermission`
|
||||
- Updated `Get-GPOZaurrFiles` to better handle access issue
|
||||
- Reversed parameters `Get-GPOZaurrFiles` from `Limited` to `ExtendedMetaData` and fixed missing columns
|
||||
- 0.0.61 - 31.08.2020
|
||||
- Improvement to `Get-GPOZaurrPermissionSummary`
|
||||
- Fixes to `ConvertFrom-CSExtension`
|
||||
- Fixes to `Find-CSExtension`
|
||||
- 0.0.59 - 26.08.2020
|
||||
- Improvement to `Get-GPOZaurrPermissionSummary`
|
||||
- 0.0.58 - 26.08.2020
|
||||
- Improvement to `Get-GPOZaurrPermissionSummary`
|
||||
- 0.0.57 - 26.08.2020
|
||||
- Improvement to `Get-GPOZaurrPermissionSummary`
|
||||
- 0.0.56 - 26.08.2020
|
||||
|
||||
Reference in New Issue
Block a user