Remediation/Consolidation/CMP-SETTINGS.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 Compares the sensitive settings of each source with the target and has each gap decided (procedure CMP-SETTINGS). .DESCRIPTION Data read: the gaps of the plan, source by source. Each gap is classed by its effect on users. decisions\CMP-SETTINGS.csv: one row per source and per setting. - Keep target: the value of the target stays. This is the proposal: the target does not lower itself to a less strict source without a written decision. The users of the source lose or gain a capability, to announce; - Exception: the customer wants to change the target. The setting goes to CON-SETTINGS, which holds the single value; - Not applicable: technical gap, with no effect for users. The script writes to no tenant: a global value of the target also touches its current users, and one decision must hold it. It produces the list of capabilities that change, for the communication plan. Limit: the target design is not in the snapshot, it is read during the meeting with the customer. #> $c = Open-TcRemediation $TechnicalOnes = 'StorageQuota|OrganizationFederatedMailbox|ConfigMetadata|OrphanedPersonalSitesRetentionPeriod' function Get-SettingEffect { param([string]$Setting) switch -Regex ($Setting) { 'AutoAdmitted|Lobby|PSTN' { return 'Lobby' } 'Recording|Transcription' { return 'Record' } 'Invit|Guest|ExternalUser' { return 'Guests' } 'Sharing|Link|Anonymous|Reshar|External access|Bots?' { return 'Sharing' } 'Method|permissionGrant|User permissions' { return 'Authentication and applications' } $TechnicalOnes { return 'Technical' } default { return 'Other' } } } $proposals = foreach ($t in $c.Tenants) { Write-TcRemediationTenant $t 'Gaps read against the target' $items = @(Get-TcRemediationPlanAction -Procedure 'CMP-SETTINGS' -Tenant $t | ForEach-Object { (Get-TcMember $_ 'items') } | Where-Object { $_ }) Write-TcRemediationNote ("{0} setting(s) differ from the target" -f $items.Count) foreach ($e in $items) { if ([string]$e -notmatch '^(?<s>.+?) - (?<p>.+?): (?<v>.*?) to (?<d>.*)$') { Write-TcRemediationAlert "Unreadable plan item: $e"; continue } $setting = $Matches['p'] $effect = Get-SettingEffect $setting [ordered]@{ Tenant = $t; Service = $Matches['s']; Setting = $setting; Effect = $effect; 'Source value' = $Matches['v']; 'Target value' = $Matches['d'] Proposal = $(if ($effect -eq 'Technical') { 'Not applicable' } else { 'Keep target' }) } } } $decisions = @(Get-TcDecision -Name 'CMP-SETTINGS' -Proposal @($proposals | Where-Object { $_ }) -Key 'Tenant', 'Service', 'Setting' -Choice 'Keep target', 'Exception', 'Not applicable') $announcements = @($decisions | Where-Object { (Get-TcMember $_ 'Decision') -eq 'Keep target' }) if ($announcements.Count) { Export-TcRemediationReport -Name 'capabilities-that-change' -Rows @($announcements | Sort-Object Tenant, Effect | ForEach-Object { [ordered]@{ Tenant = (Get-TcMember $_ 'Tenant'); Effect = (Get-TcMember $_ 'Effect'); Service = (Get-TcMember $_ 'Service'); Setting = (Get-TcMember $_ 'Setting'); 'Today' = (Get-TcMember $_ 'Source value'); 'In target' = (Get-TcMember $_ 'Target value') } }) | Out-Null } $exceptions = @($decisions | Where-Object { (Get-TcMember $_ 'Decision') -eq 'Exception' }) if ($exceptions.Count) { Write-TcRemediationNote ("{0} exception(s): to carry into CON-SETTINGS, the only decision that changes the target" -f $exceptions.Count) } Invoke-TcRemediationPlan Close-TcRemediation |