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