From b20a30501bb5abe59a540bb5da7bdfe943eaf593 Mon Sep 17 00:00:00 2001 From: Jan Bakker <38911727+BakkerJan@users.noreply.github.com> Date: Tue, 21 Jul 2026 09:43:01 +0200 Subject: [PATCH 1/3] Add MT.1185: Block legacy MSOnline (MSOL) PowerShell module The blockMsolPowerShell setting on the tenant's authorization policy blocks authentication requests from the retired MSOnline PowerShell module. It isn't enabled by default for every tenant, so this check verifies the current state via Graph rather than assuming it. --- powershell/Maester.psd1 | 3 +- .../Test-MtEntraMsolPowerShellBlocked.md | 30 +++++++++++ .../Test-MtEntraMsolPowerShellBlocked.ps1 | 54 +++++++++++++++++++ ...est-MtEntraMsolPowerShellBlocked.Tests.ps1 | 6 +++ tests/maester-config.json | 5 ++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md create mode 100644 powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.ps1 create mode 100644 tests/Maester/Entra/Test-MtEntraMsolPowerShellBlocked.Tests.ps1 diff --git a/powershell/Maester.psd1 b/powershell/Maester.psd1 index a8c73d300..3bedbe72d 100644 --- a/powershell/Maester.psd1 +++ b/powershell/Maester.psd1 @@ -262,7 +262,8 @@ 'Test-MtEntitlementManagementOrphanedResources', 'Test-MtEntitlementManagementValidApprovers', 'Test-MtEntitlementManagementValidResourceRoles', 'Test-MtEntraDeviceJoinRestricted', 'Test-MtEntraIDConnectSsso', 'Test-MtEntraIDConnectSyncOnPremisesObjectIdentifierUpdatesBlocked', - 'Test-MtEntraIDConnectSyncSoftHardMatching', 'Test-MtKrbtgtAzureADNotSynced', 'Test-MtExoDelicensingResiliency', + 'Test-MtEntraIDConnectSyncSoftHardMatching', 'Test-MtEntraMsolPowerShellBlocked', + 'Test-MtKrbtgtAzureADNotSynced', 'Test-MtExoDelicensingResiliency', 'Test-MtExoMailTip', 'Test-MtExoModernAuth', 'Test-MtExoMoeraMailActivity', 'Test-MtExoOutlookAddin', 'Test-MtExoRejectDirectSend', 'Test-MtExoSetScl', 'Test-MtFeatureUpdatePolicy', 'Test-MtGroupCreationRestricted', 'Test-MtHighRiskAppPermissions', 'Test-MtIntuneAppControl', 'Test-MtIntuneASRRules', 'Test-MtIntuneDiagnosticSettings', diff --git a/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md new file mode 100644 index 000000000..38a036e65 --- /dev/null +++ b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md @@ -0,0 +1,30 @@ +## Description + +Checks if the legacy MSOnline (MSOL) PowerShell module is blocked from authenticating to the tenant. + +## Why This Matters + +The MSOnline (MSOL) and Azure AD PowerShell modules were retired by Microsoft and no longer receive security updates. Because they predate modern authentication controls, requests made through them can be a weaker, less-monitored path into a tenant's identity administration than the current Microsoft Graph PowerShell SDK. + +The `blockMsolPowerShell` setting on the tenant's authorization policy lets an admin explicitly block authentication requests from the legacy MSOnline PowerShell module's service principal. This isn't enabled by default for every tenant, so it needs to be checked explicitly rather than assumed to already be in place — leaving it unblocked keeps an unsupported and unmonitored administrative access path open. + +#### Remediation action: + +1. Connect to Graph using **Connect-MgGraph -Scopes "Policy.ReadWrite.Authorization"**. +2. Run the following PowerShell command to review the current value: +```powershell +Get-MgPolicyAuthorizationPolicy | Select-Object BlockMsolPowerShell +``` +3. If `BlockMsolPowerShell` is `$false`, block the legacy MSOnline PowerShell module: +```powershell +$authPolicy = Get-MgPolicyAuthorizationPolicy +Update-MgPolicyAuthorizationPolicy -AuthorizationPolicyId $authPolicy.Id -BlockMsolPowerShell:$true +``` + +#### Related links + +* [Authorization policy in Entra ID | Microsoft Learn](https://learn.microsoft.com/en-us/graph/api/resources/authorizationpolicy) +* [Update-MgPolicyAuthorizationPolicy | Microsoft Learn - Graph PowerShell v1.0](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/update-mgpolicyauthorizationpolicy) + + +%TestResult% diff --git a/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.ps1 b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.ps1 new file mode 100644 index 000000000..a91972d01 --- /dev/null +++ b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.ps1 @@ -0,0 +1,54 @@ +function Test-MtEntraMsolPowerShellBlocked { + <# + .SYNOPSIS + Checks if the legacy MSOnline (MSOL) PowerShell module is blocked from authenticating to the tenant + + .DESCRIPTION + The MSOnline (MSOL) and Azure AD PowerShell modules were retired by Microsoft and no longer receive + security updates. The blockMsolPowerShell setting on the tenant's authorization policy lets an admin + explicitly block authentication requests from the legacy MSOnline PowerShell module's service + principal, closing an unsupported and unmonitored administrative access path. + + This setting isn't enabled by default for every tenant, so it needs to be checked explicitly rather + than assumed to already be in place. + + .EXAMPLE + Test-MtEntraMsolPowerShellBlocked + + Returns true if the legacy MSOnline (MSOL) PowerShell module is blocked from authenticating to the tenant + + .LINK + https://maester.dev/docs/commands/Test-MtEntraMsolPowerShellBlocked + #> + [CmdletBinding()] + [OutputType([bool])] + param() + + if (-not (Test-MtConnection Graph)) { + Add-MtTestResultDetail -SkippedBecause NotConnectedGraph + return $null + } + + Write-Verbose "Checking if the legacy MSOnline (MSOL) PowerShell module is blocked..." + try { + $authorizationPolicy = Invoke-MtGraphRequest -RelativeUri "policies/authorizationPolicy" -Select "blockMsolPowerShell" -ErrorAction Stop + + $msolPowerShellBlocked = $authorizationPolicy.blockMsolPowerShell -eq $true + + if ($msolPowerShellBlocked) { + $testResult = "Well done. The legacy MSOnline (MSOL) PowerShell module is blocked from authenticating to this tenant." + } else { + $testResult = "The legacy MSOnline (MSOL) PowerShell module is **not** blocked for this tenant.`n`n" ` + + "The MSOnline module was retired by Microsoft and no longer receives security updates, so leaving it unblocked keeps an unsupported and unmonitored administrative access path open." + } + Add-MtTestResultDetail -Result $testResult + return $msolPowerShellBlocked + } catch { + if ($_.Exception.Response -and $_.Exception.Response.StatusCode -eq 403) { + Add-MtTestResultDetail -SkippedBecause NotAuthorized + } else { + Add-MtTestResultDetail -SkippedBecause Error -SkippedError $_ + } + return $null + } +} diff --git a/tests/Maester/Entra/Test-MtEntraMsolPowerShellBlocked.Tests.ps1 b/tests/Maester/Entra/Test-MtEntraMsolPowerShellBlocked.Tests.ps1 new file mode 100644 index 000000000..e651ac618 --- /dev/null +++ b/tests/Maester/Entra/Test-MtEntraMsolPowerShellBlocked.Tests.ps1 @@ -0,0 +1,6 @@ +Describe "Maester/Entra" -Tag "Maester", "Entra" { + It "MT.1185: Block legacy MSOnline (MSOL) PowerShell module. See https://maester.dev/docs/tests/MT.1185" -Tag "MT.1185" { + $result = Test-MtEntraMsolPowerShellBlocked + $result | Should -Be $true -Because "the legacy MSOnline (MSOL) PowerShell module should be blocked from authenticating to the tenant." + } +} diff --git a/tests/maester-config.json b/tests/maester-config.json index 390cd83aa..0599fadcc 100644 --- a/tests/maester-config.json +++ b/tests/maester-config.json @@ -1538,6 +1538,11 @@ "Severity": "Medium", "Title": "Conditional Access policy without any target resources configured" }, + { + "Id": "MT.1185", + "Severity": "High", + "Title": "Block legacy MSOnline (MSOL) PowerShell module" + }, { "Id": "MT.1178", "Severity": "High", From d699dd206995c69c24bc60b93ab8badad400fd1e Mon Sep 17 00:00:00 2001 From: Jan Bakker <38911727+BakkerJan@users.noreply.github.com> Date: Tue, 21 Jul 2026 09:47:33 +0200 Subject: [PATCH 2/3] Fix markdown heading level increment per CodeRabbit review --- .../public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md index 38a036e65..8f464d76a 100644 --- a/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md +++ b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md @@ -8,7 +8,7 @@ The MSOnline (MSOL) and Azure AD PowerShell modules were retired by Microsoft an The `blockMsolPowerShell` setting on the tenant's authorization policy lets an admin explicitly block authentication requests from the legacy MSOnline PowerShell module's service principal. This isn't enabled by default for every tenant, so it needs to be checked explicitly rather than assumed to already be in place — leaving it unblocked keeps an unsupported and unmonitored administrative access path open. -#### Remediation action: +### Remediation action: 1. Connect to Graph using **Connect-MgGraph -Scopes "Policy.ReadWrite.Authorization"**. 2. Run the following PowerShell command to review the current value: @@ -21,7 +21,7 @@ $authPolicy = Get-MgPolicyAuthorizationPolicy Update-MgPolicyAuthorizationPolicy -AuthorizationPolicyId $authPolicy.Id -BlockMsolPowerShell:$true ``` -#### Related links +### Related links * [Authorization policy in Entra ID | Microsoft Learn](https://learn.microsoft.com/en-us/graph/api/resources/authorizationpolicy) * [Update-MgPolicyAuthorizationPolicy | Microsoft Learn - Graph PowerShell v1.0](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/update-mgpolicyauthorizationpolicy) From 8accc9479ada7099eacee8d3f0457ae4b3d28597 Mon Sep 17 00:00:00 2001 From: Merill Fernando Date: Wed, 22 Jul 2026 19:55:43 +1000 Subject: [PATCH 3/3] docs: fix MT.1185 remediation command --- .../maester/entra/Test-MtEntraMsolPowerShellBlocked.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md index 8f464d76a..0aafd00c9 100644 --- a/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md +++ b/powershell/public/maester/entra/Test-MtEntraMsolPowerShellBlocked.md @@ -17,8 +17,12 @@ Get-MgPolicyAuthorizationPolicy | Select-Object BlockMsolPowerShell ``` 3. If `BlockMsolPowerShell` is `$false`, block the legacy MSOnline PowerShell module: ```powershell -$authPolicy = Get-MgPolicyAuthorizationPolicy -Update-MgPolicyAuthorizationPolicy -AuthorizationPolicyId $authPolicy.Id -BlockMsolPowerShell:$true +# This example uses the cmdlet syntax published in the Microsoft Learn documentation: +# https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/update-mgpolicyauthorizationpolicy +$params = @{ + blockMsolPowerShell = $true +} +Update-MgPolicyAuthorizationPolicy -BodyParameter $params ``` ### Related links