Hey friends,
In this post, we will dive into generating a report that tracks which workflows are running on which Logic App instances within your tenant. If you are using Logic Apps, especially the Consumption or Standard-based, keeping track of these workflows across different instances can be a challenge. The good news is, with the help of PowerShell that I have developed, we can create a report that highlights which Logic App instances are running which workflows. This report can be crucial for troubleshooting, performance monitoring, and resource management.
If you're running Logic App Standard instances, which can host multiple workflows, the need for clarity becomes even more essential. Previously, tracking this information was done manually or via portal interfaces, but with a little help from PowerShell, we can automate the reporting process. Iβve designed a script that collects the necessary information, processes it, and exports it in a way that's easy to understand.
π Query Logic App Workflows using PowerShellβ
For our task, we'll use PowerShell along with the Az.Resource module to query the status of workflows across Logic App instances. While Logic Apps provide a built-in management interface, using PowerShell can significantly streamline the process when handling large numbers of workflows.
Below is the script to help you generate a report of workflow instances across the tenantβs Logic App instances:
$subscriptions   = Get-AzSubscription
$logicAppsOutput = @()
$workflowsOutput = @()
ForEach ($subscription in $subscriptions) {
    
    Write-Output "Processing subscription: $($subscription.Name)"
    Set-AzContext -Subscription $subscription.Id
    $logicApps         = Get-AzResource -ResourceType 'Microsoft.Logic/workflows'
    $standardLogicApps = Get-AzResource -ResourceType 'Microsoft.Web/sites' | Where-Object { $_.Kind -like '*workflowapp*' }
    $allLogicApps      = $logicApps + $standardLogicApps
    ForEach ($logicApp in $allLogicApps) {
        Write-Output "Processing Logic App: $($logicApp.Name)" -ForegroundColor Green
        $resourceGroupName = $logicApp.ResourceGroupName
        $logicAppName      = $logicApp.Name
        $subscriptionId    = $subscription.Id
        $location = $logicApp.Location
        $state    = $null
        $kind     = $null
        $logicAppObj = [PSCustomObject]@{
            SubscriptionName  = $subscription.Name
            SubscriptionId    = $subscription.Id
            ResourceGroupName = $resourceGroupName
            LogicAppName      = $logicAppName
            Location          = $location
            State             = $null  # Placeholder, will update later
            Kind              = $null  # Placeholder, will update later
            
        }
        $logicAppsOutput += $logicAppObj
        # Check if the Logic App is Standard or Consumption
        if ($logicApp.Type -eq "Microsoft.Web/sites") {
            # Standard Logic App
            $kind = "Standard"
            try {
                $logicAppDetails = Get-AzWebApp -ResourceGroupName $resourceGroupName -Name $logicAppName
                $state           = $logicAppDetails.State
            } catch {
                Write-Warning "Failed to retrieve details for Standard Logic App: $logicAppName"
                $state = "Unknown"
            }
            $logicAppObj.State = $state
            $logicAppObj.Kind  = $kind
            # Retrieve workflows within the Standard Logic App
            $workflowsUrl = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Web/sites/$logicAppName/workflows?api-version=2022-03-01"
            try {
                $workflows = @()
                $nextLink  = $workflowsUrl
                do {
                    $response = Invoke-AzRestMethod -Method GET -Uri $nextLink
                    $content  = $response.Content | ConvertFrom-Json
                    if ($content.value) {
                        $workflows += $content.value
                    }
                    $nextLink = $content.nextLink
                } while ($nextLink)
                # Loop through each workflow
                foreach ($workflow in $workflows) {
                    $workflowName = $workflow.name
                    # Create an object for each workflow
                    $workflowObj = [PSCustomObject]@{
                        SubscriptionName  = $subscription.Name
                        SubscriptionId    = $subscription.Id
                        ResourceGroupName = $resourceGroupName
                        LogicAppName      = $logicAppName
                        WorkflowName      = $workflowName
                        Location          = $location
                        State             = $state
                        Kind              = $kind
                    }
                    $workflowsOutput += $workflowObj
                }
                if ($workflows.Count -eq 0) {
                    $workflowObj = [PSCustomObject]@{
                        SubscriptionName  = $subscription.Name
                        SubscriptionId    = $subscription.Id
                        ResourceGroupName = $resourceGroupName
                        LogicAppName      = $logicAppName
                        WorkflowName      = "No Workflows Found"
                        Location          = $location
                        State             = $state
                        Kind              = $kind
                    }
                    $workflowsOutput += $workflowObj
                }
            }
            catch {
                Write-Warning "Failed to retrieve workflows for Standard Logic App: $logicAppName"
                $workflowObj = [PSCustomObject]@{
                    SubscriptionName  = $subscription.Name
                    SubscriptionId    = $subscription.Id
                    ResourceGroupName = $resourceGroupName
                    LogicAppName      = $logicAppName
                    WorkflowName      = "Error retrieving workflows"
                    Location          = $location
                    State             = $state
                    Kind              = $kind
                }
                $workflowsOutput += $workflowObj
            }
        }
        elseif ($logicApp.Type -eq "Microsoft.Logic/workflows") {
            $kind = "Consumption"
            try {
                $logicAppDetails = Get-AzLogicApp -ResourceGroupName $resourceGroupName -Name $logicAppName
                $state           = $logicAppDetails.State
            } catch {
                Write-Warning "Failed to retrieve details for Consumption Logic App: $logicAppName"
                $state = "Unknown"
            }
            $logicAppObj.State = $state
            $logicAppObj.Kind  = $kind
            # The workflow name is the same as the Logic App name
            $workflowName = $logicAppName
            $workflowObj = [PSCustomObject]@{
                SubscriptionName  = $subscription.Name
                SubscriptionId    = $subscription.Id
                ResourceGroupName = $resourceGroupName
                LogicAppName      = $logicAppName
                WorkflowName      = $workflowName
                Location          = $location
                State             = $state
                Kind              = $kind
                
            }
            $workflowsOutput += $workflowObj
        }
        else {
            Write-Warning "Unknown Logic App type for: $logicAppName"
            $kind = "Unknown"
            $logicAppObj.Kind = $kind
        }
    }
}
$timestamp         = Get-Date -Format "yyyyMMdd-HHmmss"
$workflowsFileName = "LogicAppWorkflows-Report-$timestamp.csv"
Write-Output "INFO: Exporting Logic App Workflows to CSV file: $workflowsFileName"
$workflowsOutput | Export-Csv -Path "$PSScriptRoot\$workflowsFileName" -NoTypeInformation -Force
π» Generating a Logic Apps Workflow Reportβ
Let's break down the script to understand how it works and what it does: The script leverages the Get-AzResource cmdlet to query all Logic Apps and Standard Logic Apps under a subscription. It then retrieves relevant details such as the workflow name, state, and the type of Logic App (Standard or Consumption). After collecting the necessary data, the script exports it into a CSV report for easier analysis.
π Execute the Scriptβ
The script will automatically get all subscriptions in the tenant and retrieve the details of each Logic App instance, including the workflows running within them. To run the script, follow these steps:
## Run the script to generate the report
.\Get-AzLogicAppWorkflowReport.ps1
Once the script finishes, youβll find a file named LogicAppWorkflows-Report-<timestamp>.csv that contains all the gathered workflow details, which you can use for further analysis or reporting.
π Extending the Scriptβ
Feel free to customize the script further if you need more specific information, such as filtering workflows by state, trigger type, or other parameters. Let me know if you have any ideas for additional features, and we can enhance the script together!