Skip to content

Commit 83fd3e7

Browse files
committed
fix: enable MDE connector before applying settings
1 parent 5ae9927 commit 83fd3e7

2 files changed

Lines changed: 159 additions & 1 deletion

File tree

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
function Enable-CIPPMDEConnector {
2+
<#
3+
.SYNOPSIS
4+
Provisions the Microsoft Defender for Endpoint Intune connector for a tenant.
5+
.DESCRIPTION
6+
Checks whether the MDE mobile threat defense connector (partnerState) is already 'available' or 'enabled'.
7+
If not, iterates through regional MDE API portal endpoints until one succeeds, then verifies
8+
the connector state afterwards. Endpoints are ordered so that the tenant's likely region
9+
(based on org countryLetterCode) is tried first.
10+
.PARAMETER TenantFilter
11+
The tenant domain or ID to provision the connector for.
12+
.FUNCTIONALITY
13+
Internal
14+
#>
15+
[CmdletBinding()]
16+
param(
17+
[Parameter(Mandatory = $true)]
18+
[string]$TenantFilter
19+
)
20+
21+
# MDE connector ID is fixed across all tenants
22+
$ConnectorId = 'fc780465-2017-40d4-a0c5-307022471b92'
23+
$ConnectorUri = "https://graph.microsoft.com/beta/deviceManagement/mobileThreatDefenseConnectors/$ConnectorId"
24+
25+
# All known regional provisioning endpoints
26+
$AllEndpoints = @(
27+
'mde-rsp-apiportal-prd-eus.securitycenter.windows.com'
28+
'mde-rsp-apiportal-prd-eus3.securitycenter.windows.com'
29+
'mde-rsp-apiportal-prd-cus.securitycenter.windows.com'
30+
'mde-rsp-apiportal-prd-cus3.securitycenter.windows.com'
31+
'mde-rsp-apiportal-prd-weu.securitycenter.windows.com'
32+
'mde-rsp-apiportal-prd-weu3.securitycenter.windows.com'
33+
'mde-rsp-apiportal-prd-neu.securitycenter.windows.com'
34+
'mde-rsp-apiportal-prd-neu3.securitycenter.windows.com'
35+
'mde-rsp-apiportal-prd-uks.securitycenter.windows.com'
36+
'mde-rsp-apiportal-prd-ukw.securitycenter.windows.com'
37+
'mde-rsp-apiportal-prd-aue.securitycenter.windows.com'
38+
'mde-rsp-apiportal-prd-aus.securitycenter.windows.com'
39+
'mde-rsp-apiportal-prd-aec0a.securitycenter.windows.com'
40+
'mde-rsp-apiportal-prd-aen0a.securitycenter.windows.com'
41+
'mde-rsp-apiportal-prd-ins0a.securitycenter.windows.com'
42+
'mde-rsp-apiportal-prd-inc0a.securitycenter.windows.com'
43+
'mde-rsp-apiportal-prd-sww0a.securitycenter.windows.com'
44+
'mde-rsp-apiportal-prd-swn0a.securitycenter.windows.com'
45+
)
46+
47+
# Country code -> likely regional endpoint prefixes (used to prioritize, not restrict)
48+
$RegionPriority = @{
49+
'US' = @('eus', 'eus3', 'cus', 'cus3')
50+
'CA' = @('eus', 'eus3', 'cus', 'cus3')
51+
'GB' = @('uks', 'ukw')
52+
'AU' = @('aue', 'aus', 'aec0a', 'aen0a')
53+
'IN' = @('ins0a', 'inc0a')
54+
'SE' = @('sww0a', 'swn0a')
55+
'DE' = @('weu', 'weu3')
56+
'FR' = @('weu', 'weu3')
57+
'NL' = @('weu', 'weu3')
58+
'BE' = @('weu', 'weu3')
59+
'AT' = @('weu', 'weu3')
60+
'CH' = @('weu', 'weu3')
61+
'IE' = @('neu', 'neu3')
62+
'FI' = @('neu', 'neu3')
63+
'NO' = @('neu', 'neu3')
64+
'DK' = @('neu', 'neu3')
65+
}
66+
67+
# Check current connector state
68+
try {
69+
$ConnectorState = New-GraphGetRequest -uri $ConnectorUri -tenantid $TenantFilter
70+
} catch {
71+
$ErrorMessage = Get-CippException -Exception $_
72+
Write-LogMessage -API 'MDEConnector' -tenant $TenantFilter -message "Failed to retrieve MDE connector state. Error: $($ErrorMessage.NormalizedError)" -Sev Error -LogData $ErrorMessage
73+
throw "Failed to retrieve MDE connector state for $TenantFilter. Error: $($ErrorMessage.NormalizedError)"
74+
}
75+
76+
if ($ConnectorState.partnerState -in @('available', 'enabled')) {
77+
Write-LogMessage -API 'MDEConnector' -tenant $TenantFilter -message 'MDE Intune connector is already in available state.' -Sev Info
78+
return [PSCustomObject]@{
79+
Success = $true
80+
AlreadyDone = $true
81+
PartnerState = $ConnectorState.partnerState
82+
}
83+
}
84+
85+
# Build a prioritized endpoint list based on tenant country
86+
$PrioritizedEndpoints = [System.Collections.Generic.List[string]]::new()
87+
try {
88+
$OrgInfo = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/organization' -tenantid $TenantFilter
89+
$CountryCode = $OrgInfo.countryLetterCode
90+
if ($CountryCode -and $RegionPriority.ContainsKey($CountryCode)) {
91+
$PrefixHints = $RegionPriority[$CountryCode]
92+
foreach ($endpoint in $AllEndpoints) {
93+
foreach ($prefix in $PrefixHints) {
94+
if ($endpoint -like "*-prd-$prefix.*") {
95+
$PrioritizedEndpoints.Add($endpoint)
96+
break
97+
}
98+
}
99+
}
100+
}
101+
Write-Information "MDE connector provisioning for $TenantFilter (country: $CountryCode): prioritized $($PrioritizedEndpoints.Count) regional endpoint(s)"
102+
} catch {
103+
Write-Information "Could not retrieve org country for $TenantFilter - will try all endpoints"
104+
}
105+
106+
# Append remaining endpoints that weren't already prioritized
107+
foreach ($endpoint in $AllEndpoints) {
108+
if ($endpoint -notin $PrioritizedEndpoints) {
109+
$PrioritizedEndpoints.Add($endpoint)
110+
}
111+
}
112+
113+
# Try each endpoint until one succeeds
114+
$ProvisionBody = '{"timeout":60000}'
115+
$ProvisionScope = 'https://api.securitycenter.windows.com/.default'
116+
$SuccessfulEndpoint = $null
117+
118+
foreach ($endpoint in $PrioritizedEndpoints) {
119+
$ProvisionUri = "https://$endpoint/api/cloud/portal/onboarding/intune/provision"
120+
try {
121+
Write-Information "Attempting MDE provisioning for $TenantFilter via $endpoint"
122+
$null = New-GraphPOSTRequest -uri $ProvisionUri -tenantid $TenantFilter -body $ProvisionBody -scope $ProvisionScope
123+
$SuccessfulEndpoint = $endpoint
124+
Write-LogMessage -API 'MDEConnector' -tenant $TenantFilter -message "MDE Intune connector provisioned successfully via $endpoint" -Sev Info
125+
break
126+
} catch {
127+
$ErrorMessage = Get-CippException -Exception $_
128+
Write-Information "Endpoint $endpoint failed for $TenantFilter`: $($ErrorMessage.NormalizedError)"
129+
}
130+
}
131+
132+
if (-not $SuccessfulEndpoint) {
133+
$Msg = "Failed to provision MDE Intune connector for $TenantFilter - all regional endpoints were unsuccessful."
134+
Write-LogMessage -API 'MDEConnector' -tenant $TenantFilter -message $Msg -Sev Error
135+
throw $Msg
136+
}
137+
138+
# Verify the connector state after provisioning
139+
try {
140+
$UpdatedState = New-GraphGetRequest -uri $ConnectorUri -tenantid $TenantFilter
141+
} catch {
142+
$UpdatedState = $null
143+
}
144+
145+
return [PSCustomObject]@{
146+
Success = $UpdatedState.partnerState -in @('available', 'enabled')
147+
AlreadyDone = $false
148+
Endpoint = $SuccessfulEndpoint
149+
PartnerState = $UpdatedState.partnerState
150+
}
151+
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ function Invoke-AddDefenderDeployment {
1111
$APIName = $Request.Params.CIPPEndpoint
1212
$Headers = $Request.Headers
1313

14-
1514
$Tenants = ($Request.Body.selectedTenants).value
1615
if ('AllTenants' -in $Tenants) { $Tenants = (Get-Tenants -IncludeErrors).defaultDomainName }
1716
$Compliance = $Request.Body.Compliance
@@ -22,6 +21,14 @@ function Invoke-AddDefenderDeployment {
2221
$Results = foreach ($tenant in $Tenants) {
2322
try {
2423
if ($Compliance) {
24+
$ConnectorStatus = Enable-CIPPMDEConnector -TenantFilter $tenant
25+
if (!$ConnectorStatus.Success) {
26+
"$($tenant): Failed to enable MDE Connector - $($ConnectorStatus.ErrorMessage)"
27+
continue
28+
} else {
29+
"$($tenant): MDE Connector is $($ConnectorStatus.PartnerState). Attempting to set compliance and reporting settings..."
30+
}
31+
2532
$SettingsObject = @{
2633
id = 'fc780465-2017-40d4-a0c5-307022471b92'
2734
androidEnabled = [bool]$Compliance.ConnectAndroid

0 commit comments

Comments
 (0)