πΌ Management Samenvatting
retentiebeleid voor Teams chats ensures chat messages retained voor compliance.
Aanbeveling
IMPLEMENT
Risico zonder
Medium
Risk Score
5/10
Implementatie
2u (tech: 1u)
Van toepassing op:
β M365
β Teams
β Teams
Teams chats bevatten business communications. Zonder retention: chats deleted, e-discovery gaps, compliance schendingen.
PowerShell Modules Vereist
Primary API: Security & Compliance PowerShell
Connection:
Required Modules: ExchangeOnlineManagement
Connection:
Connect-IPPSSessionRequired Modules: ExchangeOnlineManagement
Implementatie
retentiebeleid: Teams chats, 7 years. voorkomt premature deletion.
- Security.microsoft.com β retentiebeleid
- Maak aan policy: Teams chats en channel messages
- Retention: 7 years
- Apply to alle users
Vereisten
M365 E3/E5
Implementatie
- Security.microsoft.com β retentiebeleid
- Maak aan policy: Teams chats en channel messages
- Retention: 7 years
- Apply to alle users
Compliance en Auditing
- BIO 18.01
- ISO 27001 A.18.1.3
Monitoring
Gebruik PowerShell-script retention-teams-chats.ps1 (functie Invoke-Monitoring) β Controleren.
Remediatie
Gebruik PowerShell-script retention-teams-chats.ps1 (functie Invoke-Remediation) β Herstellen.
Compliance & Frameworks
- BIO: 18.01 - Records retention
- ISO 27001:2022: A.18.1.3 - Records bescherming
Automation
Gebruik het onderstaande PowerShell script om deze security control te monitoren en te implementeren. Het script bevat functies voor zowel monitoring (-Monitoring) als remediation (-Remediation).
PowerShell
<#
.SYNOPSIS
Retention Policy Teams Chats 7 Jaar
.DESCRIPTION
Configures 7-year retention policy for Teams Chat Messages (1-on-1 chats).
Critical for compliance and eDiscovery.
.NOTES
Filename: retention-teams-chats.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.EXAMPLE
.\retention-teams-chats.ps1 -Monitoring
Check Teams chat retention
#>
#Requires -Version 5.1
#Requires -Modules ExchangeOnlineManagement
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[switch]$Monitoring,
[Parameter(Mandatory = $false)]
[switch]$Remediation,
[Parameter(Mandatory = $false)]
[switch]$Revert,
[switch]$WhatIf
)
$ErrorActionPreference = 'Stop'
$script:RetentionDays = 2555
$script:RetentionYears = 7
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Retention Policy Teams Chats 7 Jaar" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
function Invoke-Revert {
Write-Host "`nReverting configuration..." -ForegroundColor Cyan
try {
if ($WhatIf) {
Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow
return
}
# Revert implementation - requires manual implementation per control
Write-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <#
.SYNOPSIS
Retention Policy Teams Chats 7 Jaar
.DESCRIPTION
Configures 7-year retention policy for Teams Chat Messages (1-on-1 chats).
Critical for compliance and eDiscovery.
.NOTES
Filename: retention-teams-chats.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.EXAMPLE
.\retention-teams-chats.ps1 -Monitoring
Check Teams chat retention
#>
#Requires -Version 5.1
#Requires -Modules ExchangeOnlineManagement
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[switch]$Monitoring,
[Parameter(Mandatory=$false)]
[switch]$Remediation,
[Parameter(Mandatory=$false)]
[switch]$Revert,
[switch]$WhatIf
)
$ErrorActionPreference = 'Stop'
$script:RetentionDays = 2555
$script:RetentionYears = 7
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Retention Policy Teams Chats 7 Jaar" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
Write-Host "Checking Teams Chats retention..." -ForegroundColor Gray
$policies = Get-RetentionCompliancePolicy | Where-Object { $_.TeamsChatLocation -ne $null }
$result = @{ isCompliant = $false; total = $policies.Count; compliant = 0 }
if ($policies.Count -eq 0) {
Write-Host " [FAIL] No Teams Chat policies" -ForegroundColor Red
}
else {
foreach ($policy in $policies) {
$rules = Get-RetentionComplianceRule -Policy $policy.Name -ErrorAction SilentlyContinue
$maxDuration = 0
foreach ($rule in $rules) {
if ($rule.RetentionDuration) {
$duration = [int]$rule.RetentionDuration
if ($duration -gt $maxDuration) { $maxDuration = $duration }
if ($duration -ge $script:RetentionDays -and $policy.Enabled) {
$result.compliant++
$result.isCompliant = $true
}
}
}
Write-Host " $($policy.Name): $maxDuration days" -ForegroundColor $(
if ($maxDuration -ge $script:RetentionDays) { "Green" } else { "Yellow" }
)
}
}
Write-Host "`n Total: $($result.total) | Compliant: $($result.compliant)" -ForegroundColor Cyan
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
$policyName = "Teams Chats $script:RetentionYears Year Retention"
$policy = New-RetentionCompliancePolicy -Name $policyName `
-Comment "NL Baseline" `
-TeamsChatLocation All `
-Enabled $true
$rule = New-RetentionComplianceRule -Name "$policyName - Rule" `
-Policy $policyName `
-RetentionDuration $script:RetentionDays `
-RetentionComplianceAction Keep
Write-Host "`n[OK] Policy created" -ForegroundColor Green
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
try {
if ($Revert) {
Connect-IPPSSession -ShowBanner:$false
Remove-RetentionCompliancePolicy -Identity "Teams Chats $script:RetentionYears Year Retention" -Confirm:$false -ErrorAction SilentlyContinue
}
elseif ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Use: -Monitoring | -Remediation | -Revert" -ForegroundColor Yellow
}
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
Write-Host "Checking Teams Chats retention..." -ForegroundColor Gray
$policies = Get-RetentionCompliancePolicy | Where-Object { $_.TeamsChatLocation -ne $null }
$result = @{ isCompliant = $false; total = $policies.Count; compliant = 0 }
if ($policies.Count -eq 0) {
Write-Host " [FAIL] No Teams Chat policies" -ForegroundColor Red
}
else {
foreach ($policy in $policies) {
$rules = Get-RetentionComplianceRule -Policy $policy.Name -ErrorAction SilentlyContinue
$maxDuration = 0
foreach ($rule in $rules) {
if ($rule.RetentionDuration) {
$duration = [int]$rule.RetentionDuration
if ($duration -gt $maxDuration) { $maxDuration = $duration }
if ($duration -ge $script:RetentionDays -and $policy.Enabled) {
$result.compliant++
$result.isCompliant = $true
}
}
}
Write-Host " $($policy.Name): $maxDuration days" -ForegroundColor $(
if ($maxDuration -ge $script:RetentionDays) { "Green" } else { "Yellow" }
)
}
}
Write-Host "`n Total: $($result.total) | Compliant: $($result.compliant)" -ForegroundColor Cyan
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
function Invoke-Revert {
Write-Host "`nReverting configuration..." -ForegroundColor Cyan
try {
if ($WhatIf) {
Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow
return
}
# Revert implementation - requires manual implementation per control
Write-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <#
.SYNOPSIS
Retention Policy Teams Chats 7 Jaar
.DESCRIPTION
Configures 7-year retention policy for Teams Chat Messages (1-on-1 chats).
Critical for compliance and eDiscovery.
.NOTES
Filename: retention-teams-chats.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.EXAMPLE
.\retention-teams-chats.ps1 -Monitoring
Check Teams chat retention
#>
#Requires -Version 5.1
#Requires -Modules ExchangeOnlineManagement
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[switch]$Monitoring,
[Parameter(Mandatory=$false)]
[switch]$Remediation,
[Parameter(Mandatory=$false)]
[switch]$Revert,
[switch]$WhatIf
)
$ErrorActionPreference = 'Stop'
$script:RetentionDays = 2555
$script:RetentionYears = 7
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Retention Policy Teams Chats 7 Jaar" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
Write-Host "Checking Teams Chats retention..." -ForegroundColor Gray
$policies = Get-RetentionCompliancePolicy | Where-Object { $_.TeamsChatLocation -ne $null }
$result = @{ isCompliant = $false; total = $policies.Count; compliant = 0 }
if ($policies.Count -eq 0) {
Write-Host " [FAIL] No Teams Chat policies" -ForegroundColor Red
}
else {
foreach ($policy in $policies) {
$rules = Get-RetentionComplianceRule -Policy $policy.Name -ErrorAction SilentlyContinue
$maxDuration = 0
foreach ($rule in $rules) {
if ($rule.RetentionDuration) {
$duration = [int]$rule.RetentionDuration
if ($duration -gt $maxDuration) { $maxDuration = $duration }
if ($duration -ge $script:RetentionDays -and $policy.Enabled) {
$result.compliant++
$result.isCompliant = $true
}
}
}
Write-Host " $($policy.Name): $maxDuration days" -ForegroundColor $(
if ($maxDuration -ge $script:RetentionDays) { "Green" } else { "Yellow" }
)
}
}
Write-Host "`n Total: $($result.total) | Compliant: $($result.compliant)" -ForegroundColor Cyan
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
$policyName = "Teams Chats $script:RetentionYears Year Retention"
$policy = New-RetentionCompliancePolicy -Name $policyName `
-Comment "NL Baseline" `
-TeamsChatLocation All `
-Enabled $true
$rule = New-RetentionComplianceRule -Name "$policyName - Rule" `
-Policy $policyName `
-RetentionDuration $script:RetentionDays `
-RetentionComplianceAction Keep
Write-Host "`n[OK] Policy created" -ForegroundColor Green
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
try {
if ($Revert) {
Connect-IPPSSession -ShowBanner:$false
Remove-RetentionCompliancePolicy -Identity "Teams Chats $script:RetentionYears Year Retention" -Confirm:$false -ErrorAction SilentlyContinue
}
elseif ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Use: -Monitoring | -Remediation | -Revert" -ForegroundColor Yellow
}
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
$policyName = "Teams Chats $script:RetentionYears Year Retention"
$policy = New-RetentionCompliancePolicy -Name $policyName `
-Comment "NL Baseline" `
-TeamsChatLocation All `
-Enabled $true
$rule = New-RetentionComplianceRule -Name "$policyName - Rule" `
-Policy $policyName `
-RetentionDuration $script:RetentionDays `
-RetentionComplianceAction Keep
Write-Host "`n[OK] Policy created" -ForegroundColor Green
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Revert {
Write-Host "`nReverting configuration..." -ForegroundColor Cyan
try {
if ($WhatIf) {
Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow
return
}
# Revert implementation - requires manual implementation per control
Write-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <#
.SYNOPSIS
Retention Policy Teams Chats 7 Jaar
.DESCRIPTION
Configures 7-year retention policy for Teams Chat Messages (1-on-1 chats).
Critical for compliance and eDiscovery.
.NOTES
Filename: retention-teams-chats.ps1
Author: Nederlandse Baseline voor Veilige Cloud
.EXAMPLE
.\retention-teams-chats.ps1 -Monitoring
Check Teams chat retention
#>
#Requires -Version 5.1
#Requires -Modules ExchangeOnlineManagement
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[switch]$Monitoring,
[Parameter(Mandatory=$false)]
[switch]$Remediation,
[Parameter(Mandatory=$false)]
[switch]$Revert,
[switch]$WhatIf
)
$ErrorActionPreference = 'Stop'
$script:RetentionDays = 2555
$script:RetentionYears = 7
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Retention Policy Teams Chats 7 Jaar" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
Write-Host "Checking Teams Chats retention..." -ForegroundColor Gray
$policies = Get-RetentionCompliancePolicy | Where-Object { $_.TeamsChatLocation -ne $null }
$result = @{ isCompliant = $false; total = $policies.Count; compliant = 0 }
if ($policies.Count -eq 0) {
Write-Host " [FAIL] No Teams Chat policies" -ForegroundColor Red
}
else {
foreach ($policy in $policies) {
$rules = Get-RetentionComplianceRule -Policy $policy.Name -ErrorAction SilentlyContinue
$maxDuration = 0
foreach ($rule in $rules) {
if ($rule.RetentionDuration) {
$duration = [int]$rule.RetentionDuration
if ($duration -gt $maxDuration) { $maxDuration = $duration }
if ($duration -ge $script:RetentionDays -and $policy.Enabled) {
$result.compliant++
$result.isCompliant = $true
}
}
}
Write-Host " $($policy.Name): $maxDuration days" -ForegroundColor $(
if ($maxDuration -ge $script:RetentionDays) { "Green" } else { "Yellow" }
)
}
}
Write-Host "`n Total: $($result.total) | Compliant: $($result.compliant)" -ForegroundColor Cyan
if ($result.isCompliant) {
Write-Host "`n[OK] COMPLIANT" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
$policyName = "Teams Chats $script:RetentionYears Year Retention"
$policy = New-RetentionCompliancePolicy -Name $policyName `
-Comment "NL Baseline" `
-TeamsChatLocation All `
-Enabled $true
$rule = New-RetentionComplianceRule -Name "$policyName - Rule" `
-Policy $policyName `
-RetentionDuration $script:RetentionDays `
-RetentionComplianceAction Keep
Write-Host "`n[OK] Policy created" -ForegroundColor Green
exit 0
}
catch {
Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red
exit 2
}
}
try {
if ($Revert) {
Connect-IPPSSession -ShowBanner:$false
Remove-RetentionCompliancePolicy -Identity "Teams Chats $script:RetentionYears Year Retention" -Confirm:$false -ErrorAction SilentlyContinue
}
elseif ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Use: -Monitoring | -Remediation | -Revert" -ForegroundColor Yellow
}
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
if ($Revert) {
Connect-IPPSSession -ShowBanner:$false
Remove-RetentionCompliancePolicy -Identity "Teams Chats $script:RetentionYears Year Retention" -Confirm:$false -ErrorAction SilentlyContinue
}
elseif ($Monitoring) {
Invoke-Monitoring
}
elseif ($Remediation) {
Invoke-Remediation
}
else {
Write-Host "Use: -Monitoring | -Remediation | -Revert" -ForegroundColor Yellow
}
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
Risico zonder implementatie
Risico zonder implementatie
Medium: Medium - Teams chats deleted is compliance hiaten.
Management Samenvatting
Retention: Teams chats 7 years. Voldoet aan BIO 18.01. Setup: 1u.
- Implementatietijd: 2 uur
- FTE required: 0.02 FTE