functions/Import-GptPermission.ps1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
function Import-GptPermission { <# .SYNOPSIS Import permissions to GPOs. .DESCRIPTION Import permissions to GPOs. This tries to restore the same permissions that existed on the GPOs before the export. Notes: - It is highly recommended to perform this before executing Import-GptLink. - Executing this requires the identities to have been imported (Import-GptIdentity) .PARAMETER Path The path where the permission export file is stored. .PARAMETER Name Only restore permissions for GPOs with a matching name. .PARAMETER GpoObject Select the GPOs to restore permissions to by specifying their full object. .PARAMETER ExcludeInherited Do not import permissions that were inherited permissions on the source GPO .PARAMETER Domain The domain to restore the GPO permissions to. .EXAMPLE PS C:\> Import-GptPermission -Path '.' Import GPO permissions from the current path. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateScript({ Test-Path -Path $_ })] [string] $Path, [string[]] $Name = '*', [Parameter(ValueFromPipeline = $true)] $GpoObject, [switch] $ExcludeInherited, [string] $Domain = $env:USERDNSDOMAIN ) begin { #region Utility Functions function Update-GpoPermission { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( $ADObject, $Permission, $GpoObject, $DomainObject ) try { $accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList @( (ConvertFrom-ImportedIdentity -Permission $Permission -DomainObject $DomainObject), $Permission.ActiveDirectoryRights, $Permission.AccessControlType, $Permission.ObjectType, $Permission.InheritanceType, $Permission.InheritedObjectType ) } catch { New-ImportResult -Action 'Update Gpo Permission' -Step 'Resolving Identity' -Target $Permission.GpoName -Success $false -Data $Permission -ErrorData $_ return } $matchingRule = $null $matchingRule = $ADObject.ntSecurityDescriptor.Access | Where-Object { $accessRule.IdentityReference -eq $_.IdentityReference -and $accessRule.ActiveDirectoryRights -eq $_.ActiveDirectoryRights -and $accessRule.AccessControlType -eq $_.AccessControlType -and $accessRule.ObjectType -eq $_.ObjectType -and $accessRule.InheritanceType -eq $_.InheritanceType -and $accessRule.InheritedObjectType -eq $_.InheritedObjectType } if ($matchingRule) { New-ImportResult -Action 'Update Gpo Permission' -Step 'Skipped, already exists' -Target $Permission.GpoName -Success $true -Data $Permission, $accessRule return } #region Set AD Permissions try { Write-Verbose "Updating ACL on GPO $($ADObject.DistinguishedName)" $acl = Get-Acl -Path "AD:\$($ADObject.DistinguishedName)" -ErrorAction Stop $acl.AddAccessRule($accessRule) $acl | Set-Acl -Path "AD:\$($ADObject.DistinguishedName)" -ErrorAction Stop } catch { New-ImportResult -Action 'Update Gpo Permission' -Step 'Apply AD Permission' -Target $Permission.GpoName -Success $false -Data $Permission, $accessRule -ErrorData $_ continue } #endregion Set AD Permissions #region Set File Permissions if (-not (Test-Path $ADObject.gPCFileSysPath)) { New-ImportResult -Action 'Update Gpo Permission' -Step 'Apply File Permission' -Target $Permission.GpoName -Success $false -Data $Permission, $accessRule -ErrorData "Path not found" continue } try { $rights = 'Read' if ($accessRule.ActiveDirectoryRights -eq 983295) { $rights = 'FullControl' } $fileRule = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList @( $accessRule.IdentityReference $rights $accessRule.AccessControlType ) $acl = Get-Acl -Path $ADObject.gPCFileSysPath -ErrorAction Stop $acl.AddAccessRule($fileRule) $acl | Set-Acl -Path $ADObject.gPCFileSysPath -ErrorAction Stop } catch { New-ImportResult -Action 'Update Gpo Permission' -Step 'Apply File Permission' -Target $Permission.GpoName -Success $false -Data $Permission, $accessRule -ErrorData $_ continue } #endregion Set File Permissions New-ImportResult -Action 'Update Gpo Permission' -Step Success -Target $Permission.GpoName -Success $true -Data $Permission, $accessRule } #endregion Utility Functions $pathItem = Get-Item -Path $Path if ($pathItem.Extension -eq '.csv') { $resolvedPath = $pathItem.FullName } else { $resolvedPath = (Get-ChildItem -Path $pathItem.FullName -Filter 'gp_permissions_*.csv' | Select-Object -First 1).FullName } if (-not $resolvedPath) { throw "Could not find permissions file in $($pathItem.FullName)" } if (-not $script:identityMapping) { throw 'Could not find imported identities to match. Please run Import-GptIdentity first!' } $domainObject = Get-ADDomain -Server $Domain $allPermissionData = Import-Csv -Path $resolvedPath } process { $gpoObjects = $GpoObject if (-not $GpoObject) { $gpoObjects = Get-GPO -All -Domain $Domain } foreach ($gpoItem in $gpoObjects) { if (-not (Test-Overlap -ReferenceObject $gpoItem.DisplayName -DifferenceObject $Name -Operator Like)) { continue } $adObject = Get-ADObject -Identity $gpoItem.Path -Server $gpoItem.DomainName -Properties ntSecurityDescriptor, gPCFileSysPath foreach ($permission in $allPermissionData) { # Skip items that do not apply if ($permission.GpoName -ne $gpoItem.DisplayName) { continue } if ($ExcludeInherited -and $permission.IsInherited -eq "True") { continue } Update-GpoPermission -ADObject $adObject -Permission $permission -GpoObject $gpoItem -DomainObject $domainObject } } } } |