- 30 Jan 2026
- 13 Minutes to read
- Print
- DarkLight
- PDF
After Resource Runs Logic App
- Updated on 30 Jan 2026
- 13 Minutes to read
- Print
- DarkLight
- PDF
In this scenario we want to implement a Logic App that will be triggered by the schedule After it takes an action on a resource such as turn it on/off or scale it up/down. In this example case I would like to use the Run Command feature on the Azure Management API to log a message to the event log on the VM. You could use this for many other such interactions which might involve running code on your VM.
The steps to achieve this are:
Create an action on the resource within the schedule
The schedule will trigger a logic app in my case which will call the Azure management API and use the Run Command operation to execute some Powershell on the VM.
Note you will need the appropriate RBAC access control for this.
HTTP Headers sent from Scheduler
The scheduler automation will pass some key HTTP headers to your Logic App. These include things like the name of the schedule and the group in cost analyzer. It will also include the below headers which are probably ones you will use to drive your workflow logic:
Header | Use | Values |
|---|---|---|
Execution-Type | This is used to indicate if its an event from the validate button or if the schedule has generally ran | Test = The validate button was clicked in the scheduler Actual = The scheduler actually ran |
Schedule-Operation | Used to indicate the state that the schedule is transferring resources to. | Start = We are going to the green state (scale up / turn on) Stop = We are going to the red state (scale down / turn off) |
AzureResourceId | Used to pass the resource id of the resource the scheduler is about to action |
Logic App Example
In the below picture you can see an example Logic App which will be used to handle the scenario of an extensibility before the overall schedule runs.
In the implementation I need to handle the following conditional Logic:
If the Execution-Type header is Test then just return an ACK that all is good with an HTTP 200 response
If Schedule-Operation is Start then do some action because the schedule is about to run and move resources to the started state
If Schedule-Operation is Stop then do some action because the schedule is about to run and move resources to the stopped state
The below picture shows my sample workflow which you could easily replicate then add your own custom extensibility.

Sample Logic App Template
The below json is a sample Logic App which you can paste into a logic app consumption logic app and use this to get up and running quickly.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"triggers": {
"When_an_HTTP_request_is_received": {
"type": "Request",
"kind": "Http"
}
},
"actions": {
"Response": {
"type": "Response",
"kind": "Http",
"inputs": {
"statusCode": 200
},
"runAfter": {
"Switch_-_Schedule_Operation": [
"Succeeded"
]
}
},
"Initialize_variables": {
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "executionType",
"type": "string",
"value": "@{triggerOutputs()?['headers']?['Execution-Type']}"
},
{
"name": "scheduleOperation",
"type": "string",
"value": "@{triggerOutputs()?['headers']?['Schedule-Operation']}"
},
{
"name": "resourceId",
"type": "string",
"value": "@{triggerOutputs()?['headers']?['AzureResourceId']}"
}
]
},
"runAfter": {}
},
"Condition_-_Is_Test_Event": {
"type": "If",
"expression": {
"and": [
{
"equals": [
"@variables('executionType')",
"Test"
]
}
]
},
"actions": {
"Response_-_Ack_-_Test": {
"type": "Response",
"kind": "Http",
"inputs": {
"statusCode": 200
}
},
"Terminate_-_Ack": {
"type": "Terminate",
"inputs": {
"runStatus": "Succeeded"
},
"runAfter": {
"Response_-_Ack_-_Test": [
"Succeeded"
]
}
}
},
"else": {
"actions": {}
},
"runAfter": {
"Initialize_variables": [
"Succeeded"
]
}
},
"Switch_-_Schedule_Operation": {
"type": "Switch",
"expression": "@variables('scheduleOperation')",
"default": {
"actions": {
"Compose_-_Do_nothing": {
"type": "Compose",
"inputs": "You would do nothing here because the schedule is not going to the start or stop state"
}
}
},
"cases": {
"Case_-_Start": {
"actions": {
"Compose_-_Do_Something_Start_State": {
"type": "Compose",
"inputs": "The schedule is about to run to move the resources to the start state. Do something here before the resources are acted upon"
},
"HTTP_-_Log_Start_Event": {
"type": "Http",
"inputs": {
"uri": "https://management.azure.com/@{variables('resourceId')}/runCommand?api-version=2025-04-01",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": {
"commandId": "RunPowerShellScript",
"script": [
"$logName = 'Application'",
"$source = 'Turbo360-FinOps'",
"$eventId = 3002",
"$message = 'Turbo360 scheduler has just started this VM'",
"",
"if (-not [System.Diagnostics.EventLog]::SourceExists($source)) {",
" New-EventLog -LogName $logName -Source $source",
"}",
"",
"Write-EventLog -LogName $logName -Source $source -EventId $eventId -EntryType Information -Message $message"
]
},
"authentication": {
"type": "ManagedServiceIdentity",
"identity": "/subscriptions/{your subscription id here}/resourceGroups/T360-Scheduler-VM-Demo-Actions/providers/Microsoft.ManagedIdentity/userAssignedIdentities/T360-Scheduler-VM-Demo-Actions",
"audience": "https://management.azure.com/"
},
"retryPolicy": {
"type": "none"
}
},
"runAfter": {
"Compose_-_Do_Something_Start_State": [
"Succeeded"
]
},
"runtimeConfiguration": {
"contentTransfer": {
"transferMode": "Chunked"
}
}
}
},
"case": "Start"
},
"Case_-_Stop": {
"actions": {
"Compose_-_Do_something_Stop_State": {
"type": "Compose",
"inputs": "The schedule is going to the stopped or scaled down state.\n\nYou can do something here to before the schedule is actioned"
}
},
"case": "Stop"
}
},
"runAfter": {
"Condition_-_Is_Test_Event": [
"Succeeded"
]
}
}
},
"outputs": {},
"parameters": {
"$connections": {
"type": "Object",
"defaultValue": {}
}
}
},
"parameters": {
"$connections": {
"type": "Object",
"value": {}
}
}
}