Azure Function Apps can occasionally encounter challenges in downloading the required PowerShell modules within the 10-minute timeout period imposed by Microsoft during startup. To mitigate this issue, you can preload large PowerShell modules directly into the Function App’s storage, ensuring they are readily available without relying on external downloads during the initialization process. In this post, we’ll walk through all the necessary steps to ensure the required PowerShell modules are available in your Azure Function App.
Creating the Function App
- Head to the Azure Portal and create a Function App.
- As of 24.09.2024 be sure to use PS Core 7.4 or newer.
- Create a new storage account and add the Azure Files connection.
- Public access can be disabled, we’ll enable IP based access later on:
- To add application insights, it might need a new log analytics workspace.
- Skip continuous deployment, assign relevant tags and create the function app.
Configuration of relevant settings
With our newly created Function App, we can start configuring all the relevant settings.
- First, it’s a good practice to restrict public access to your Function App unless explicitly required. Begin by modifying the access restrictions to limit interaction to your specific public IP address. Navigate to Settings > Networking > Public Network Access, and set it to Disabled. This will block general public access to your Function App. Later, we’ll configure IP-based access to ensure secure communication.
- Add the Public IP(s) from which you’ll be managing the Function App.
- Navigate to Functions > App files, select host.json, and set the functionTimeout to the maximum of 10 minutes. Additionally, set managedDependency to false. Be aware that if you use managed dependencies, it may take several minutes to download the PowerShell module. Instead, we’ll upload the PowerShell module directly into the Function App storage.
{
"version": "2.0",
"managedDependency": {
"Enabled": false
},
"functionTimeout": "00:10:00",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
- Save the configuration and navigate to the next file called profile.ps1, where you can comment out the interaction with the Az PowerShell Module. Add lines 12 to 14 which this will append the custom PowerShell module path to $env:PSModulePath. Otherwise, your manually uploaded modules wouldn’t be detected. The profile.ps1 file is loaded each time you restart the Function App. The profile script also allows you to connect to Microsoft services at startup, instead of reconnecting every time the Function App script runs.
if (-not $env:PSModulePath.Split(';') -contains "$env:HOME\site\wwwroot\Modules") {
$env:PSModulePath += ";$env:HOME\site\wwwroot\Modules"
}
- Finally, the file requirements.psd1 will not be used as long as host.json has managedDependency set to false. In our case, we don’t need to make any changes to this file.
# This file enables modules to be automatically managed by the Functions service.
# See https://aka.ms/functionsmanageddependency for additional information.
#
@{
# For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'.
# To use the Az module in your function app, please uncomment the line below.
# 'Az' = '12.*'
}
- Under Settings, Configuration change the Platform to 64 Bit.

Uploading PowerShell Modules
Usually, the Function App is either very slow or fails to download the required PowerShell modules on its own. There’s an easy way around this if you want to directly upload the module.
- Head over to the connected storage account and generate a SAS key.
- Download the Microsoft Azure Storage Explorer and add the connection but be sure to add the azure file shares name to the SAS string. The string should look like the following one.
https://YOURSTORAGEACCOUNTNAME.file.core.windows.net/YOURAZUREFILESHARE?sv=2022-11-02......
- Once added, change the directory to site/wwwroot/ and create a new folder called Modules.
- Copy all your needed PowerShell Module folders directly into the newly created folder Modules.
Create a function to run a script
All required settings are set and the modules should be available to use. Open the Function App blade and add a new function.
- We’ll use a Time trigger to run our script regularly.
By using the cron expression 0 0 * * * * the function will run once an hour at minute 0. - Click on the function you just created and open the
run.ps1
script for editing. When using a Timer trigger, ensure the script includes theparam($Timer)
declaration, as it is required for the function to execute properly. To test the functionality of your function, add the following code snippet to therun.ps1
file and save the script:
# Input bindings are passed in via param block.
param($Timer)
# List all module paths
Write-Output "Current PSModulePaths: $($env:PSModulePath)"
# List the PowerShell modules in the custom path
Get-Module -ListAvailable -Name * | ForEach-Object {
Write-Host "Module: $($_.Name), Path: $($_.ModuleBase)"
}
- This script should output the details of the previously uploaded PowerShell modules. To verify the output, check the verbose logs in Application Insights. This will confirm that the uploaded modules are correctly recognized by your Function App.

What Now?
If you’re interested in taking your Azure Function Apps further, check out our other blog post Microsoft Graph Managed Identities – Digitalmaterial Blog on using managed identities to securely sign in to Microsoft Graph. This approach simplifies authentication while enhancing security, allowing your Function Apps to interact with Microsoft Graph without storing credentials.
Schreiben Sie einen Kommentar