|
80 | 80 | $ADObject, |
81 | 81 |
|
82 | 82 | [bool] |
83 | | - $Disable |
| 83 | + $Disable, |
| 84 | + |
| 85 | + $Changes, |
| 86 | + |
| 87 | + $Definition |
84 | 88 | ) |
85 | 89 | $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential |
86 | 90 |
|
87 | | - if (-not $Disable) { |
| 91 | + $newChanges = foreach ($change in $Definition) { |
| 92 | + if ($change.Policy -notin $Changes.Policy) { |
| 93 | + $change.ToLink() |
| 94 | + continue |
| 95 | + } |
| 96 | + if (-not $Disable) { continue } |
| 97 | + |
| 98 | + '[LDAP://{0};1]' -f $change.PolicyDN |
| 99 | + } |
| 100 | + |
| 101 | + if (-not $newChanges) { |
88 | 102 | Set-ADObject @parameters -Identity $ADObject -Clear gPLink -ErrorAction Stop |
89 | 103 | return |
90 | 104 | } |
91 | | - Set-ADObject @parameters -Identity $ADObject -Replace @{ gPLink = ($ADObject.gPLink -replace ";\d\]", ";1]") } -ErrorAction Stop -Confirm:$false |
| 105 | + Set-ADObject @parameters -Identity $ADObject -Replace @{ gPLink = $newChanges -join '' } -ErrorAction Stop -Confirm:$false |
92 | 106 | } |
93 | 107 |
|
94 | 108 | function New-Link { |
|
103 | 117 |
|
104 | 118 | $ADObject, |
105 | 119 |
|
106 | | - $Configuration, |
107 | | - |
108 | | - [Hashtable] |
109 | | - $GpoNameMapping |
| 120 | + $Changes |
110 | 121 | ) |
111 | 122 | $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential |
112 | 123 |
|
113 | | - $gpLinkString = ($Configuration.Include | Sort-Object -Property @{ Expression = { $_.Tier }; Descending = $false }, Precedence -Descending | ForEach-Object { |
114 | | - $gpoDN = $GpoNameMapping[(Resolve-String -Text $_.PolicyName)] |
115 | | - if (-not $gpoDN) { |
116 | | - Write-PSFMessage -Level Warning -String 'Invoke-DMGPLink.New.GpoNotFound' -StringValues (Resolve-String -Text $_.PolicyName) -Target $ADObject -FunctionName Invoke-DMGPLink |
117 | | - return |
118 | | - } |
119 | | - $stateID = "0" |
120 | | - if ($_.State -eq 'Enforced') { $stateID = "2" } |
121 | | - if ($_.State -eq 'Disabled') { $stateID = "1" } |
122 | | - "[LDAP://$gpoDN;$stateID]" |
123 | | - }) -Join "" |
| 124 | + $gpLinkString = @($Changes | Sort-Object -Property @{ Expression = { $_.Tier }; Descending = $false }, Precedence -Descending).ForEach{ $_.ToLink() } -Join "" |
124 | 125 | Write-PSFMessage -Level Debug -String 'Invoke-DMGPLink.New.NewGPLinkString' -StringValues $ADObject.DistinguishedName, $gpLinkString -Target $ADObject -FunctionName Invoke-DMGPLink |
125 | 126 | Set-ADObject @parameters -Identity $ADObject -Replace @{ gPLink = $gpLinkString } -ErrorAction Stop -Confirm:$false |
126 | 127 | } |
|
145 | 146 | [Hashtable] |
146 | 147 | $GpoNameMapping, |
147 | 148 |
|
| 149 | + |
| 150 | + [AllowNull()] |
148 | 151 | $Changes |
149 | 152 | ) |
150 | 153 | $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential |
151 | 154 |
|
152 | | - $gpLinkString = '' |
153 | | - if ($Disable) { |
154 | | - $desiredDNs = $Configuration.ExtendedInclude.PolicyName | Resolve-String | ForEach-Object { $GpoNameMapping[$_] } |
155 | | - $gpLinkString += ($ADobject.LinkedGroupPolicyObjects | Where-Object DistinguishedName -NotIn $desiredDNs | Sort-Object -Property Precedence -Descending | ForEach-Object { |
156 | | - "[LDAP://$($_.DistinguishedName);1]" |
157 | | - }) -join "" |
| 155 | + $allItems = $Configuration.Definition | Sort-Object -Property @{ Expression = { $_.Tier }; Descending = $false }, Precedence -Descending |
| 156 | + $itemsToInclude = $allItems | Where-Object { |
| 157 | + ($_.Action -in 'None', 'State', 'Reorder') -or |
| 158 | + ( |
| 159 | + ($_.Action -eq 'Add') -and |
| 160 | + ($_.Policy -in $Changes.Policy) |
| 161 | + ) -or |
| 162 | + ( |
| 163 | + ($_.Action -eq 'Delete') -and |
| 164 | + ($_.Policy -notin $Changes.Policy) -and |
| 165 | + (-not $Disable) |
| 166 | + ) |
158 | 167 | } |
159 | | - |
160 | | - $gpLinkString += ($Configuration.ExtendedInclude | Where-Object DistinguishedName | Sort-Object -Property @{ Expression = { $_.Tier }; Descending = $false }, Precedence -Descending | ForEach-Object { |
161 | | - $_.ToLink() |
162 | | - }) -Join "" |
| 168 | + |
| 169 | + $dontReorder = $allItems | Where-Object { |
| 170 | + ($_.Action -eq 'Reorder') -and |
| 171 | + ($_.Policy -notin $Changes.Policy) |
| 172 | + } |
| 173 | + foreach ($noReorderItem in $dontReorder | Sort-Object OriginalPosition) { |
| 174 | + $below = $null |
| 175 | + $above = $null |
| 176 | + if ($noReorderItem.OriginalPosition -gt 1) { $below = $allItems | Where-Object OriginalPosition -eq ($noReorderItem.OriginalPosition - 1) } |
| 177 | + else { $above = $allItems | Where-Object OriginalPosition -eq ($noReorderItem.OriginalPosition + 1) } |
| 178 | + |
| 179 | + $allOtherItems = $itemsToInclude | Where-Object { $_ -ne $noReorderItem } |
| 180 | + if ($above) { |
| 181 | + $index = $allOtherItems.IndexOf($above) |
| 182 | + $itemsAbove = @() |
| 183 | + if ($index -gt 0) { $itemsAbove = @($allOtherItems[0..($index-1)]) } |
| 184 | + $itemsBelow = @($allOtherItems[$index..(@($allOtherItems).Count - 1)]) |
| 185 | + } |
| 186 | + else { |
| 187 | + $index = $allOtherItems.IndexOf($below) |
| 188 | + $itemsAbove = @($allOtherItems[0..($index-1)]) |
| 189 | + $itemsBelow = @() |
| 190 | + if ($index -lt ($allOtherItems.Count - 1)) { $itemsBelow = @($allOtherItems[($index)..($allOtherItems.Count - 1)])} |
| 191 | + } |
| 192 | + $itemsToInclude = $itemsAbove + $noReorderItem + $itemsBelow |
| 193 | + } |
| 194 | + |
| 195 | + $gpLinkString = @($itemsToInclude).ForEach{ $_.ToLink() } -join "" |
| 196 | + |
163 | 197 | $msgParam = @{ |
164 | 198 | Level = 'SomewhatVerbose' |
165 | 199 | Tag = 'change' |
|
200 | 234 | Stop-PSFFunction -String 'General.Invalid.Input' -StringValues 'Test-DMGPLink', $testItem -Target $testItem -Continue -EnableException $EnableException |
201 | 235 | } |
202 | 236 |
|
203 | | - $countConfigured = ($testItem.Configuration | Measure-Object).Count |
| 237 | + $countConfigured = ($testItem.Changed | Measure-Object).Count |
204 | 238 | $countActual = ($testItem.ADObject.LinkedGroupPolicyObjects | Measure-Object).Count |
205 | 239 | $countNotInConfig = ($testItem.ADObject.LinkedGroupPolicyObjects | Where-Object DistinguishedName -NotIn ($testItem.Configuration.PolicyName | Remove-PSFNull | Resolve-String | ForEach-Object { $gpoDisplayToDN[$_] }) | Measure-Object).Count |
206 | 240 |
|
207 | 241 | switch ($testItem.Type) { |
208 | 242 | 'Delete' { |
209 | 243 | Invoke-PSFProtectedCommand -ActionString 'Invoke-DMGPLink.Delete.AllEnabled' -ActionStringValues $countActual -Target $testItem -ScriptBlock { |
210 | | - Clear-Link @parameters -ADObject $testItem.ADObject -Disable $Disable -ErrorAction Stop |
| 244 | + Clear-Link @parameters -ADObject $testItem.ADObject -Disable $Disable -Changes $testItem.Changed -Definition $testItem.Configuration.Definition -ErrorAction Stop |
211 | 245 | } -EnableException $EnableException.ToBool() -PSCmdlet $PSCmdlet -Continue |
212 | 246 | } |
213 | 247 | 'Create' { |
214 | 248 | Invoke-PSFProtectedCommand -ActionString 'Invoke-DMGPLink.New' -ActionStringValues $countConfigured -Target $testItem -ScriptBlock { |
215 | | - New-Link @parameters -ADObject $testItem.ADObject -Configuration $testItem.Configuration -GpoNameMapping $gpoDisplayToDN -ErrorAction Stop |
| 249 | + New-Link @parameters -ADObject $testItem.ADObject -Changes $testItem.Changed -ErrorAction Stop |
216 | 250 | } -EnableException $EnableException.ToBool() -PSCmdlet $PSCmdlet -Continue |
217 | 251 | } |
218 | 252 | 'Update' { |
|
0 commit comments