Start >
M365 >
Identity Governance >
Shared Mailbox Sign-in Blocked
L1
BIO 09.02
ISO A.9.2.1
CIS 1.3.5
Shared Mailbox Sign-in Blocked
π
2025-10-29
β’
β±οΈ 5 minuten lezen
β’
π΄ Must-Have
π₯ Download
π Bookmark
π€ Share
πΌ Management Samenvatting
Shared mailboxes zou moeten NOT Sta toe direct sign-in - access via delegation only.
Implementatie
3u (tech: 2u)
Van toepassing op:
β M365
β Exchange
Shared mailbox direct sign-in risks: shared password (multiple users know password), no individual accountability, bypasses MFA (gedeeld accounts often MFA-exempt), Diefstal van inloggegevens. Access via delegation is individual authentication, audittrail.
PowerShell Modules Vereist
Primary API: Exchange Online PowerShell
Connection: Connect-ExchangeOnline
Required Modules: ExchangeOnlineManagement
Implementatie
Blokkeer sign-in voor shared mailbox accounts. Users access via delegation (Verzend As, volledige toegangsmachtigingen). Shared mailbox password unknown/random.
For each shared mailbox: Set-Mailbox -Identity shared@company.com -AccountDisabled $true
Verifieer users access via delegation (Full Access permission)
Monitor: alert op shared mailbox sign-ins (zou moeten zijn none)
Vereisten
Exchange Online
Shared mailboxes inventory
Implementatie
For each shared mailbox: Set-Mailbox -Identity shared@company.com -AccountDisabled $true
Verifieer users access via delegation (Full Access permission)
Monitor: alert op shared mailbox sign-ins (zou moeten zijn none)
Compliance en Auditing
CIS M365 - control 1.3.5
BIO 09.02
ISO 27001 A.9.2.1
Monitoring
Gebruik PowerShell-script shared-mailbox-signin-blocked.ps1 (functie Invoke-Monitoring) β Controleren.
Gebruik PowerShell-script shared-mailbox-signin-blocked.ps1 (functie Invoke-Remediation) β Herstellen.
Compliance & Frameworks
CIS M365: Control 1.3.5 (L1) - Blokkeer shared mailbox sign-in
BIO: 09.02 - Individual accountability
ISO 27001:2022: A.9.2.1 - User registration
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).
<
.SYNOPSIS
Shared Mailbox Sign-in Blocked
.DESCRIPTION
Ensures shared mailboxes cannot be used for direct sign-in (security risk)
.NOTES
NL Baseline v2.0
[CmdletBinding()]
param ([switch ]$Monitoring , [switch ]$Remediation ,
[switch ]$Revert ,
[switch ]$WhatIf )
$ErrorActionPreference = 'Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Shared Mailbox Sign-in Protection" -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
}
Write-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <
.SYNOPSIS
Shared Mailbox Sign-in Blocked
.DESCRIPTION
Ensures shared mailboxes cannot be used for direct sign-in (security risk)
.NOTES
NL Baseline v2.0
[CmdletBinding()]
param ([switch ]$Monitoring , [switch ]$Remediation ,
[switch ]$Revert ,
[switch ]$WhatIf )
$ErrorActionPreference ='Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Shared Mailbox Sign-in Protection" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$result = @{
total = $sharedMailboxes .Count
signinBlocked = 0
signinAllowed = 0
allowedMailboxes = @()
}
Write-Host " Checking $($result .total) shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
$user = Get-MgUser -UserId $mb .UserPrincipalName -Property "AccountEnabled" -ErrorAction SilentlyContinue
if ($user .AccountEnabled -eq $false ) {
$result .signinBlocked++
}
else {
$result .signinAllowed++
$result .allowedMailboxes += $mb .UserPrincipalName
}
}
Write-Host "`n Summary:" -ForegroundColor Cyan
Write-Host " Total Shared Mailboxes: $($result .total)" -ForegroundColor White
Write-Host " Sign-in Blocked: $($result .signinBlocked)" -ForegroundColor Green
Write-Host " Sign-in Allowed: $($result .signinAllowed)" -ForegroundColor $(
if ($result .signinAllowed -eq 0 ){'Green'}else {'Red'}
)
if ($result .signinAllowed -gt 0 ) {
Write-Host "`n β οΈ Mailboxes with sign-in ALLOWED:" -ForegroundColor Red
$result .allowedMailboxes | Select-Object -First 20 | ForEach-Object {
Write-Host " β’ $_ " -ForegroundColor Gray
}
if ($result .allowedMailboxes.Count -gt 20 ) {
Write-Host " ... and $($result .allowedMailboxes.Count - 20 ) more" -ForegroundColor Gray
}
}
Write-Host "`n Security Risk:" -ForegroundColor Cyan
Write-Host " Shared mailboxes with sign-in can be compromised" -ForegroundColor Gray
Write-Host " Users should access via delegation only" -ForegroundColor Gray
if ($result .signinAllowed -eq 0 ) {
Write-Host "`n[OK] COMPLIANT - All shared mailboxes protected" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT - $($result .signinAllowed) mailboxes at risk!" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "ERROR: $_ " -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.ReadWrite.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$count = 0
Write-Host " Blocking sign-in for all shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
Update-MgUser -UserId $mb .UserPrincipalName -AccountEnabled:$false -ErrorAction Stop
$count ++
if ($count % 50 -eq 0 ) {
Write-Host " Processed $count /$($sharedMailboxes .Count)..." -ForegroundColor Gray
}
}
Write-Host "`n[OK] Blocked sign-in for $count shared mailboxes" -ForegroundColor Green
Write-Host "Users can still access via delegation" -ForegroundColor Cyan
exit 0
}
catch {
Write-Host "ERROR: $_ " -ForegroundColor Red
exit 2
}
}
try {
if ($Monitoring ) { Invoke-Monitoring }
elseif ($Remediation ) { Invoke-Remediation }
else { Write-Host "Use: -Monitoring | -Remediation" -ForegroundColor Yellow }
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$result = @{
total = $sharedMailboxes .Count
signinBlocked = 0
signinAllowed = 0
allowedMailboxes = @()
}
Write-Host " Checking $($result .total) shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
$user = Get-MgUser -UserId $mb .UserPrincipalName -Property "AccountEnabled" -ErrorAction SilentlyContinue
if ($user .AccountEnabled -eq $false ) {
$result .signinBlocked++
}
else {
$result .signinAllowed++
$result .allowedMailboxes += $mb .UserPrincipalName
}
}
Write-Host "`n Summary:" -ForegroundColor Cyan
Write-Host " Total Shared Mailboxes: $($result .total)" -ForegroundColor White
Write-Host " Sign-in Blocked: $($result .signinBlocked)" -ForegroundColor Green
Write-Host " Sign-in Allowed: $($result .signinAllowed)" -ForegroundColor $(
if ($result .signinAllowed -eq 0 ) { 'Green' }else { 'Red' }
)
if ($result .signinAllowed -gt 0 ) {
Write-Host "`n β οΈ Mailboxes with sign-in ALLOWED:" -ForegroundColor Red
$result .allowedMailboxes | Select-Object -First 20 | ForEach-Object {
Write-Host " β’ $_ " -ForegroundColor Gray
}
if ($result .allowedMailboxes.Count -gt 20 ) {
Write-Host " ... and $($result .allowedMailboxes.Count - 20 ) more" -ForegroundColor Gray
}
}
Write-Host "`n Security Risk:" -ForegroundColor Cyan
Write-Host " Shared mailboxes with sign-in can be compromised" -ForegroundColor Gray
Write-Host " Users should access via delegation only" -ForegroundColor Gray
if ($result .signinAllowed -eq 0 ) {
Write-Host "`n[OK] COMPLIANT - All shared mailboxes protected" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT - $($result .signinAllowed) mailboxes at risk!" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "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
}
Write-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <
.SYNOPSIS
Shared Mailbox Sign-in Blocked
.DESCRIPTION
Ensures shared mailboxes cannot be used for direct sign-in (security risk)
.NOTES
NL Baseline v2.0
[CmdletBinding()]
param ([switch ]$Monitoring , [switch ]$Remediation ,
[switch ]$Revert ,
[switch ]$WhatIf )
$ErrorActionPreference ='Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Shared Mailbox Sign-in Protection" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$result = @{
total = $sharedMailboxes .Count
signinBlocked = 0
signinAllowed = 0
allowedMailboxes = @()
}
Write-Host " Checking $($result .total) shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
$user = Get-MgUser -UserId $mb .UserPrincipalName -Property "AccountEnabled" -ErrorAction SilentlyContinue
if ($user .AccountEnabled -eq $false ) {
$result .signinBlocked++
}
else {
$result .signinAllowed++
$result .allowedMailboxes += $mb .UserPrincipalName
}
}
Write-Host "`n Summary:" -ForegroundColor Cyan
Write-Host " Total Shared Mailboxes: $($result .total)" -ForegroundColor White
Write-Host " Sign-in Blocked: $($result .signinBlocked)" -ForegroundColor Green
Write-Host " Sign-in Allowed: $($result .signinAllowed)" -ForegroundColor $(
if ($result .signinAllowed -eq 0 ){'Green'}else {'Red'}
)
if ($result .signinAllowed -gt 0 ) {
Write-Host "`n β οΈ Mailboxes with sign-in ALLOWED:" -ForegroundColor Red
$result .allowedMailboxes | Select-Object -First 20 | ForEach-Object {
Write-Host " β’ $_ " -ForegroundColor Gray
}
if ($result .allowedMailboxes.Count -gt 20 ) {
Write-Host " ... and $($result .allowedMailboxes.Count - 20 ) more" -ForegroundColor Gray
}
}
Write-Host "`n Security Risk:" -ForegroundColor Cyan
Write-Host " Shared mailboxes with sign-in can be compromised" -ForegroundColor Gray
Write-Host " Users should access via delegation only" -ForegroundColor Gray
if ($result .signinAllowed -eq 0 ) {
Write-Host "`n[OK] COMPLIANT - All shared mailboxes protected" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT - $($result .signinAllowed) mailboxes at risk!" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "ERROR: $_ " -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.ReadWrite.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$count = 0
Write-Host " Blocking sign-in for all shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
Update-MgUser -UserId $mb .UserPrincipalName -AccountEnabled:$false -ErrorAction Stop
$count ++
if ($count % 50 -eq 0 ) {
Write-Host " Processed $count /$($sharedMailboxes .Count)..." -ForegroundColor Gray
}
}
Write-Host "`n[OK] Blocked sign-in for $count shared mailboxes" -ForegroundColor Green
Write-Host "Users can still access via delegation" -ForegroundColor Cyan
exit 0
}
catch {
Write-Host "ERROR: $_ " -ForegroundColor Red
exit 2
}
}
try {
if ($Monitoring ) { Invoke-Monitoring }
elseif ($Remediation ) { Invoke-Remediation }
else { Write-Host "Use: -Monitoring | -Remediation" -ForegroundColor Yellow }
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.ReadWrite.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$count = 0
Write-Host " Blocking sign-in for all shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
Update-MgUser -UserId $mb .UserPrincipalName -AccountEnabled:$false -ErrorAction Stop
$count ++
if ($count % 50 -eq 0 ) {
Write-Host " Processed $count /$($sharedMailboxes .Count)..." -ForegroundColor Gray
}
}
Write-Host "`n[OK] Blocked sign-in for $count shared mailboxes" -ForegroundColor Green
Write-Host "Users can still access via delegation" -ForegroundColor Cyan
exit 0
}
catch {
Write-Host "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
}
Write-Host " Configuration reverted" -ForegroundColor Green
Write-Host "`nRevert completed" -ForegroundColor Green
}
catch {
Write-Error "Error during revert: <
.SYNOPSIS
Shared Mailbox Sign-in Blocked
.DESCRIPTION
Ensures shared mailboxes cannot be used for direct sign-in (security risk)
.NOTES
NL Baseline v2.0
[CmdletBinding()]
param ([switch ]$Monitoring , [switch ]$Remediation ,
[switch ]$Revert ,
[switch ]$WhatIf )
$ErrorActionPreference ='Stop'
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Shared Mailbox Sign-in Protection" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
function Invoke-Monitoring {
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.Read.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$result = @{
total = $sharedMailboxes .Count
signinBlocked = 0
signinAllowed = 0
allowedMailboxes = @()
}
Write-Host " Checking $($result .total) shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
$user = Get-MgUser -UserId $mb .UserPrincipalName -Property "AccountEnabled" -ErrorAction SilentlyContinue
if ($user .AccountEnabled -eq $false ) {
$result .signinBlocked++
}
else {
$result .signinAllowed++
$result .allowedMailboxes += $mb .UserPrincipalName
}
}
Write-Host "`n Summary:" -ForegroundColor Cyan
Write-Host " Total Shared Mailboxes: $($result .total)" -ForegroundColor White
Write-Host " Sign-in Blocked: $($result .signinBlocked)" -ForegroundColor Green
Write-Host " Sign-in Allowed: $($result .signinAllowed)" -ForegroundColor $(
if ($result .signinAllowed -eq 0 ){'Green'}else {'Red'}
)
if ($result .signinAllowed -gt 0 ) {
Write-Host "`n β οΈ Mailboxes with sign-in ALLOWED:" -ForegroundColor Red
$result .allowedMailboxes | Select-Object -First 20 | ForEach-Object {
Write-Host " β’ $_ " -ForegroundColor Gray
}
if ($result .allowedMailboxes.Count -gt 20 ) {
Write-Host " ... and $($result .allowedMailboxes.Count - 20 ) more" -ForegroundColor Gray
}
}
Write-Host "`n Security Risk:" -ForegroundColor Cyan
Write-Host " Shared mailboxes with sign-in can be compromised" -ForegroundColor Gray
Write-Host " Users should access via delegation only" -ForegroundColor Gray
if ($result .signinAllowed -eq 0 ) {
Write-Host "`n[OK] COMPLIANT - All shared mailboxes protected" -ForegroundColor Green
exit 0
}
else {
Write-Host "`n[FAIL] NON-COMPLIANT - $($result .signinAllowed) mailboxes at risk!" -ForegroundColor Red
exit 1
}
}
catch {
Write-Host "ERROR: $_ " -ForegroundColor Red
exit 2
}
}
function Invoke-Remediation {
try {
Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop
Connect-MgGraph -Scopes "User.ReadWrite.All" -ErrorAction Stop -NoWelcome
$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize Unlimited
$count = 0
Write-Host " Blocking sign-in for all shared mailboxes..." -ForegroundColor Cyan
foreach ($mb in $sharedMailboxes ) {
Update-MgUser -UserId $mb .UserPrincipalName -AccountEnabled:$false -ErrorAction Stop
$count ++
if ($count % 50 -eq 0 ) {
Write-Host " Processed $count /$($sharedMailboxes .Count)..." -ForegroundColor Gray
}
}
Write-Host "`n[OK] Blocked sign-in for $count shared mailboxes" -ForegroundColor Green
Write-Host "Users can still access via delegation" -ForegroundColor Cyan
exit 0
}
catch {
Write-Host "ERROR: $_ " -ForegroundColor Red
exit 2
}
}
try {
if ($Monitoring ) { Invoke-Monitoring }
elseif ($Remediation ) { Invoke-Remediation }
else { Write-Host "Use: -Monitoring | -Remediation" -ForegroundColor Yellow }
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
"
throw
}
}
try {
if ($Monitoring ) { Invoke-Monitoring }
elseif ($Remediation ) { Invoke-Remediation }
else { Write-Host "Use: -Monitoring | -Remediation" -ForegroundColor Yellow }
}
catch { throw }
finally {
Write-Host "`n========================================`n" -ForegroundColor Cyan
}
Risico zonder implementatie
Risico zonder implementatie
High: High - Shared mailbox passwords is shared credentials, no accountability, MFA bypass.
Management Samenvatting
Blokkeer shared mailbox sign-in. Access via delegation only. Voldoet aan CIS 1.3.5 L1. Setup: 2u.
Implementatietijd: 3 uur
FTE required: 0.03 FTE