Dit regelen configureert retention m365 groups via Microsoft Intune apparaat configuratie beleid of compliance policies om Windows endpoints te beveiligen volgens security best practices.
Vereisten
m365
Implementatie
Gebruik PowerShell-script retention-m365-groups.ps1 (functie Invoke-Monitoring) β Monitoren.
monitoring
Gebruik PowerShell-script retention-m365-groups.ps1 (functie Invoke-Monitoring) β Controleren.
Remediatie
Gebruik PowerShell-script retention-m365-groups.ps1 (functie Invoke-Remediation) β Herstellen.
Compliance en Auditing
Beleid documentatie
Compliance & Frameworks
CIS M365: Control 18.9.19.2 (L1) - CIS Security Benchmark aanbevelingen
BIO: 16.01 - BIO Baseline Informatiebeveiliging Overheid - 16.01 - Gebeurtenissen logging en audittrails
ISO 27001:2022: A.12.4.1 - ISO 27001:2022 - Gebeurtenissen logging en audittrails
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 M365 Groups 7 Jaar
.DESCRIPTION
Retention policy voor Microsoft 365 Groups moet configured worden met 7-jaar retention om te voldoen aan
Nederlandse wettelijke bewaarplichten, essentieel voor compliance van team collaboration en shared mailboxes.
.NOTES
Filename: retention-m365-groups.ps1
Author: Nederlandse Baseline voor Veilige Cloud
Created: 2025-10-15
Last Modified: 2025-10-17
Version: 2.0
Related JSON: content/m365/data-lifecycle-management/retention-m365-groups.json
Category: data-lifecycle-management
Workload: m365
.LINK
https://github.com/m365-tenant-best-practise
.EXAMPLE
.\retention-m365-groups.ps1 -Monitoring
Check compliance status
.EXAMPLE
.\retention-m365-groups.ps1 -Remediation
Apply configuration
#>
#Requires -Version 5.1#Requires -Modules ExchangeOnlineManagement
[CmdletBinding()]
param(
[Parameter()]
[switch]$Monitoring,
[Parameter()]
[switch]$Remediation,
[Parameter()]
[switch]$Revert,
[Parameter()]
[switch]$WhatIf
)
$ErrorActionPreference = 'Stop'
# ============================================================================
# HEADER
# ============================================================================
Write-Host "
========================================" -ForegroundColor Cyan
Write-Host "Retention Policy M365 Groups 7 Jaar" -ForegroundColor Cyan
Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan
Write-Host "========================================
" -ForegroundColor Cyan
# ============================================================================
# CONFIGURATION
# ============================================================================
$script:RetentionDays = 2555# 7 years
$script:RetentionYears = 7# ============================================================================
# FUNCTIONS
# ============================================================================
functionTest-Compliance {
[CmdletBinding()]
param()
return Invoke-Monitoring
}
function Invoke-Monitoring {
try {
Write-Host "`nMonitoring:" -ForegroundColor Yellow
Write-Host " Connecting to Security & Compliance Center..." -ForegroundColor Gray
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
Write-Host " Retrieving retention policies..." -ForegroundColor Gray
$retentionPolicies = Get-RetentionCompliancePolicy -ErrorAction Stop
$groupsPolicies = $retentionPolicies | Where-Object {
$_.ModernGroupLocation -ne $null -and $_.ModernGroupLocation.Count -gt 0
}
$result = @{
isCompliant = $false
totalPolicies = $groupsPolicies.Count
compliantPolicies = 0
policyDetails = @()
}
if ($groupsPolicies.Count -eq 0) {
Write-Host " No retention policies found for M365 Groups" -ForegroundColor Red
}
else {
Write-Host "`n Retention Policies for M365 Groups:" -ForegroundColor Cyan
foreach ($policy in $groupsPolicies) {
$rules = Get-RetentionComplianceRule -Policy $policy.Name -ErrorAction SilentlyContinue
$hasCompliantRule = $false$maxRetentionDays = 0foreach ($rule in $rules) {
if ($rule.RetentionDuration -ne $null) {
$retentionDays = [int]$rule.RetentionDuration
if ($retentionDays -gt $maxRetentionDays) { $maxRetentionDays = $retentionDays }
if ($retentionDays -ge $script:RetentionDays) { $hasCompliantRule = $true }
}
}
$isCompliant = ($hasCompliantRule -and $policy.Enabled)
if ($isCompliant) {
$result.compliantPolicies++
$result.isCompliant = $trueWrite-Host " COMPLIANT: $($policy.Name)" -ForegroundColor Green
Write-Host " Retention: $maxRetentionDays days ($([Math]::Round($maxRetentionDays/365,1)) years)" -ForegroundColor Green
}
else {
Write-Host " NON-COMPLIANT: $($policy.Name)" -ForegroundColor Yellow
if ($maxRetentionDays -gt 0) {
Write-Host " Retention: $maxRetentionDays days - Requires $script:RetentionYears years" -ForegroundColor Yellow
}
}
if ($policy.ModernGroupLocation -contains "All") {
Write-Host " Scope: All M365 Groups" -ForegroundColor Gray
}
}
}
Write-Host "`n Summary:" -ForegroundColor Cyan
Write-Host " Total: $($result.totalPolicies) | Compliant: $($result.compliantPolicies)" -ForegroundColor Gray
if ($result.isCompliant) {
Write-Host "`n COMPLIANT" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n NON-COMPLIANT" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "`n ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Write-Host "`nRemediation:" -ForegroundColor Yellow
Write-Host " Connecting to Security & Compliance Center..." -ForegroundColor Gray
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
$existingPolicies = Get-RetentionCompliancePolicy -ErrorAction Stop
$groupsPolicies = $existingPolicies | Where-Object {
$_.ModernGroupLocation -ne $null -and $_.ModernGroupLocation.Count -gt 0
}
$hasCompliantPolicy = $falseforeach ($policy in $groupsPolicies) {
$rules = Get-RetentionComplianceRule -Policy $policy.Name -ErrorAction SilentlyContinue
foreach ($rule in $rules) {
if ($rule.RetentionDuration -ge $script:RetentionDays -and $policy.Enabled) {
$hasCompliantPolicy = $truebreak
}
}
if ($hasCompliantPolicy) { break }
}
if ($hasCompliantPolicy) {
Write-Host " Policy already compliant" -ForegroundColor Green
exit 0
}
$policyName = "M365 Groups $script:RetentionYears Year Retention"
Write-Host " Creating retention policy..." -ForegroundColor Gray
$policy = New-RetentionCompliancePolicy `
-Name $policyName `
-Comment "Created by Nederlandse Baseline voor Veilige Cloud - $script:RetentionYears year retention for M365 Groups" `
-ModernGroupLocation All `
-Enabled $true `
-ErrorAction Stop
$rule = New-RetentionComplianceRule `
-Name "$policyName - Rule" `
-Policy $policyName `
-RetentionDuration $script:RetentionDays `
-RetentionComplianceAction Keep `
-ErrorAction Stop
Write-Host " Policy created successfully" -ForegroundColor Green
exit 0
}
catch {
Write-Host "`n ERROR: $_" -ForegroundColor Red
exit 2
}
}
function Invoke-Revert {
try {
Write-Host "`nRevert:" -ForegroundColor Yellow
Connect-IPPSSession -ShowBanner:$false -ErrorAction Stop
$policyName = "M365 Groups $script:RetentionYears Year Retention"
$policy = Get-RetentionCompliancePolicy -Identity $policyName -ErrorAction SilentlyContinue
if (-not $policy) {
Write-Host " Policy not found" -ForegroundColor Yellow
exit 0
}
Remove-RetentionCompliancePolicy -Identity $policyName -Confirm:$false -ErrorAction Stop
Write-Host " Policy removed" -ForegroundColor Yellow
exit 0
}
catch {
Write-Host "`n ERROR: $_" -ForegroundColor Red
exit 2
}
}
# ============================================================================
# MAIN EXECUTION
# ============================================================================
try {
if ($Revert) {
if ($WhatIf) { Write-Host "WhatIf: Would revert" -ForegroundColor Yellow }
else { Invoke-Revert }
}
elseif ($Monitoring) { Invoke-Monitoring }
elseif ($Remediation) {
if ($WhatIf) { Write-Host "WhatIf: Would apply remediation" -ForegroundColor Yellow }
else { Invoke-Remediation }
}
else {
Write-Host "Available parameters:" -ForegroundColor Yellow
Write-Host " -Monitoring : Check status" -ForegroundColor Gray
Write-Host " -Remediation : Apply config" -ForegroundColor Gray
Write-Host " -Revert : Revert changes" -ForegroundColor Gray
}
}
catch {
Write-Error "Error: $_"
throw
}
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}