auditing
73 TopicsPrimer: How to Use RBAC for Applications to Control App Use of the Mail.Send Permission
The temptation to use the Mail.Send application permission in scripts can lead PowerShell developers into trouble because the permission allows access to all mailboxes, including sensitive executive and financial mailboxes. Fortunately, RBAC for Applications allows tenants to control the access that apps have to mailboxes and other Exchange content. All explained here with an example script to test RBAC of Applications. https://office365itpros.com/2026/02/17/mail-send-rbac-for-applications/252Views3likes4CommentsI built a free, open-source M365 security assessment tool - looking for feedback
I work as an IT consultant, and a good chunk of my time is spent assessing Microsoft 365 environments for small and mid-sized businesses. Every engagement started the same way: connect to five different PowerShell modules, run dozens of commands across Entra ID, Exchange Online, Defender, SharePoint, and Teams, manually compare each setting against CIS benchmarks, then spend hours assembling everything into a report the client could actually read. The tools that automate this either cost thousands per year, require standing up Azure infrastructure just to run, or only cover one service area. I wanted something simpler: one command that connects, assesses, and produces a client-ready deliverable. So I built it. What M365 Assess does https://github.com/Daren9m/M365-Assess is a PowerShell-based security assessment tool that runs against a Microsoft 365 tenant and produces a comprehensive set of reports. Here is what you get from a single run: 57 automated security checks aligned to the CIS Microsoft 365 Foundations Benchmark v6.0.1, covering Entra ID, Exchange Online, Defender for Office 365, SharePoint Online, and Teams 12 compliance frameworks mapped simultaneously -- every finding is cross-referenced against NIST 800-53, NIST CSF 2.0, ISO 27001:2022, SOC 2, HIPAA, PCI DSS v4.0.1, CMMC 2.0, CISA SCuBA, and DISA STIG (plus CIS profiles for E3 L1/L2 and E5 L1/L2) 20+ CSV exports covering users, mailboxes, MFA status, admin roles, conditional access policies, mail flow rules, device compliance, and more A self-contained HTML report with an executive summary, severity badges, sortable tables, and a compliance overview dashboard -- no external dependencies, fully base64-encoded, just open it in any browser or email it directly The entire assessment is read-only. It never modifies tenant settings. Only Get-* cmdlets are used. A few things I'm proud of Real-time progress in the console. As the assessment runs, you see each check complete with live status indicators and timing. No staring at a blank terminal wondering if it hung. The HTML report is a single file. Logos, backgrounds, fonts -- everything is embedded. You can email the report as an attachment and it renders perfectly. It supports dark mode (auto-detects system preference), and all tables are sortable by clicking column headers. Compliance framework mapping. This was the feature that took the most work. The compliance overview shows coverage percentages across all 12 frameworks, with drill-down to individual controls. Each finding links back to its CIS control ID and maps to every applicable framework control. Pass/Fail detail tables. Each security check shows the CIS control reference, what was checked, what the expected value is, what the actual value is, and a clear Pass/Fail/Warning status. Findings include remediation descriptions to help prioritize fixes. Quick start If you want to try it out, it takes about 5 minutes to get running: # Install prerequisites (if you don't have them already) Install-Module Microsoft.Graph, ExchangeOnlineManagement -Scope CurrentUser Clone and run git clone https://github.com/Daren9m/M365-Assess.git cd M365-Assess .\Invoke-M365Assessment.ps1 The interactive wizard walks you through selecting assessment sections, entering your tenant ID, and choosing an authentication method (interactive browser login, certificate-based, or pre-existing connections). Results land in a timestamped folder with all CSVs and the HTML report. Requires PowerShell 7.x and runs on Windows (macOS and Linux are experimental -- I would love help testing those platforms). Cloud support M365 Assess works with: Commercial (global) tenants GCC, GCC High, and DoD environments If you work in government cloud, the tool handles the different endpoint URIs automatically. What is next This is actively maintained and I have a roadmap of improvements: More automated checks -- 140 CIS v6.0.1 controls are tracked in the registry, with 57 automated today. Expanding coverage is the top priority. Remediation commands -- PowerShell snippets and portal steps for each finding, so you can fix issues directly from the report. XLSX compliance matrix -- A spreadsheet export for audit teams who need to work in Excel. Standalone report regeneration -- Re-run the report from existing CSV data without re-assessing the tenant. I would love your feedback I have been building this for my own consulting work, but I think it could be useful to the broader community. If you try it, I would genuinely appreciate hearing: What checks should I prioritize next? Which security controls matter most in your environment? What compliance frameworks are most requested by your clients or auditors? How does the report land with non-technical stakeholders? Is the executive summary useful, or does it need work? macOS/Linux users -- does it run? What breaks? I have tested it on macOS, but not extensively. Bug reports, feature requests, and contributions are all welcome on GitHub. Repository: https://github.com/Daren9m/M365-Assess License: MIT (free for commercial and personal use) Runtime: PowerShell 7.x Thanks for reading. Happy to answer any questions in the comments.996Views2likes1CommentAudit Log Search - Document Library
Hi all, (hopefully posting in the correct area). I have a requirement to check audit logs for permission/inheritance changes at a Document Library level. I have looked to use the Security & Compliance > Search > Audit Log Search function within O365 Admin, however it only appears to audit Site level permission activities? If it's possible, can I run an audit of changes against a specific Document Library within a SharePoint site? In this instance it's actually the Site Pages document library. SharePoint Online being used under MS 365 E3 licensing.1.3KViews2likes0Commentsenable mailbox auditing for all mailbox
Hello everyone, I am trying to set up mailbox auditing for my users in office 365 however it is not working: here is the powershell script I used : https://github.com/OfficeDev/O365-InvestigationTooling/blob/master/EnableMailboxAuditing.ps1 When I am log in with my admin account it does the following: And when I am trying with my normal account it does the following: What am I doing wrong?1.3KViews1like1Commentenabled mailbox auditing for all mailbox
Hello every one, I am trying to enabled mailbox auditing for all mailbox in office 365 by running the script EnableMailboxAuditing.ps1 https://github.com/OfficeDev/O365-InvestigationTooling/blob/master/EnableMailboxAuditing.ps1 But I encountered some issue... When I log in with my administrator account it does the following: And when I try with my normal user it does the following: What am I doing wrong?1.3KViews1like1CommentUnified Audit Log- Data Source for Power Platform
Hi guys, Does anyone have any idea where the Unified Audit Log in the M365 Security & Compliance Center is pulling data from regarding Power Platform? I would imagine it's from the Power Platform audit logs, hence auditing needs to be enabled for Power Platform or am I wrong? I am failing to find an adequate answer in the official documentation.1.2KViews1like1CommentPowerShell script to export Audit log search Data based on userID filter
Office 365 Audit Log platform is helping you to monitor and control activities on your tenant. In some case, it's necessary to export some user activity to detect some problematic usage. FROM WEB ADMIN SITE It's possible to do that export from the dedicated Admin site "Security & Compliance": https://protection.office.com/?rfr=AdminCenter#/unifiedauditlog You can select certain filter options to focus on your question based on: Activity type Start & End DateTime UsersID (email or O365 login) File, folder, url or site this filterset will be used: to execute the search and export the resultset (in CSV format) to create an alert You can find a lot of details related to that Audit Log usage: https://docs.microsoft.com/en-us/office365/securitycompliance/search-the-audit-log-in-security-and-compliance#search-the-audit-log But some important restrictions need to be accepted before work with that solution: Number of lines (or Events) is limited to 50’000 max Number of characters exported to the AuditData details is restricted to the first 3’060 chars FROM POWERSHELL Based on many other articles and blogposts, I wrote a dedicated PowerShell script like a toolkit you can use to connect directly Office 365 Audit Log system and send the filters you need to get the result set in memory. Based on that results, the script will directly extract the AuditData field and convert it into a CSV file with many fields (extracted form the JSON Format) The PowerShell command used is: Search-UnifiedAuditLog - https://docs.microsoft.com/en-us/powershell/module/exchange/policy-and-compliance-audit/search-unifiedauditlog?view=exchange-ps Function Split-O365AuditLogs-FromO365 () { #Get the content to process Write-host " -----------------------------------------" -ForegroundColor Green [string]$username = "YourAdminAccount@yourtenant.onmicrosoft.com" [string]$PwdTXTPath = "C:\SECUREDPWD\ExportedPWD-$($username).txt" $secureStringPwd = ConvertTo-SecureString -string (Get-Content $PwdTXTPath) $UserCredential = New-Object System.Management.Automation.PSCredential $username, $secureStringPwd #This will prompt the user for credential # $UserCredential = Get-Credential $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-LiveID/ -Credential $UserCredential -Authentication Basic -AllowRedirection Import-PSSession $Session [DateTime]$startDate = "01/01/2019 00:00" #Format: mm/dd/yyyy hh:MM [DateTime]$endDate = "01/11/2019 23:59" #Format: mm/dd/yyyy hh:MM $SpecifiedUserIDs = "Youremailtoscan@yourtenant.com", "Youremailtoscan2@yourtenant.com" #syntax: "<value1>","<value2>",..."<valueX>". $scriptStart=(get-date) $sessionName = (get-date -Format 'u')+'o365auditlog' # Reset user audit accumulator $aggregateResults = @() $i = 0 # Loop counter Do { Write-host " >> Audit Request Details: StartDate=", $startDate, "- EndDate=", $endDate, "SpecifiedUserIDs=", $SpecifiedUserIDs $currentResults = Search-UnifiedAuditLog -StartDate $startDate -EndDate $enddate -SessionId $sessionName -SessionCommand ReturnLargeSet -ResultSize 1000 -UserIds $SpecifiedUserIDs if ($currentResults.Count -gt 0) { Write-Host (" Finished {3} search #{1}, {2} records: {0} min" -f [math]::Round((New-TimeSpan -Start $scriptStart).TotalMinutes,4), $i, $currentResults.Count, $user.UserPrincipalName ) # Accumulate the data $aggregateResults += $currentResults # No need to do another query if the # recs returned <1k - should save around 5-10 sec per user if ($currentResults.Count -lt 1000) { $currentResults = @() } else { $i++ } } } Until ($currentResults.Count -eq 0) # --- End of Session Search Loop --- # [int]$IntemIndex = 1 $data=@() foreach ($line in $aggregateResults) { Write-host " ItemIndex:", $IntemIndex, "- Creation Date:", $line.CreationDate, "- UserIds:", $line.UserIds, "- Operations:", $line.Operations Write-host " > AuditData:", $line.AuditData $datum = New-Object -TypeName PSObject $Converteddata = convertfrom-json $line.AuditData $datum | Add-Member -MemberType NoteProperty -Name Id -Value $Converteddata.Id $datum | Add-Member -MemberType NoteProperty -Name CreationTimeUTC -Value $Converteddata.CreationTime $datum | Add-Member -MemberType NoteProperty -Name CreationTime -Value $line.CreationDate $datum | Add-Member -MemberType NoteProperty -Name Operation -Value $Converteddata.Operation $datum | Add-Member -MemberType NoteProperty -Name OrganizationId -Value $Converteddata.OrganizationId $datum | Add-Member -MemberType NoteProperty -Name RecordType -Value $Converteddata.RecordType $datum | Add-Member -MemberType NoteProperty -Name ResultStatus -Value $Converteddata.ResultStatus $datum | Add-Member -MemberType NoteProperty -Name UserKey -Value $Converteddata.UserKey $datum | Add-Member -MemberType NoteProperty -Name UserType -Value $Converteddata.UserType $datum | Add-Member -MemberType NoteProperty -Name Version -Value $Converteddata.Version $datum | Add-Member -MemberType NoteProperty -Name Workload -Value $Converteddata.Workload $datum | Add-Member -MemberType NoteProperty -Name UserId -Value $Converteddata.UserId $datum | Add-Member -MemberType NoteProperty -Name ClientIPAddress -Value $Converteddata.ClientIPAddress $datum | Add-Member -MemberType NoteProperty -Name ClientInfoString -Value $Converteddata.ClientInfoString $datum | Add-Member -MemberType NoteProperty -Name ClientProcessName -Value $Converteddata.ClientProcessName $datum | Add-Member -MemberType NoteProperty -Name ClientVersion -Value $Converteddata.ClientVersion $datum | Add-Member -MemberType NoteProperty -Name ExternalAccess -Value $Converteddata.ExternalAccess $datum | Add-Member -MemberType NoteProperty -Name InternalLogonType -Value $Converteddata.InternalLogonType $datum | Add-Member -MemberType NoteProperty -Name LogonType -Value $Converteddata.LogonType $datum | Add-Member -MemberType NoteProperty -Name LogonUserSid -Value $Converteddata.LogonUserSid $datum | Add-Member -MemberType NoteProperty -Name MailboxGuid -Value $Converteddata.MailboxGuid $datum | Add-Member -MemberType NoteProperty -Name MailboxOwnerSid -Value $Converteddata.MailboxOwnerSid $datum | Add-Member -MemberType NoteProperty -Name MailboxOwnerUPN -Value $Converteddata.MailboxOwnerUPN $datum | Add-Member -MemberType NoteProperty -Name OrganizationName -Value $Converteddata.OrganizationName $datum | Add-Member -MemberType NoteProperty -Name OriginatingServer -Value $Converteddata.OriginatingServer $datum | Add-Member -MemberType NoteProperty -Name SessionId -Value $Converteddata.SessionId $data += $datum $IntemIndex += 1 } $datestring = (get-date).ToString("yyyyMMdd-hhmm") $fileName = ("C:\AuditLogs\CSVExport\" + $datestring + ".csv") Write-Host (" >>> writing to file {0}" -f $fileName) $data | Export-csv $fileName -NoTypeInformation Remove-PSSession $Session } Split-O365AuditLogs-FromO365 You can use that script as you want and adapt it with your own needs Attention: AuditData limitation stay into the PowerShell option, but it's a MS Support Bug known as detailed into that following posts, I hope that will be fixed soon: https://techcommunity.microsoft.com/t5/Office-365/Incomplete-data-from-Search-UnifiedAuditLog-cmdlet-for-AzureAD/td-p/240805 https://office365itpros.com/2018/10/22/longer-retention-office365-auditdata/ Additional links: https://angryanalyticsblog.azurewebsites.net/index.php/2018/02/16/power-bi-audit-log-analytics-solution/ https://docs.microsoft.com/en-us/office365/securitycompliance/detailed-properties-in-the-office-365-audit-log https://docs.microsoft.com/en-us/office365/securitycompliance/detailed-properties-in-the-office-365-audit-log https://docs.microsoft.com/en-us/office365/securitycompliance/search-the-audit-log https://www.youtube.com/watch?v=KUyE59E3EFY https://blogs.msdn.microsoft.com/tehnoonr/2018/01/26/retrieving-office-365-audit-data-using-powershell/ https://office365itpros.com/2018/10/22/longer-retention-office365-auditdata/ https://docs.microsoft.com/en-us/powershell/module/exchange/policy-and-compliance-audit/search-unifiedauditlog?view=exchange-ps https://www.sherweb.com/blog/activity-reports-audit-logs-office-365/ http://alexbrassington.com/2016/03/03/splitting-office-365-audit-logs/ https://www.powershellgallery.com/packages/O365_Unified_Auditlog_parser/1.1/Content/O365_Unified_Auditlog_parser.ps1 Fabrice Romelard French version: http://blogs.developpeur.org/fabrice69/archive/2019/01/28/office-365-script-powershell-pour-extraire-les-audit-log-bas-s-sur-des-filtres-fournis.aspx31KViews1like3CommentsWhat are the recommendation and procedures for flagging data as CUI and managing it?
In preparing for our CMMC Certification, as a company that is heavily uses SharePoint and Teams in the Office365 cloud environment -- what are the recommendations and procedures for flagging data as CUI and managing it?2KViews1like1Comment