diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1
index 992e41e4..317fdaa0 100644
--- a/powershell/Maester.psd1
+++ b/powershell/Maester.psd1
@@ -113,7 +113,7 @@ FunctionsToExport = 'Add-MtTestResultDetail', 'Clear-MtGraphCache', 'Connect-Mae
'Test-MtCisaAntiSpamSafeList', 'Test-MtCisaMailboxAuditing',
'Test-MtCisaSpfRestriction', 'Test-MtCisaSpfDirective', 'Test-MtCisaDkim',
'Test-MtCisaDmarcRecordExist', 'Test-MtCisaDmarcRecordReject',
- 'Test-MtCisaDmarcAggregateCisa',
+ 'Test-MtCisaDmarcAggregateCisa', 'Test-MtCisaDmarcReport',
'Test-MtConditionalAccessWhatIf',
'Test-MtConnection',
'Test-MtEidscaAF01',
diff --git a/powershell/public/CISA/exchange/Test-MtCisaDmarcReport.md b/powershell/public/CISA/exchange/Test-MtCisaDmarcReport.md
new file mode 100644
index 00000000..299ac89d
--- /dev/null
+++ b/powershell/public/CISA/exchange/Test-MtCisaDmarcReport.md
@@ -0,0 +1,20 @@
+An agency point of contact SHOULD be included for aggregate and failure reports.
+
+Rationale: Email spoofing attempts are not inherently visible to domain owners. DMARC provides a mechanism to receive reports of spoofing attempts. Including an agency point of contact gives the agency insight into attempts to spoof their domains.
+
+#### Remediation action:
+
+See MS.EXO.4.1v1 Instructions for an overview of how to publish and check a DMARC record. Ensure the record published includes:
+
+* A point of contact specific to your agency in the RUA field.
+* reports@dmarc.cyber.dhs.gov as one of the emails in the RUA field.
+* One or more agency-defined points of contact in the RUF field.
+
+#### Related links
+
+* [Exchange admin center - Accepted domains](https://admin.exchange.microsoft.com/#/accepteddomains)
+* [CISA 4 Domain-Based Message Authentication, Reporting, and Conformance (DMARC) - MS.EXO.4.4v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo44v1)
+* [CISA ScubaGear Rego Reference](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/Rego/EXOConfig.rego#L252)
+
+
+%TestResult%
\ No newline at end of file
diff --git a/powershell/public/CISA/exchange/Test-MtCisaDmarcReport.ps1 b/powershell/public/CISA/exchange/Test-MtCisaDmarcReport.ps1
new file mode 100644
index 00000000..77daa49e
--- /dev/null
+++ b/powershell/public/CISA/exchange/Test-MtCisaDmarcReport.ps1
@@ -0,0 +1,115 @@
+<#
+.SYNOPSIS
+ Checks state of DMARC records for all exo domains
+
+.DESCRIPTION
+
+ An agency point of contact SHOULD be included for aggregate and failure reports.
+
+.EXAMPLE
+ Test-MtCisaDmarcReport
+
+ Returns true if DMARC record inlcudes report targets within same domain
+#>
+
+Function Test-MtCisaDmarcReport {
+ [CmdletBinding()]
+ [OutputType([bool])]
+ param()
+
+ if(!(Test-MtConnection ExchangeOnline)){
+ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange
+ return $null
+ }
+
+ $acceptedDomains = Get-AcceptedDomain
+ <# Parked domains should have DMARC with reject policy
+ $sendingDomains = $acceptedDomains | Where-Object {`
+ -not $_.SendingFromDomainDisabled
+ }
+ #>
+ $expandedDomains = @()
+ foreach($domain in $acceptedDomains){
+ #This regex does NOT capture for third level domain scenarios
+ #e.g., example.co.uk; example.ny.us;
+ $matchDomain = "(?:^|\.)(?'second'\w+.\w+$)"
+ $dmarcMatch = $domain.domainname -match $matchDomain
+ if($dmarcMatch){
+ $expandedDomains += $Matches.second
+ if($domain.domainname -ne $Matches.second){
+ $expandedDomains += $domain.domainname
+ }
+ }else{
+ $expandedDomains += $domain.domainname
+ }
+ }
+
+ $dmarcRecords = @()
+ foreach($domain in $expandedDomains){
+ $dmarcRecord = Get-MailAuthenticationRecord -DomainName $domainName -Records DMARC
+ $dmarcRecord | Add-Member -MemberType NoteProperty -Name "pass" -Value "Failed"
+ $dmarcRecord | Add-Member -MemberType NoteProperty -Name "reason" -Value ""
+
+ $checkType = $dmarcRecord.dmarcRecord.GetType().Name -eq "DMARCRecord"
+ $hostsAggregate = $dmarcRecord.dmarcRecord.reportAggregate.mailAddress.Host
+ $hostsForensic = $dmarcRecord.dmarcRecord.reportForensic.mailAddress.Host
+
+ if($checkType -and $domain -in $hostsAggregate -and $domain -in $hostsForensic){
+ $dmarcRecord.pass = "Passed"
+ }elseif($checkType){
+ $dmarcRecord.reason = "No target in domain"
+ }else{
+ $dmarcRecord.reason = $dmarcRecord.dmarcRecord
+ }
+
+ $dmarcRecords += $dmarcRecord
+ }
+
+ if("Failed" -in $dmarcRecords.pass){
+ $testResult = $false
+ }else{
+ $testResult = $true
+ }
+
+ if($testResult){
+ $testResultMarkdown = "Well done. Your tenant's domains have in domain report targets. Review report targets.`n`n%TestResult%"
+ }else{
+ $testResultMarkdown = "Your tenant's second level domains do not have in domain report targets.`n`n%TestResult%"
+ }
+
+ $passResult = "✅ Pass"
+ $failResult = "❌ Fail"
+ $result = "| Domain | Result | Reason | Targets |`n"
+ $result += "| --- | --- | --- | --- |`n"
+ foreach ($item in $dmarcRecords | Sort-Object -Property domain) {
+ switch($item.pass){
+ "Passed" {$itemResult = $passResult}
+ "Failed" {$itemResult = $failResult}
+ }
+ $aggregates = $item.dmarcRecord.reportForensic.mailAddress
+ $aggregatesCount = ($aggregates|Measure-Object).Count
+ if($aggregatesCount -ge 3){
+ $aggregates = "$($aggregates[0])
$($aggregates[1])
"
+ $aggregates += "...$aggregatesCount targets"
+ }elseif(aggregatesCount -gt 1){
+ $aggregates = $aggregates -join "
"
+ }
+ $forensics = $item.dmarcRecord.reportForensic.mailAddress
+ $forensicsCount = ($forensics|Measure-Object).Count
+ if($forensicsCount -ge 3){
+ $forensics = "$($forensics[0])
$($forensics[1])
"
+ $forensics += "...$forensicsCount targets"
+ }elseif(aggregatesCount -gt 1){
+ $forensics = $forensics -join "
"
+ }
+
+ $result += "| $($item.domain) | $($itemResult) | $($item.reason) | Aggregate Reports: $($aggregates) |`n"
+ $result += "| $($item.domain) | $($itemResult) | $($item.reason) | Forensic Reports: $($forensics) |`n"
+ }
+
+ $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result
+
+ Add-MtTestResultDetail -Result $testResultMarkdown
+
+ return $testResult
+}
\ No newline at end of file
diff --git a/tests/CISA/exchange/Test-MtCisaDmarcReport.ps1 b/tests/CISA/exchange/Test-MtCisaDmarcReport.ps1
new file mode 100644
index 00000000..39291d55
--- /dev/null
+++ b/tests/CISA/exchange/Test-MtCisaDmarcReport.ps1
@@ -0,0 +1,9 @@
+Describe "CISA SCuBA" -Tag "MS.EXO", "MS.EXO.4.4", "CISA", "Security", "All" {
+ It "MS.EXO.4.4: An agency point of contact SHOULD be included for aggregate and failure reports." {
+ $cisaDmarcReport = Test-MtCisaDmarcReport
+
+ if ($null -ne $cisaDmarcReport) {
+ $cisaDmarcReport | Should -Be $true -Because "DMARC report targets should exist."
+ }
+ }
+}
\ No newline at end of file
diff --git a/website/docs/tests/cisa/exo.md b/website/docs/tests/cisa/exo.md
index 2907c5b4..2b439d6e 100644
--- a/website/docs/tests/cisa/exo.md
+++ b/website/docs/tests/cisa/exo.md
@@ -26,6 +26,7 @@ See the [Installation guide](/docs/installation#optional-modules-and-permissions
| Test-MtCisaDmarcRecordExist | [MS.EXO.4.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo41v1) |
| Test-MtCisaDmarcRecordReject | [MS.EXO.4.2v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo42v1) |
| Test-MtCisaDmarcAggregateCisa | [MS.EXO.4.3v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo43v1) |
+| Test-MtCisaDmarcReport | [MS.EXO.4.4v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo44v1) |
| Test-MtCisaSmtpAuthentication | [MS.EXO.5.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo51v1) |
| Test-MtCisaContactSharing | [MS.EXO.6.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo61v1) |
| Test-MtCisaCalendarSharing | [MS.EXO.6.2v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/exo.md#msexo62v1) |