diff --git a/Identify and Block Shared Mailbox Signin/BlockSigninForSharedAndResourceMailbox.ps1 b/Identify and Block Shared Mailbox Signin/BlockSigninForSharedAndResourceMailbox.ps1 new file mode 100644 index 0000000..c211c4f --- /dev/null +++ b/Identify and Block Shared Mailbox Signin/BlockSigninForSharedAndResourceMailbox.ps1 @@ -0,0 +1,276 @@ +<# +==================================================================================================== +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 +