Skip to content

Commit 05fcb75

Browse files
authored
Merge pull request KelvinTegelaar#1075 from JohnDuprey/dev
Fix reset MFA
2 parents 9d8efca + 645b57a commit 05fcb75

1 file changed

Lines changed: 34 additions & 21 deletions

File tree

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,44 @@ Function Invoke-ExecResetMFA {
1313
$APIName = $TriggerMetadata.FunctionName
1414
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
1515

16-
17-
# Write to the Azure Functions log stream.
18-
Write-Host 'PowerShell HTTP trigger function processed a request.'
19-
Write-Host "$($Request.query.ID)"
2016
# Interact with query parameters or the body of the request.
2117
$TenantFilter = $Request.Query.TenantFilter
18+
$UserID = $Request.Query.ID
2219
try {
23-
$AADGraphtoken = (Get-GraphToken -scope 'https://graph.windows.net/.default')
24-
$tenantid = (Get-Tenants | Where-Object -Property defaultDomainName -EQ $TenantFilter).customerId
25-
$TrackingGuid = (New-Guid).GUID
26-
$LogonPost = @"
27-
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://provisioning.microsoftonline.com/IProvisioningWebService/MsolConnect</a:Action><a:MessageID>urn:uuid:$TrackingGuid</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><UserIdentityHeader xmlns="http://provisioning.microsoftonline.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><BearerToken xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">$($AADGraphtoken['Authorization'])</BearerToken><LiveToken i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService"/></UserIdentityHeader><ClientVersionHeader xmlns="http://provisioning.microsoftonline.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ClientId xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">50afce61-c917-435b-8c6d-60aa5a8b8aa7</ClientId><Version xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">1.2.183.57</Version></ClientVersionHeader><ContractVersionHeader xmlns="http://becwebservice.microsoftonline.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><BecVersion xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">Version47</BecVersion></ContractVersionHeader><TrackingHeader xmlns="http://becwebservice.microsoftonline.com/">$($TrackingGuid)</TrackingHeader><a:To s:mustUnderstand="1">https://provisioningapi.microsoftonline.com/provisioningwebservice.svc</a:To></s:Header><s:Body><MsolConnect xmlns="http://provisioning.microsoftonline.com/"><request xmlns:b="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:BecVersion>Version4</b:BecVersion><b:TenantId i:nil="true"/><b:VerifiedDomain i:nil="true"/></request></MsolConnect></s:Body></s:Envelope>
28-
"@
29-
$DataBlob = (Invoke-RestMethod -Method POST -Uri 'https://provisioningapi.microsoftonline.com/provisioningwebservice.svc' -ContentType 'application/soap+xml; charset=utf-8' -Body $LogonPost).envelope.header.BecContext.DataBlob.'#text'
30-
$MSOLXML = @"
31-
<?xml version="1.0" encoding="UTF-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://provisioning.microsoftonline.com/IProvisioningWebService/SetUser</a:Action><a:MessageID>urn:uuid:$TrackingGuid</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><UserIdentityHeader xmlns="http://provisioning.microsoftonline.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><BearerToken xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">$($AADGraphtoken['Authorization'])</BearerToken><LiveToken xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService" i:nil="true" /></UserIdentityHeader><BecContext xmlns="http://becwebservice.microsoftonline.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><DataBlob xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">$($DataBlob)</DataBlob><PartitionId xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">94</PartitionId></BecContext><ClientVersionHeader xmlns="http://provisioning.microsoftonline.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ClientId xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">50afce61-c917-435b-8c6d-60aa5a8b8aa7</ClientId><Version xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">1.2.183.57</Version></ClientVersionHeader><ContractVersionHeader xmlns="http://becwebservice.microsoftonline.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><BecVersion xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService">Version47</BecVersion></ContractVersionHeader><TrackingHeader xmlns="http://becwebservice.microsoftonline.com/">$TrackingGuid</TrackingHeader><a:To s:mustUnderstand="1">https://provisioningapi.microsoftonline.com/provisioningwebservice.svc</a:To></s:Header><s:Body><SetUser xmlns="http://provisioning.microsoftonline.com/"><request xmlns:b="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration.WebService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:BecVersion>Version16</b:BecVersion><b:TenantId>$($tenantid)</b:TenantId><b:VerifiedDomain i:nil="true" /><b:User xmlns:c="http://schemas.datacontract.org/2004/07/Microsoft.Online.Administration"><c:ObjectId>$($Request.query.id)</c:ObjectId><c:StrongAuthenticationMethods /><c:StrongAuthenticationRequirements><c:StrongAuthenticationRequirement><c:RelyingParty>*</c:RelyingParty><c:RememberDevicesNotIssuedBefore>0001-01-01T00:00:00</c:RememberDevicesNotIssuedBefore><c:State>Enabled</c:State></c:StrongAuthenticationRequirement></c:StrongAuthenticationRequirements></b:User></request></SetUser></s:Body></s:Envelope>
32-
"@
33-
$SetMFA = (Invoke-RestMethod -Uri 'https://provisioningapi.microsoftonline.com/provisioningwebservice.svc' -Method post -Body $MSOLXML -ContentType 'application/soap+xml; charset=utf-8')
34-
35-
$Results = [pscustomobject]@{'Results' = 'Successfully completed request. User must supply MFA at next logon' }
36-
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Reset Multi factor authentication settings for $($Request.query.id)" -Sev 'Info'
20+
Write-Host "Getting auth methods for $UserID"
21+
$AuthMethods = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$UserID/authentication/methods" -tenantid $TenantFilter -AsApp $true
22+
$Requests = [System.Collections.Generic.List[object]]::new()
23+
foreach ($Method in $AuthMethods) {
24+
if ($Method.'@odata.type' -and $Method.'@odata.type' -ne '#microsoft.graph.passwordAuthenticationMethod') {
25+
$MethodType = ($Method.'@odata.type' -split '\.')[-1] -replace 'Authentication', ''
26+
$Requests.Add(@{
27+
id = "$MethodType-$($Method.id)"
28+
method = 'DELETE'
29+
url = ('users/{0}/authentication/{1}s/{2}' -f $UserID, $MethodType, $Method.id)
30+
})
31+
}
32+
}
33+
if (($Requests | Measure-Object).Count -eq 0) {
34+
$Results = [pscustomobject]@{'Results' = "No MFA methods found for user $($Request.Query.ID)" }
35+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
36+
StatusCode = [HttpStatusCode]::OK
37+
Body = $Results
38+
})
39+
return
40+
}
41+
42+
$Results = New-GraphBulkRequest -Requests $Requests -tenantid $TenantFilter -asapp $true -erroraction stop
43+
44+
45+
if ($Results.status -eq 204) {
46+
$Results = [pscustomobject]@{'Results' = "Successfully completed request. User $($Request.Query.ID) must supply MFA at next logon" }
47+
} else {
48+
$FailedAuthMethods = (($Results | Where-Object { $_.status -ne 204 }).id -split '-')[0] -join ', '
49+
$Results = [pscustomobject]@{'Results' = "Failed to reset MFA methods for $FailedAuthMethods" }
50+
}
3751
} catch {
38-
$Results = [pscustomobject]@{'Results' = "Failed to reset MFA methods for $($Request.query.id): $($_.Exception.Message)" }
39-
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to reset MFA: $($_.Exception.Message)" -Sev 'Error'
40-
52+
$Results = [pscustomobject]@{'Results' = "Failed to reset MFA methods for $($Request.Query.ID): $(Get-NormalizedError -message $_.Exception.Message)" }
53+
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to reset MFA for user $($Request.Query.ID): $($_.Exception.Message)" -Sev 'Error' -LogData (Get-CippException -Exception $_)
4154
}
4255

4356
# Associate values to output bindings by calling 'Push-OutputBinding'.

0 commit comments

Comments
 (0)