Configuring an Azure Function App to run a PowerShell script on a Timer Trigger

As a follow up to my previous post:

Creating a Service Principal to connect to Azure AD using a Certificate to authenticate
https://blog.terenceluk.com/2022/02/creating-service-principal-to-connect.html

This post serves to demonstrate how to create a Function App to automate the execution of a PowerShell script that is ran via a timer trigger.

Step #1 – Create the Function App

Begin by creating a Function App in the Azure portal:

114

Provide the required parameters:

Resource Group: <Name of resource group to place function app>

Function App name: <Name of Function App>

Publish: Code

Runtime stack: PowerShell Core

Version: 7.0

Region: <Desired region>

1113

Select the desired storage account and the plan type:

112

As this is the consumption plan, the Enable network injection is not available:

111

Application Insights is not available for the consumption plan:

110

Proceed to create the Function App:

109

Step #2 – Update Function App platform to 64 Bit

The default PowerShell Core settings for the Function App is set to 32-bit so navigate to Configuration > General settings > Platform, change the setting to 64-Bit and save:

108

Step #3 – Configure application settings

It is imperative that we do not include any sensitive parameters such as the tenant ID, application ID and certificate thumbprint in the PowerShell script to authenticate against Azure AD so these can be configured in the Function App’s Application settings as they would be encrypted and transmitted over an encrypted channel. Navigate to Configuration > Application settings then click on New application setting:

107

Configure the following 3 settings:

  1. tenant
  2. WEBSITE_LOAD_CERTIFICATES
  3. appId

Note that the second application setting named WEBSITE_LOAD_CERTIFICATES represents the certificate thumbprint the PowerShell script will use to authenticate against Azure AD and the reason why it is named as such is because the name will have the Azure Function load the certificate PFX when it starts. We’ll be referencing these variables within our PowerShell script. Proceed to save the new settings.

106

105

104

You should now see the 3 settings configured:

103

Step #4 – Load the exported PFX of the certificate used to authentication against Azure AD

With the application settings configured, proceed to upload the PFX export of the certificate that will be used by the PowerShell script to authenticate against Azure AD. Navigate to TLS/SSL settings > Private Key Certificates (.pfx) and click on Upload Certificate:

102

Proceed to upload the exported PFX certificate:

101

The certificate should be displayed under Private Key Certificates:

100

Step #5 – Define modules to load so the script can import them at runtime

Modules required by the PowerShell script will need to be loaded by the Function App. Proceed and navigate to App files then select requirements.psd1 from the drop down list:

99

From within this file, define the modules to load. For the purpose of this example, we will load the latest version 2 AzureAD module: https://www.powershellgallery.com/packages/AzureAD/2.0.2.140

Proceed to save the configuration:

98

Step #6 – Create the Function

Proceed to create the actual function containing the PowerShell script by navigating to Functions > Create, then enter the appropriate settings:

Development environment: we’ll use the portal for this example

Template: we’ll configure this function with a Timer trigger

New Function: Enter a name for the function

Schedule: As this is timer triggered, we’ll need to use NCRONTAB expressions to set the timer schedule (https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=csharp#ncrontab-expressions)

97

For the purpose of this example, the timer will be set to run every 3 hours Monday to Friday between 8a.m. to 6p.m. (8a.m., 11a.m., 2p.m., 5p.m.) so the NCRONTAB expression for this will be: 0 0 8-18/3 * * 1-5

Sample schedule:

2022-02-08 08:00:00

2022-02-08 11:00:00

2022-02-08 14:00:00

2022-02-08 17:00:00

2022-02-09 08:00:00

2022-02-09 11:00:00

2022-02-09 14:00:00

2022-02-09 17:00:00

2022-02-10 08:00:00

2022-02-10 11:00:00

2022-02-10 14:00:00

2022-02-10 17:00:00

2022-02-11 08:00:00

2022-02-11 11:00:00

2022-02-11 14:00:00

2022-02-11 17:00:00

2022-02-14 08:00:00

2022-02-14 11:00:00

2022-02-14 14:00:00

2022-02-14 17:00:00

Click on the create button to create the function.

Note that the default timezone used with the CRON expressions is Coordinated Universal Time (UTC) and if the schedule defined is to be ran on a different timezone, use the WEBSITE_TIME_ZONE app setting to change the timezone. Refer to the following document for more information: https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=csharp#ncrontab-time-zones

Step #7 – Configure the PowerShell script to run

Navigate into the Code + Test and switch to the run.ps1 script:

96

There will be a sample script provided and we’ll only need the first 2 lines:

# Input bindings are passed in via param block.

param($Timer)

Remove the remaining lines and add the lines declaring and setting the variables that will reference the application settings and the Connect-AzureAd cmdlet to connect to Azure AD:

Import-Module AzureAD -UseWindowsPowerShell

$tenant = $ENV:tenant

$thumb = $ENV:WEBSITE_LOAD_CERTIFICATES

$appId = $ENV:appId

Connect-AzureAD -TenantId $tenant -ApplicationId $AppId -CertificateThumbprint $thumb

As shown above, the $ENV: prefix is used to reference the application settings configured for the Function. At this point, save the function, so we can use the Test/Run button to test connectivity to the tenant:

95

The output should display a successful connection to Azure AD:

94

Now that we have confirmed connectivity, proceed to add the rest of the PowerShell script to the run.ps1 code and test that the Azure Function executes and completes as desired.