Remediation/Consolidation/CON-TEAMS-POLICIES.ps1
|
# UNTESTED: this script has never been run on a real tenant. Read it, try it on a test tenant first, and use it at your own risk. <# .SYNOPSIS Designs a single set of Teams policies for the target and creates the missing policies (procedure CON-TEAMS-POLICIES). .DESCRIPTION Reads the teamsPolicies table of each source and of the target, then groups the custom policies by type and by name, not by source. decisions\CON-TEAMS-POLICIES.csv says for each: Reuse (it exists in the target), Recreate or Set aside. Only Recreate writes to the target, with New-Cs<Type> -Identity: the policy starts from the global values of the target. Limit: the script does not copy the settings of the source. If they matter, adjust them in the Teams admin center. The assignment by group and rank is done by TMS-POLICIES. #> $c = Open-TcRemediation function Get-PolicyName { param([string]$Identity) return ($Identity -replace '^Tag:', '') } $target = @{} foreach ($p in Get-TcRemediationTable 'Target' 'teamsPolicies') { $target[('{0}|{1}' -f $p['Type'], (Get-PolicyName $p['Identity']))] = 1 } $byKey = [ordered]@{} foreach ($t in @($c.Tenants | Where-Object { $_ -ne 'Target' })) { Write-TcRemediationTenant $t $personal = @(Get-TcRemediationTable $t 'teamsPolicies' | Where-Object { ConvertTo-TcBoolean $_['Custom'] }) Write-TcRemediationNote ("{0} custom policy(ies) read" -f $personal.Count) foreach ($p in $personal) { $name = Get-PolicyName $p['Identity'] $key = '{0}|{1}' -f $p['Type'], $name if (-not $byKey.Contains($key)) { $byKey[$key] = [ordered]@{ Type = $p['Type']; Policy = $name; Sources = [System.Collections.Generic.List[string]]::new() } } $byKey[$key].Sources.Add($t) } } $proposals = foreach ($key in $byKey.Keys) { $e = $byKey[$key] $exists = $target.ContainsKey($key) [ordered]@{ Type = (Get-TcMember $e 'Type'); Policy = (Get-TcMember $e 'Policy'); Sources = ((Get-TcMember $e 'Sources') -join ', '); 'Exists in target' = $(if ($exists) { 'Yes' } else { 'No' }); Proposal = $(if ($exists) { 'Reuse' } else { '' }) } } if ('Target' -in $c.Tenants) { Write-TcRemediationTenant 'Target' } $missingOnes = @($proposals | Where-Object { $_['Exists in target'] -eq 'No' }) Write-TcRemediationNote ("{0} distinct policy(ies), including {1} missing from the target" -f @($proposals).Count, $missingOnes.Count) $decisions = @(Get-TcDecision -Name 'CON-TEAMS-POLICIES' -Proposal @($proposals) -Key 'Type', 'Policy' -Choice 'Reuse', 'Recreate', 'Set aside') foreach ($d in $decisions | Where-Object { (Get-TcMember $_ 'Decision') -eq 'Recreate' }) { if ((Get-TcMember $d 'Exists in target') -eq 'Yes') { Write-TcRemediationAlert ("{0} {1} already exists in the target: Recreate decision ignored" -f (Get-TcMember $d 'Type'), (Get-TcMember $d 'Policy')); continue } Add-TcCommandAction -Tenant 'Target' -Service Teams -Command ("New-Cs{0}" -f (Get-TcMember $d 'Type')) -Parameters @{ Identity = (Get-TcMember $d 'Policy') } -Object ("{0} {1}" -f (Get-TcMember $d 'Type'), (Get-TcMember $d 'Policy')) ` -Description ("Create the policy {0} ({1})" -f (Get-TcMember $d 'Policy'), (Get-TcMember $d 'Type')) ` -Test { param($a) $readList = $a.command -replace '^New-', 'Get-' return [bool](@(Invoke-TcServiceCommand -Tenant $a.tenant -Service Teams -Command $readList) | Where-Object { (Get-PolicyName (Get-TcMember $_ 'Identity')) -eq $a.parameters.Identity }) } ` -Undo @{ command = ("Remove-Cs{0}" -f (Get-TcMember $d 'Type')); parameters = @{ Identity = (Get-TcMember $d 'Policy') } } } Invoke-TcRemediationPlan -Verify { param($t) if ($t -ne 'Target') { return } foreach ($d in @($decisions | Where-Object { (Get-TcMember $_ 'Decision') -eq 'Recreate' })) { $l = @(Invoke-TcServiceCommand -Tenant 'Target' -Service Teams -Command ("Get-Cs{0}" -f (Get-TcMember $d 'Type'))) | Where-Object { (Get-PolicyName (Get-TcMember $_ 'Identity')) -eq (Get-TcMember $d 'Policy') } if ($l) { New-TcRemediationResult OK ("{0} {1} present" -f (Get-TcMember $d 'Type'), (Get-TcMember $d 'Policy')) } else { New-TcRemediationResult Blocking ("{0} {1} missing" -f (Get-TcMember $d 'Type'), (Get-TcMember $d 'Policy')) } } } Close-TcRemediation |