Azure Function App: Run Every Minute
Description:
So if you ever have a runbook that you need to run often, like once a minute often, here is the workaround since the Web UI will only allow once an hour at most
To Resolve:
- Go to Automation Account => Runbooks => YourRunbook => Webhooks => Add Webhook
- Create a web hook, copy URL - you only get one chance to see this so write it down
- Make sure that it is set to run on your hybrid workers
-
Using Postman, use a Microsoft Graph API call to the webook and see if it works. Ensure that whatever user or application you are using has the permissions to execute runbooks. Honestly not sure what permissions are needed since this worked with my generic Powershell Rest API application and that app has no rights in my Azure subscription
-
Go to Function Apps => New
- Name:
run-every-minute
- Publish
code
, Runtime stackpowershell core
, version6
- New Function => ‘timer trigger’
- Name:
default
- Schedule:
0 */1 * * * *
- Click on the function name above the word functions => Platform Features => Configuration
- Add in the following environmental variables:
AzClientID = blah
andAzClientSecret = blah
replacingblah
with a clientID and clientSecret for an Azure app that has the ability to start runbooks via Rest API (as always, test this in Postman first!)
- Name:
-
Then set your code, under the provided code:
- Default code provided by Azure:
1 2 3 4 5 6 7 8 9 10 11 12 13
# Input bindings are passed in via param block. param($Timer) # Get the current universal time in the default string format $currentUTCtime = (Get-Date).ToUniversalTime() # The 'IsPastDue' porperty is 'true' when the current function invocation is later than scheduled. if ($Timer.IsPastDue) { Write-Host "PowerShell timer is running late!" } # Write an information log with the current time. Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime"
- Your code under it:
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
Function New-MSGraphAPIToken { <# .SYNOPSIS Acquire authentication token for MS Graph API .DESCRIPTION If you have a registered app in Azure AD, this function can help you get the authentication token from the MS Graph API endpoint. Each token is valid for 60 minutes. .PARAMETER ClientID This is the registered ClientID in AzureAD .PARAMETER ClientSecret This is the key of the registered app in AzureAD .PARAMETER TenantID This is your Office 365 Tenant Domain .EXAMPLE $graphToken = New-MSGraphAPIToken -ClientID <ClientID> -ClientSecret <ClientSecret> -TenantID <TenantID> The above example gets a new token using the ClientID, ClientSecret and TenantID combination .NOTES General notes #> param( [parameter(mandatory = $true)] [string]$ClientID, [parameter(mandatory = $true)] [string]$ClientSecret, [parameter(mandatory = $true)] [string]$TenantID ) $body = @{grant_type = "client_credentials"; scope = "https://graph.microsoft.com/.default"; client_id = $ClientID; client_secret = $ClientSecret } $oauth = Invoke-RestMethod -Method Post -Uri https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token -Body $body $token = @{'Authorization' = "$($oauth.token_type) $($oauth.access_token)" } Return $token } $clientID = $env:AzClientID $clientSecret = $env:AzClientSecret $TenantId = 'your-org-guid-for-tenant-id' $token = New-MSGraphAPIToken -clientID $clientID -clientSecret $clientSecret -tenantID $tenantID $uri = "https://s5events.azure-automation.net/webhooks?token=someToken" Try { Write-Output "Sending request to run azure job" Invoke-RestMethod -Method POST -Uri $uri -Headers $token -ErrorAction Stop Write-Output "Sending request to run azure job - completed" } Catch { Write-Output "Unable to send request" }
-
Set your function app execution to run every minute: Go to Integrate tab and choose schedule:
0 */1 * * * *
- Just a note that if you set it to something like
0 */1 8-17 * * 1-5
which will run every minute between 8-5 M-F, it will not work if your timezone is not exactly UTC. You have to go to your function app => App Settings (Configuration) and addWEBSITE_TIME_ZONE
with the value ofCentral Standard Time
for instance.
Comments