powershell-scripts/Identify and Block Shared Mailbox Signin/BlockSigninForSharedAndResourceMailbox.ps1
2025-03-26 10:10:48 +05:30

277 lines
11 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<#
====================================================================================================
Name: Identify and Block Sign-in for Shared Mailboxes in Microsoft 365
Version: 1.0
Website: o365reports.com
Script Highlights:
~~~~~~~~~~~~~~~~~
1. Export sign-in status report for all the resource and shared mailboxes into a CSV file, including:
a. Shared mailboxes Check sign-in settings for shared accounts.
b. Room mailboxes Track sign-in configurations for meeting rooms.
c. Equipment mailboxes Review sign-in status for assigned equipment.
2. Blocks sign-in for all shared mailboxes upon confirmation.
3. Allows to verify sign-in configuration for specific mailbox types and blocks them.
4. The script automatically verifies and installs the Exchange Online PowerShell and Microsoft Graph Beta modules (if not installed already) upon your confirmation.
5. Allows users to modify the generated CSV report and provide it as input later to block the sign-in on respective mailboxes.
6. Provides a detailed log file after disabling sign-in for shared and resource mailboxes.
7. The script can be executed with an MFA-enabled account too.
8. The script supports Certificate-based authentication (CBA).
For detailed Script execution: https://o365reports.com/2025/03/25/identify-and-block-sign-in-to-shared-mailbox-using-powershell/
====================================================================================================
#>
param (
[string] $CertificateThumbPrint,
[string] $ClientId,
[string] $Organization,
[string] $TenantId,
[Switch] $SharedMailboxOnly,
[Switch] $RoomMailboxOnly,
[Switch] $EquipmentMailboxOnly,
[string] $CSV
)
if($CSV){
if (-not (Test-Path $CSV -PathType Leaf))
{
Write-Host "Error: The specified CSV file does not exist or is not accessible." -ForegroundColor Red
Exit
}
}
Function ConnectModules
{
$MgGraphBetaModule = Get-Module Microsoft.Graph.Beta -ListAvailable
if($MgGraphBetaModule -eq $null)
{
Write-Host "Important: Microsoft Graph Beta module is unavailable. It is mandatory to have this module installed in the system to run the script successfully."
$Confirm = Read-Host Are you sure you want to install Microsoft Graph Beta module? [Y] Yes [N] No
if($Confirm -match "[yY]")
{
Write-Host "Installing Microsoft Graph Beta module..."
try{
Install-Module Microsoft.Graph.Beta -Scope CurrentUser -AllowClobber
}
catch{
Write-Host "Error occurred : $( $_.Exception.Message )" -ForegroundColor Red
Exit
}
Write-Host "Microsoft Graph Beta module is installed in the machine successfully" -ForegroundColor Magenta
}
else
{
Write-Host "Exiting. `nNote: Microsoft Graph Beta module must be available in your system to run the script" -ForegroundColor Red
Exit
}
}
$EXOModule=Get-Module ExchangeOnlineManagement -ListAvailable
if($EXOModule.count -eq 0)
{
Write-Host "Important: Exchangeonlinemanagement module is unavailable. It is mandatory to have this module installed in the system to run the script successfully." -ForegroundColor Red
$Confirm = Read-Host Are you sure want to install module? [Y] Yes [N] No
if($Confirm -match "[yY]")
{
Write-Host Installing Exchange Online Powershell module
try
{
Install-Module -Name ExchangeOnlineManagement -Repository PSGallery -AllowClobber -Force -Scope CurrentUser
}
catch
{
Write-Host "Error occurred : $( $_.Exception.Message)" -ForegroundColor Red
Exit
}
Write-Host ExchangeOnline installed successfully -ForegroundColor Green
}
else
{
Write-Host "EXO module is required. Please Install-module ExchangeOnlineManagement."
Exit
}
}
try
{
if(($TenantId -ne "") -and ($ClientId -ne "") -and ($CertificateThumbprint -ne "") -and ($Organization -ne ""))
{
Write-Host "Connecting to ExchangeOnline."
Connect-ExchangeOnline -CertificateThumbprint $CertificateThumbPrint -AppId $ClientId -Organization $Organization -ErrorAction stop -ShowBanner:$false
Write-Host "ExchangeOnline connected successfully" -ForegroundColor Green
Write-Host "Connecting to Microsoft Graph."
Connect-MgGraph -TenantId $TenantId -ClientId $ClientId -CertificateThumbprint $CertificateThumbprint -ErrorAction stop | Out-Null
Write-Host "Microsoft Graph connected successfully" -ForegroundColor Green
}
else
{
Write-Host "Connecting to ExchangeOnline"
Connect-Exchangeonline -ErrorAction stop -ShowBanner:$false
Write-Host "ExchangeOnline connected successfully" -ForegroundColor Green
Write-Host "Connecting to Microsoft.Graph."
#Import-Module Microsoft.Graph.Authentication
Connect-MgGraph -scopes "Directory.AccessAsUser.All" -ErrorAction Stop | Out-Null
Write-Host "Microsoft Graph connected successfully" -ForegroundColor Green
}
}
catch
{
Write-Host $_.Exception.Message -ForegroundColor Red
Disconnect-ExchangeOnline -confirm:$false
Exit
}
}
Function WriteToLogFile ($message)
{
$message >> $global:logfile
}
Function CheckMailboxSigninStatus
{
param(
$ExoMailbox
)
$mailbox = Get-MgBetaUser -Userid $ExoMailbox.userprincipalname
$DisplayName = $mailbox.DisplayName
Write-Progress -Activity "`n Retrieving Signin status for the mailbox: $DisplayName" -status "Mailbox count:$global:RetrieveCount"
$global:RetrieveCount++
$UserPrincipalName = $mailbox.UserPrincipalName
$AccountEnabled = $mailbox.AccountEnabled
$RecipientTypeDetails = $ExoMailbox.RecipientTypeDetails
if($RecipientTypeDetails -ne "SharedMailbox" -and $RecipientTypeDetails -ne "RoomMailbox" -and $RecipientTypeDetails -ne "EquipmentMailbox"){
Write-Host "$userprincipalname is not a shared/room/equipment mailbox" -ForegroundColor Red
return
}
if($AccountEnabled -and !$global:flag){
$global:flag = $true
}
$ExportResult = @{'Display Name' = $DisplayName; 'User Principal Name' = $UserPrincipalName; 'Account Enabled' = $AccountEnabled; 'Recipient Type Details' = $RecipientTypeDetails }
$ExportResults = New-Object PSObject -Property $ExportResult
$ExportResults | Select-object 'Display Name', 'User Principal Name', 'Account Enabled', 'Recipient Type Details' | Export-csv -path $global:ExportCSV -NoType -Append -Force
}
Function BlockSignin
{
Import-Csv $global:ExportCSV | ForEach-Object{
if($_.'Account Enabled' -eq $true){
$Displayname = $_.'Display Name'
Write-Progress -Activity "Updating signin status for the mailbox: $DisplayName" -status "processing:$global:UpdatedCount"
$global:UpdatedCount++
$UserPrincipalName = $_.'User Principal Name'
try{
Update-MgBetaUser -UserId $UserPrincipalName -AccountEnabled:$false -ErrorAction Stop
WriteToLogFile " Successfully blocked signin for the mailbox: $UserPrincipalName"
}
catch{
WriteToLogFile " Error occured while trying to block the mailbox: $UserPrincipalName "
Write-Host "An error occurred for the mailbox: $UserPrincipalname" ": $( $_.Exception.Message )"
}
}
}
if(((Test-Path -Path $global:logfile) -eq "True")){
Write-host "The log file $global:logfile available in $global:Location" -ForegroundColor yellow
}
}
Function ConfirmationToBlock
{
Write-Host "`n`nDo you want to proceed with blocking signin enabled mailboxes? Yes[y] No[n]?"
$confirm = (Read-Host "Enter your choice").ToUpper()
if($confirm -eq 'Y')
{
Write-Host "Updating Mailbox Signin Status..."
BlockSignin
}
}
Function GettingMailbox
{
param(
$RecipientTypeDetails
)
Get-EXOMailbox -RecipientTypeDetails $RecipientTypeDetails -ResultSize unlimited | ForEach-Object {
CheckMailboxSigninStatus -ExoMailbox $_
}
}
Function OutputFileCreation
{
param(
$OutputFileName
)
$global:ExportCSV = $OutputFileName + "Mailboxes_SigninStatus_" + ((Get-Date -format "MMM-dd hh-mm-ss tt").ToString()) + ".csv"
$global:logfile = "DisabledSigninLogFile_" + ((Get-Date -format "MMM-dd hh-mm-ss tt").ToString()) + ".txt"
}
#........................................................Execution starts here..................................... .........................
#Calling Connection Function
ConnectModules
#To check whether the mailbox have accountenabled true
$global:flag =$false
#No of mailboxes retrieved count
$global:RetrieveCount = 1
#No of signin updated count
$global:UpdatedCount = 1
if($SharedMailboxOnly)
{
$FileName = "Shared"
OutputFileCreation -OutputFileName $FileName
GettingMailbox -RecipientTypeDetails SharedMailbox
}
elseif($RoomMailboxOnly)
{
$FileName = "Room"
OutputFileCreation -OutputFileName $FileName
GettingMailbox -RecipientTypeDetails RoomMailbox
}
elseif($EquipmentMailboxOnly)
{
$FileName = "Equipment"
OutputFileCreation -OutputFileName $FileName
GettingMailbox -RecipientTypeDetails EquipmentMailbox
}
elseif($CSV)
{
$FileName = "Shared_Room_Equipment"
OutputFileCreation -OutputFileName $FileName
Import-Csv $CSV | ForEach-object{
$Mailbox = Get-EXOMailbox $_.'User Principal Name'
CheckMailboxSigninStatus -ExoMailbox $Mailbox
}
}
else
{
$FileName = "SharedandResource"
OutputFileCreation -OutputFileName $FileName
GettingMailbox -RecipientTypeDetails SharedMailbox,RoomMailbox,EquipmentMailbox
}
$global:Location = Get-Location
Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green
Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~" -ForegroundColor Green `n
#Invoking outputFile
if (((Test-Path -Path $global:ExportCSV) -ne "True")) {
Write-Host "`nNo Mailboxes matches the given criteria." -ForegroundColor Cyan
}
else {
Write-Host "`nThe output file $global:ExportCSV is available in the $global:Location" -ForegroundColor Yellow
$prompt = New-Object -ComObject wscript.shell
$userInput = $prompt.popup("Do you want to open output file?", 0, "Open Output File", 4)
if ($userInput -eq 6) {
Invoke-Item "$global:ExportCSV"
}
if($global:flag){
ConfirmationToBlock
}
else{
Write-Host "Signin status has been already disabled for all the mailboxes" -ForegroundColor Cyan
}
}
Disconnect-ExchangeOnline -confirm:$false
Disconnect-Mggraph | Out-Null