PowerShell + REST APIs to monitor the status of MS Flows
Translated from the Spanish original. Read in Spanish
In this guide, we’ll learn how to use PowerShell together with REST APIs and an Azure Service Principal to monitor the status of several Flows. This can be especially useful for managing and automating alerts on critical flows.

Create a Service Principal in Azure
Before running the script, you’ll need to create a Service Principal in Azure. It acts as an application identity that lets you authenticate and perform operations through the Azure APIs.
Define the environment ID and the scope
The EnvironmentID is the Microsoft Automate environment where your flows live.
$environmentId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$scope = "https://service.flow.microsoft.com//.default"
Set the Flows to monitor
Create a hashtable with the names of the Flows you want to monitor and their IDs.
$taskFlows = @{
"Flow1" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
"Flow2" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Agrega más Flows si es necesario
}
Service Principal details
Provide your Service Principal’s details: Tenant ID, Application ID and Secret.
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$appId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$appSecret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Getting the Token for the Service Principal
Send a request to get an access token, which we’ll use to authenticate our API calls.
$body = @{
grant_type = "client_credentials"
client_id = $appId
client_secret = $appSecret
scope = $scope
}
$tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method Post -Body $body
$token = $tokenResponse.access_token
Setting up the headers for the API call
The headers include the access token and the accepted content type.
$headers = @{
Authorization = "Bearer $token"
'Content-Type' = 'application/json'
}
Creating a Hashtable to store the failure status of the Flows
$flowFailureStatus = @{}
Loop through and process each Flow
Loop through each Flow, check its status and store the result in the hashtable.
foreach ($key in $taskFlows.Keys) {
Write-Output "Processing: $key"
Write-Output "FlowName: $($taskFlows[$key])"
Write-Output "------------------"
$taskFlowID = $($taskFlows[$key])
$apiUrl = "https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/$environmentId/flows/$taskFlowID/runs?api-version=2016-11-01&$top=50"
try {
$response = Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Get
if ($key -eq "Flow1") {
$runningCount = ($response.value | Where-Object { $_.properties.status -eq 'Running' }).Count
if ($runningCount -eq 5) {
Write-Output "Flow Alert: at least 5 jobs are still running in the Flow1 flow."
}
}
$failedCount = ($response.value | Where-Object { $_.properties.status -eq 'Failed' }).Count
if ($failedCount -gt 5) {
Write-Output "The flow has failed more than 5 times."
$flowFailureStatus[$key] = $true
}
} catch {
Write-Output "Failed to retrieve flow run history for: $key"
Write-Output $_.Exception.Message
$flowFailureStatus[$key] = $null
}
Write-Output "------------------"
}
Complete code
Here is the complete PowerShell script to monitor the status of your Flows:
$environmentId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$scope = "https://service.flow.microsoft.com//.default"
$taskFlows = @{
"Flow1" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
"Flow2" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# ... (agrega tantos Flows como necesites)
}
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$appId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$appSecret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Acquire Token for Service Principal
$body = @{
grant_type = "client_credentials"
client_id = $appId
client_secret = $appSecret
scope = $scope
}
$tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method Post -Body $body
$token = $tokenResponse.access_token
$headers = @{
Authorization = "Bearer $token"
'Content-Type' = 'application/json'
}
$flowFailureStatus = @{}
foreach ($key in $taskFlows.Keys) {
Write-Output "Processing: $key"
Write-Output "FlowName: $($taskFlows[$key])"
Write-Output "------------------"
$taskFlowID = $($taskFlows[$key])
$apiUrl = "https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/$environmentId/flows/$taskFlowID/runs?api-version=2016-11-01&$top=50"
try {
$response = Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Get
if ($key -eq "Flow1") {
$runningCount = ($response.value | Where-Object { $_.properties.status -eq 'Running' }).Count
if ($runningCount -eq 5) {
Write-Output "Flow Alert: at least 5 jobs are still running in the Flow1 flow."
}
}
$failedCount = ($response.value | Where-Object { $_.properties.status -eq 'Failed' }).Count
if ($failedCount -gt 5) {
Write-Output "The flow has failed more than 5 times."
$flowFailureStatus[$key] = $true
}
} catch {
Write-Output "Failed to retrieve flow run history for: $key"
Write-Output $_.Exception.Message
$flowFailureStatus[$key] = $null
}
Write-Output "------------------"
}
if ($flowFailureStatus.Count -gt 0) {
Write-Host "Flows that have failed the last 5 times:"
foreach ($flow in $flowFailureStatus.GetEnumerator()) {
if ($flow.Value -eq $true) {
Write-Host "Flow: $($flow.Key) - Failed 5 times consecutively"
}
}
} else {
Write-Host "No flows have failed the last 5 times."
}
