Entra / Microsoft 365 · Users & guests
Check sign-ins for utility accounts
Uses Microsoft Graph sign-in logs to detect sign-ins for accounts that should not authenticate, such as break-glass, service, and utility accounts.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -Scopes AuditLog.Read.All, Mail.Send, User.Read.All -NoWelcome
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
If ([Environment]::UserInteractive) {# We're running interactively...Write-Host "Running interactively..."Connect-MgGraph -Scopes AuditLog.Read.All, Mail.Send, User.Read.All -NoWelcome} Else {# We're not, so likely in Azure AutomationWrite-Output "Running the Check Utility account script in Azure Automation..."Connect-MgGraph -Identity}# Find marked utility accounts[array]$UtilityAccounts = Get-MgUser -Filter "(onPremisesExtensionAttributes/extensionAttribute1 eq 'BG' or onPremisesExtensionAttributes/extensionAttribute1 eq 'Utility') and userType eq 'Member'" -All -PageSize 250 -ConsistencyLevel eventual -CountVariable RecordsIf ($UtilityAccounts) {Write-Host "Found $($Users.Count) utility accounts to process..." -ForegroundColor Yellow} Else {Write-Host "No utility accounts found." -ForegroundColor YellowExit}Write-Host "Processing utility accounts..." -ForegroundColor Cyan$Report = [System.Collections.Generic.List[Object]]::new()ForEach ($User in $UtilityAccounts) {Write-Host "Processing account: $($User.displayName)" -ForegroundColor CyanTry {$UserId = $User.Id[array]$SignIn = Get-MgAuditLogSignIn -Filter "userid eq '$UserId'" -Top 1 -ErrorAction Stop} Catch {Write-Host "Failed to retrieve sign-ins for user $($User.displayName): $($_.Exception.Message)" -ForegroundColor RedContinue}If ($SignIn) {Write-Host "Found sign-ins for user $($User.displayName)" -ForegroundColor RedIf ($SignIn.Status.ErrorCode -eq 0) {$SignInStatus = "Success"} Else {$SignInStatus = "Failure: $($SignIn.Status.ErrorCode)"}$ReportLine = [PSCustomObject]@{User = $User.displayNameUPN = $User.userPrincipalNameSignInTime = Get-Date $SignIn.createdDateTime -format 'dd-MMM-yyyy HH:mm:ss'Status = $SignInStatusSignInIP = $SignIn.ipAddressSignInLocation= $SignIn.location.city + ", " + $SignIn.location.countryOrRegion}$Report.Add($ReportLine)}}# Define HTML style$HtmlStyle = @"<style>body { font-family: Segoe UI, Arial, sans-serif; background: #f4f6f8; color: #222; }h1 { background: #0078d4; color: #fff; padding: 16px; border-radius: 6px 6px 0 0; margin-bottom: 0; }table { border-collapse: collapse; width: 100%; background: #fff; border-radius: 0 0 6px 6px; overflow: hidden; }th, td { padding: 10px 12px; text-align: left; }th { background: #e5eaf1; color: #222; }tr { background: #fff; color: #222; }tr:nth-child(even) { background: #f0f4fa; color: #222; }tr:hover { background: #d0e7fa; color: #222; }.caption { font-size: 14px; color: #555; margin-bottom: 12px; }</style>"@# Create the HTML content$HtmlTable = $Report | ConvertTo-HTML -Fragment -As Table$HtmlReport = @"<html><head>$HtmlStyle<title>Sign-ins Detected for Utility Accounts</title></head><body><p>Report generated: <b>$((Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss 'UTC'"))</b></p><h1>Sign-In Records Observed for Utility Accounts</h1><p><p>Please check these sign-in events to validate that the accounts are not being used incorrectly.</p>$HtmlTable</body></html>"@If ($Report) {# Create and send a message to the administrator# Change this email address to be the sender of the message$MsgFrom = 'Background.Monitoring.Service@office365itpros.com'# Build the array of a single TO recipient detailed in a hash table - change this address to be the desired recipient of the mail$ToRecipient = @{}$ToRecipient.Add("emailAddress",@{'address'="AdminsDL@office365itpros.com"})[array]$MsgTo = $ToRecipient# Define the message subject$MsgSubject = "Important: Sign-ins Detected for Utility Accounts"# Construct the message body$MsgBody = @{}$MsgBody.Add('Content', "$($HtmlReport)")$MsgBody.Add('ContentType','html')# Build the parameters to submit the message$Message = @{}$Message.Add('subject', $MsgSubject)$Message.Add('toRecipients', $MsgTo)$Message.Add('body', $MsgBody)$EmailParameters = @{}$EmailParameters.Add('message', $Message)$EmailParameters.Add('saveToSentItems', $true)$EmailParameters.Add('isDeliveryReceiptRequested', $true)# Send the messageTry {Send-MgUserMail -UserId $MsgFrom -BodyParameter $EmailParameters -ErrorAction StopWrite-Host "Email sent successfully to $($MsgTo[0].emailAddress.address)" -ForegroundColor Green} Catch {Write-Host "Failed to send email: $($_.Exception.Message)" -ForegroundColor Red}}
Attribution
Author
Office365itpros