diff --git a/Private/Get-PrivGPOZaurrLInk.ps1 b/Private/Get-PrivGPOZaurrLInk.ps1 new file mode 100644 index 0000000..6c18448 --- /dev/null +++ b/Private/Get-PrivGPOZaurrLInk.ps1 @@ -0,0 +1,53 @@ +function Get-PrivGPOZaurrLink { + [cmdletBinding()] + param( + [Microsoft.ActiveDirectory.Management.ADObject] $Object, + [switch] $Limited, + [System.Collections.IDictionary] $GPOCache + ) + if ($Object.GpLink -and $Object.GpLink.Trim() -ne '') { + $Object.GpLink -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object { + if ($_) { + $Output = [ordered] @{ + DistinguishedName = $Object.DistinguishedName + CanonicalName = $Object.CanonicalName + Guid = [Regex]::Match( $_, '(?={)(.*)(?<=})').Value -replace '{' -replace '}' + } + if ($GPOCache -and -not $Limited) { + $Output['Name'] = $GPOCache[$Output['Guid']].DisplayName + $Output['DomainName'] = $GPOCache[$Output['Guid']].DomainName + $Output['Owner'] = $GPOCache[$Output['Guid']].Owner + $Output['GpoStatus'] = $GPOCache[$Output['Guid']].GpoStatus + $Output['Description'] = $GPOCache[$Output['Guid']].Description + $Output['CreationTime'] = $GPOCache[$Output['Guid']].CreationTime + $Output['ModificationTime'] = $GPOCache[$Output['Guid']].ModificationTime + } + $Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDC + $Output['GPOLink'] = $_ + [PSCustomObject] $Output + } + } + } elseif ($Object.LinkedGroupPolicyObjects -and $Object.LinkedGroupPolicyObjects.Trim() -ne '') { + $Object.LinkedGroupPolicyObjects -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object { + if ($_) { + $Output = [ordered] @{ + DistinguishedName = $Object.DistinguishedName + CanonicalName = $Object.CanonicalName + Guid = [Regex]::Match( $_, '(?={)(.*)(?<=})').Value -replace '{' -replace '}' + } + if ($GPOCache -and -not $Limited) { + $Output['Name'] = $GPOCache[$Output['Guid']].DisplayName + $Output['DomainName'] = $GPOCache[$Output['Guid']].DomainName + $Output['Owner'] = $GPOCache[$Output['Guid']].Owner + $Output['GpoStatus'] = $GPOCache[$Output['Guid']].GpoStatus + $Output['Description'] = $GPOCache[$Output['Guid']].Description + $Output['CreationTime'] = $GPOCache[$Output['Guid']].CreationTime + $Output['ModificationTime'] = $GPOCache[$Output['Guid']].ModificationTime + } + $Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDC + $Output['GPOLink'] = $_ + [PSCustomObject] $Output + } + } + } +} \ No newline at end of file diff --git a/Private/Get-PrivPermission.ps1 b/Private/Get-PrivPermission.ps1 index b0020bc..8acf1af 100644 --- a/Private/Get-PrivPermission.ps1 +++ b/Private/Get-PrivPermission.ps1 @@ -14,31 +14,37 @@ ) Write-Verbose "Get-GPOZaurrPermission - Processing $($GPO.DisplayName) from $($GPO.DomainName)" $SecurityRights = $GPO.GetSecurityInfo() + $Index = 0 $SecurityRights | ForEach-Object -Process { #Get-GPPermissions -Guid $GPO.ID -DomainName $GPO.DomainName -All -Server $QueryServer | ForEach-Object -Process { $GPOPermission = $_ if ($ExcludePermissionType -contains $GPOPermission.Permission) { + $Index++ return } if ($IncludePermissionType) { if ($IncludePermissionType -notcontains $GPOPermission.Permission) { + $Index++ return } } if ($SkipWellKnown.IsPresent) { if ($GPOPermission.Trustee.SidType -eq 'WellKnownGroup') { + $Index++ return } } if ($SkipAdministrative.IsPresent) { $IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value] if ($IsAdministrative) { + $Index++ return } } if ($Type -contains 'Unknown' -and $Type -notcontains 'All') { # May need updates if there's more types if ($GPOPermission.Trustee.SidType -ne 'Unknown') { + $Index++ return } } @@ -60,24 +66,38 @@ } if ($Accounts) { $A = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name) - #$TranslatedUser = $Accounts[$A] - $ReturnObject['UserPrincipalName'] = $Accounts[$A].UserPrincipalName - $ReturnObject['AccountEnabled'] = $Accounts[$A].Enabled - $ReturnObject['PasswordLastSet'] = if ($Accounts[$A].PasswordLastSet) { $Accounts[$A].PasswordLastSet } else { '' } - $ReturnObject['LastLogonDate'] = if ($Accounts[$A].LastLogonDate ) { $Accounts[$A].LastLogonDate } else { '' } - if ($Accounts[$A].ObjectClass -eq 'group') { - $ReturnObject['SidType'] = 'Group' - } elseif ($Accounts[$A].ObjectClass -eq 'user') { - $ReturnObject['SidType'] = 'user' - } #else { - - #} + 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' + } + } else { + $ReturnObject['UserPrincipalName'] = '' + $ReturnObject['AccountEnabled'] = '' + $ReturnObject['PasswordLastSet'] = '' + $ReturnObject['LastLogonDate'] = '' + } } if ($IncludeGPOObject) { $ReturnObject['GPOObject'] = $GPO $ReturnObject['GPOSecurity'] = $SecurityRights + $ReturnObject['GPOSecurityPermissionIndex'] = $Index } [PSCustomObject] $ReturnObject + $Index++ } if ($IncludeOwner.IsPresent) { if ($GPO.Owner) { @@ -117,28 +137,35 @@ } if ($Accounts) { $A = $GPO.Owner - #$TranslatedUser = $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' + 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' + } } else { - $ReturnObject['SidType'] = 'EmptyOrUnknown' + $ReturnObject['UserPrincipalName'] = '' + $ReturnObject['AccountEnabled'] = '' + $ReturnObject['PasswordLastSet'] = '' + $ReturnObject['LastLogonDate'] = '' } } if ($IncludeGPOObject) { - $ReturnObject.GPOObject = $GPO - $ReturnObject.GPOSecurity = $SecurityRights + $ReturnObject['GPOObject'] = $GPO + $ReturnObject['GPOSecurity'] = $SecurityRights + $ReturnObject['GPOSecurityPermissionIndex'] = $null } [PSCustomObject] $ReturnObject } diff --git a/Public/Add-GPOZaurrPermission.ps1 b/Public/Add-GPOZaurrPermission.ps1 new file mode 100644 index 0000000..8da4276 --- /dev/null +++ b/Public/Add-GPOZaurrPermission.ps1 @@ -0,0 +1,108 @@ +function Add-GPOZaurrPermission { + [cmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'GPOGUID')] + param( + [Parameter(ParameterSetName = 'GPOName', Mandatory)] + [string] $GPOName, + + [Parameter(ParameterSetName = 'GPOGUID', Mandatory)] + [alias('GUID', 'GPOID')][string] $GPOGuid, + + [Parameter(ParameterSetName = 'ADObject', Mandatory)] + [alias('OrganizationalUnit', 'DistinguishedName')][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject, + + [string] $Principal, + [Microsoft.GroupPolicy.GPPermissionType[]] $PermissionType, + [switch] $Inheritable, + + [alias('ForestName')][string] $Forest, + [string[]] $ExcludeDomains, + [alias('Domain', 'Domains')][string[]] $IncludeDomains, + [System.Collections.IDictionary] $ExtendedForestInformation, + + [int] $LimitProcessing + ) + Begin { + $Count = 0 + } + Process { + + if ($GPOName) { + $Splat = @{ + GPOName = $GPOName + } + } elseif ($GPOGUID) { + $Splat = @{ + GPOGUID = $GPOGUID + } + } else { + $Splat = @{ + + } + } + + $Splat['IncludeGPOObject'] = $true + $Splat['Forest'] = $Forest + $Splat['IncludeDomains'] = $IncludeDomains + $Splat['ExcludeDomains'] = $ExcludeDomains + $Splat['ExtendedForestInformation'] = $ExtendedForestInformation + #$Splat['ExcludePermissionType'] = $ExcludePermissionType + #$Splat['IncludePermissionType'] = $PermissionType- + $Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent + $Splat['SkipAdministrative'] = $SkipAdministrative.IsPresent + + # Get-GPOZaurrPermission @Splat + + #Set-GPPermission -PermissionLevel $PermissionType -TargetName $Principal -TargetType Group -Verbose -DomainName 'ad.evotec.xyz' -Name $GPOName -Replace #-WhatIf + + #continue + [Array] $GPOPermissions = Get-GPOZaurrPermission @Splat + [Array] $LimitedPermissions = foreach ($GPOPermission in $GPOPermissions) { + #$GPOPermission = $_ + # continue + if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) { + Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)" + $GPOPermission + #break + } + # Write-Verbose "Test" + # $GPOPermission + + + + + #$GPOPermission.GPOSecurity.Add + #void Add(Microsoft.GroupPolicy.GPPermission item) + #void ICollection[GPPermission].Add(Microsoft.GroupPolicy.GPPermission item) + #int IList.Add(System.Object value) + + + # $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + } + + if ($LimitedPermissions.Count -gt 0) { + #$LimitedPermissions + } else { + try { + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)" + $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) + $GPOPermissions[0].GPOSecurity.Add($AddPermission) + $GPOPermissions[0].GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + + <# + [Microsoft.GroupPolicy.GPPermission]::new + + OverloadDefinitions + ------------------- + Microsoft.GroupPolicy.GPPermission new(string trustee, Microsoft.GroupPolicy.GPPermissionType rights, bool inheritable) + Microsoft.GroupPolicy.GPPermission new(System.Security.Principal.IdentityReference identity, Microsoft.GroupPolicy.GPPermissionType rights, bool inheritable) + + #> + } + } + End { + + } +} \ No newline at end of file diff --git a/Public/Get-GPOZaurr.ps1 b/Public/Get-GPOZaurr.ps1 index 4639fb9..dd32767 100644 --- a/Public/Get-GPOZaurr.ps1 +++ b/Public/Get-GPOZaurr.ps1 @@ -28,7 +28,12 @@ Get-GPO -Name $GPOName -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object { Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain" if (-not $Limited) { - $XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain + try { + $XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop + } catch { + Write-Warning "Get-GPOZaurr - Failed to ger GPOReport: $($_.Exception.Message). Skipping." + continue + } Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups } else { $_ @@ -38,7 +43,12 @@ Get-GPO -Guid $GPOGuid -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object { Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain" if (-not $Limited) { - $XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain + try { + $XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop + } catch { + Write-Warning "Get-GPOZaurr - Failed to ger GPOReport: $($_.Exception.Message). Skipping." + continue + } Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups } else { $_ @@ -48,7 +58,12 @@ Get-GPO -All -Server $QueryServer -Domain $Domain -ErrorAction SilentlyContinue | ForEach-Object { Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain" if (-not $Limited) { - $XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain + try { + $XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop + } catch { + Write-Warning "Get-GPOZaurr - Failed to ger GPOReport: $($_.Exception.Message). Skipping." + continue + } Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups } else { $_ diff --git a/Public/Get-GPOZaurrLink.ps1 b/Public/Get-GPOZaurrLink.ps1 new file mode 100644 index 0000000..6fe8e33 --- /dev/null +++ b/Public/Get-GPOZaurrLink.ps1 @@ -0,0 +1,64 @@ +function Get-GPOZaurrLink { + [cmdletbinding()] + param( + [parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject, + [switch] $Limited, + [System.Collections.IDictionary] $GPOCache, + + [string] $Filter = '*', + [string] $SearchBase, + [Microsoft.ActiveDirectory.Management.ADSearchScope] $SearchScope, + + + [alias('ForestName')][string] $Forest, + [string[]] $ExcludeDomains, + [alias('Domain', 'Domains')][string[]] $IncludeDomains, + [System.Collections.IDictionary] $ExtendedForestInformation + ) + Begin { + $ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation + if (-not $GPOCache -and -not $Limited) { + $GPOCache = @{ } + foreach ($Domain in $ForestInformation.Domains) { + $QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0] + Get-GPO -All -DomainName $Domain -Server $QueryServer | ForEach-Object { + $GPOCache[$_.ID.Guid] = $_ + } + } + } + } + Process { + if (-not $ADObject) { + foreach ($Domain in $ForestInformation.Domains) { + $Splat = @{ + Filter = $Filter + Properties = 'distinguishedName', 'gplink', 'CanonicalName' + Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0] + } + if ($PSBoundParameters.ContainsKey('SearchBase')) { + $DomainDistinguishedName = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName'] + if ($SearchBase -notlike "*$DomainDistinguishedName") { + # we check if SearchBase is part of domain distinugishname. If it isn't we skip + continue + } + $Splat['SearchBase'] = $SearchBase + + } + if ($PSBoundParameters.ContainsKey('SearchScope')) { + $Splat['SearchScope'] = $SearchScope + } + + Get-ADObject @Splat | ForEach-Object { + Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache + } + } + } else { + foreach ($Object in $ADObject) { + Get-PrivGPOZaurrLink -Object $Object -Limited:$Limited.IsPresent -GPOCache $GPOCache + } + } + } + End { + + } +} \ No newline at end of file diff --git a/Public/Get-GPOZaurrPassword.ps1 b/Public/Get-GPOZaurrPassword.ps1 index 46fbde3..3e1902e 100644 --- a/Public/Get-GPOZaurrPassword.ps1 +++ b/Public/Get-GPOZaurrPassword.ps1 @@ -14,7 +14,7 @@ $ForestInformation = $ExtendedForestInformation } - $GPOPath = foreach ($Domain in $ForestInformation.Domains) { + [Array] $GPOPath = foreach ($Domain in $ForestInformation.Domains) { -join ('\\', $Domain, '\SYSVOL\', $Domain, '\Policies') } } diff --git a/Public/Get-GPOZaurrWmi.ps1 b/Public/Get-GPOZaurrWmi.ps1 index 92a4e7c..290ebc6 100644 --- a/Public/Get-GPOZaurrWmi.ps1 +++ b/Public/Get-GPOZaurrWmi.ps1 @@ -20,9 +20,9 @@ Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer | ForEach-Object -Process { $WMI = $_.'msWMI-Parm2' -split ';' [PSCustomObject] @{ - DisplayName = $_.'msWMI-Name' + DisplayName = $_.'msWMI-Name' Description = $_.'msWMI-Parm1' - DomainName = $Domain + DomainName = $Domain NameSpace = $WMI[5] Query = $WMI[6] Author = $_.'msWMI-Author' @@ -44,9 +44,9 @@ Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer | ForEach-Object -Process { $WMI = $_.'msWMI-Parm2' -split ';' [PSCustomObject] @{ - DisplayName = $_.'msWMI-Name' + DisplayName = $_.'msWMI-Name' Description = $_.'msWMI-Parm1' - DomainName = $Domain + DomainName = $Domain NameSpace = $WMI[5] Query = $WMI[6] Author = $_.'msWMI-Author' @@ -68,9 +68,9 @@ Get-ADObject -LDAPFilter $ldapFilter -Properties $wmiFilterAttr -Server $QueryServer | ForEach-Object -Process { $WMI = $_.'msWMI-Parm2' -split ';' [PSCustomObject] @{ - DisplayName = $_.'msWMI-Name' + DisplayName = $_.'msWMI-Name' Description = $_.'msWMI-Parm1' - DomainName = $Domain + DomainName = $Domain NameSpace = $WMI[5] Query = $WMI[6] Author = $_.'msWMI-Author' diff --git a/Public/Remove-GPOZaurr.ps1 b/Public/Remove-GPOZaurr.ps1 index dfde4e2..83bc3f1 100644 --- a/Public/Remove-GPOZaurr.ps1 +++ b/Public/Remove-GPOZaurr.ps1 @@ -35,12 +35,13 @@ Write-Verbose "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName)" $BackupInfo = Backup-GPO -Guid $_.Guid -Domain $_.DomainName -Path $BackupFinalPath -ErrorAction Stop #-Server $QueryServer $BackupInfo + $BackupOK = $true } catch { Write-Warning "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)" - + $BackupOK = $false } } - if (($BackupRequired -and $BackupInfo) -or (-not $BackupRequired)) { + if (($BackupRequired -and $BackupOK) -or (-not $BackupRequired)) { try { Write-Verbose "Remove-GPOZaurr - Removing GPO $($_.DisplayName) from $($_.DomainName)" Remove-GPO -Domain $_.DomainName -Guid $_.Guid -ErrorAction Stop #-Server $QueryServer @@ -61,11 +62,13 @@ Write-Verbose "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName)" $BackupInfo = Backup-GPO -Guid $_.Guid -Domain $_.DomainName -Path $BackupFinalPath -ErrorAction Stop #-Server $QueryServer $BackupInfo + $BackupOK = $true } catch { Write-Warning "Remove-GPOZaurr - Backing up GPO $($_.DisplayName) from $($_.DomainName) failed: $($_.Exception.Message)" + $BackupOK = $false } } - if (($BackupRequired -and $BackupInfo) -or (-not $BackupRequired)) { + if (($BackupRequired -and $BackupOK) -or (-not $BackupRequired)) { try { Write-Verbose "Remove-GPOZaurr - Removing GPO $($_.DisplayName) from $($_.DomainName)" Remove-GPO -Domain $_.DomainName -Guid $_.Guid -ErrorAction Stop #-Server $QueryServer diff --git a/Public/Remove-GPOZaurrPermission.ps1 b/Public/Remove-GPOZaurrPermission.ps1 index eb1efb5..632d579 100644 --- a/Public/Remove-GPOZaurrPermission.ps1 +++ b/Public/Remove-GPOZaurrPermission.ps1 @@ -1,5 +1,5 @@ function Remove-GPOZaurrPermission { - [cmdletBinding(SupportsShouldProcess)] + [cmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Global')] param( [Parameter(ParameterSetName = 'GPOName', Mandatory)] [string] $GPOName, @@ -7,11 +7,12 @@ [Parameter(ParameterSetName = 'GPOGUID', Mandatory)] [alias('GUID', 'GPOID')][string] $GPOGuid, - [Parameter(ParameterSetName = 'GPOGUID', Mandatory)] - [validateset('Unknown', 'Named')][string[]] $Type, + [string] $Principal, + [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName', + [validateset('Unknown', 'Named', 'NonAdministrative', 'Default')][string[]] $Type = 'Default', - [Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType, + [alias('PermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType, [Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType, [switch] $SkipWellKnown, [switch] $SkipAdministrative, @@ -33,14 +34,54 @@ Write-Warning "Remove-GPOZaurrPermission - When using type Named you need to provide names to remove. Terminating." return } - Get-GPOZaurrPermission -IncludeGPOObject -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -ExcludePermissionType $ExcludePermissionType -IncludePermissionType $IncludePermissionType -SkipWellKnown:$SkipWellKnown.IsPresent -SkipAdministrative:$SkipAdministrative.IsPresent | ForEach-Object -Process { + if ($GPOName) { + $Splat = @{ + GPOName = $GPOName + } + } elseif ($GPOGUID) { + $Splat = @{ + GPOGUID = $GPOGUID + } + } else { + $Splat = @{ + + } + } + + $Splat['IncludeGPOObject'] = $true + $Splat['Forest'] = $Forest + $Splat['IncludeDomains'] = $IncludeDomains + $Splat['ExcludeDomains'] = $ExcludeDomains + $Splat['ExtendedForestInformation'] = $ExtendedForestInformation + $Splat['ExcludePermissionType'] = $ExcludePermissionType + $Splat['IncludePermissionType'] = $IncludePermissionType + $Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent + $Splat['SkipAdministrative'] = $SkipAdministrative.IsPresent + + + # $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid) + #void RemoveTrustee(string trustee) + #void RemoveTrustee(System.Security.Principal.IdentityReference identity) + #$GPOPermission.GPOSecurity.Remove + #void RemoveAt(int index) + #void IList[GPPermission].RemoveAt(int index) + #void IList.RemoveAt(int index) + + Get-GPOZaurrPermission @Splat | ForEach-Object -Process { $GPOPermission = $_ if ($Type -contains 'Unknown') { if ($GPOPermission.SidType -eq 'Unknown') { #Write-Verbose "Remove-GPOZaurrPermission - Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)" if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)")) { - $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid) - $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + try { + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $($GPOPermission.Permission) for $($GPOPermission.Sid)" + $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid) + $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + #$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) + #$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + } catch { + Write-Warning "Remove-GPOZaurrPermission - Removing permission $($GPOPermission.Permission) for $($GPOPermission.Sid) with error: $($_.Exception.Message)" + } # Set-GPPPermission doesn't work on Unknown Accounts } $Count++ @@ -51,8 +92,19 @@ } } if ($Type -contains 'Named') { + <# + if ($PrincipalType -eq 'DistinguishedName') { - if ($Named -contains $GPOPermission.Sid) { + } elseif ($PrincipalType -eq 'Sid') { + if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { + + } + } elseif ($PrincipalType -eq 'Name') { + if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { + + } + } + if ($NamedObjects -contains $GPOPermission.Sid) { #Write-Verbose "Remove-GPOZaurrPermission - Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)" if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)")) { $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid) @@ -65,6 +117,44 @@ break } } + #> + } + if ($Type -contains 'NonAdministrative') { + + } + if ($Type -contains 'Default') { + if ($PrincipalType -eq 'DistinguishedName') { + if ($GPOPermission.DistinguishedName -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { + try { + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" + $GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) + $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + } catch { + Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + } + } elseif ($PrincipalType -eq 'Sid') { + if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { + try { + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" + $GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) + $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + } catch { + Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + } + } elseif ($PrincipalType -eq 'Name') { + if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { + try { + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" + $GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) + $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + } catch { + Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + } + } + } #Set-GPPermission -PermissionLevel None -TargetName $GPOPermission.Sid -Verbose -DomainName $GPOPermission.DomainName -Guid $GPOPermission.GUID #-WhatIf #Set-GPPermission -PermissionLevel GpoRead -TargetName 'Authenticated Users' -TargetType Group -Verbose -DomainName $Domain -Guid $_.GUID -WhatIf diff --git a/Public/Set-GPOZaurrOwner.ps1 b/Public/Set-GPOZaurrOwner.ps1 index be00cc0..d41fbe6 100644 --- a/Public/Set-GPOZaurrOwner.ps1 +++ b/Public/Set-GPOZaurrOwner.ps1 @@ -2,7 +2,7 @@ [cmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Type')] param( [Parameter(ParameterSetName = 'Type', Mandatory)] - [validateset('EmptyOrUnknown', 'NonAdministrative')][string[]] $Type, + [validateset('EmptyOrUnknown', 'NonAdministrative', 'All')][string[]] $Type, [Parameter(ParameterSetName = 'Named')][string] $GPOName, [Parameter(ParameterSetName = 'Named')][alias('GUID', 'GPOID')][string] $GPOGuid, @@ -23,7 +23,8 @@ [Parameter(ParameterSetName = 'Named')] [System.Collections.IDictionary] $ExtendedForestInformation, - [Parameter(Mandatory, ParameterSetName = 'Named')] + [Parameter(ParameterSetName = 'Type')] + [Parameter(ParameterSetName = 'Named')] [string] $Principal, [Parameter(ParameterSetName = 'Type')] @@ -31,36 +32,57 @@ [int] $LimitProcessing ) Begin { - if ($Type -contains 'NonAdministrative') { - $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation - } + $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation $Count = 0 } Process { if ($Type) { Get-GPOZaurr -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Verbose:$false | ForEach-Object -Process { $GPO = $_ - if ($Type -contains 'NonAdministrative') { + if ($Type -contains 'All') { + # Regardless who is the owner it is overwritten + if ($Principal) { + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + } else { + $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + $Count++ + if ($Count -eq $LimitProcessing) { + break + } + } + } + if ($Type -contains 'NonAdministrative' -and $Type -notcontains 'All') { if ($GPO.Owner) { $AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"] - $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] - if ($AdministrativeGroup) { - #Write-Verbose "Set-GPOZaurrOwner - Skipping GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName). Already owner $($GPO.Owner)." - } else { - Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $DefaultPrincipal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false - $Count++ - if ($Count -eq $LimitProcessing) { - break + if (-not $AdministrativeGroup) { + if ($Principal) { + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + } else { + $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + $Count++ + if ($Count -eq $LimitProcessing) { + break + } } } } } - if ($Type -contains 'EmptyOrUnknown') { + if ($Type -contains 'EmptyOrUnknown' -and $Type -notcontains 'All') { if ($null -eq $GPO.Owner) { - $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] - Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner NULL/$($GPO.OwnerSID) to $DefaultPrincipal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false + if ($Principal) { + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner NULL/$($GPO.OwnerSID) to $Principal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + } else { + $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner NULL/$($GPO.OwnerSID) to $DefaultPrincipal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + } $Count++ if ($Count -eq $LimitProcessing) { break @@ -71,8 +93,14 @@ } else { Get-GPOZaurr -GPOName $GPOName -GPOGuid $GPOGUiD -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Verbose:$false | ForEach-Object -Process { $GPO = $_ - Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $Principal -Verbose:$false + if ($Principal) { + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $Principal -Verbose:$false -WhatIf:$WhatIfPreference + } else { + $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] + Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal" + Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + } $Count++ if ($Count -eq $LimitProcessing) { break