powershell
19 TopicsInstall AzureAD and AzureADPreview module in PowerShell Function App
One wants to install AzureAD and AzureADPreview in his/her windows PowerShell function app. Modules are already input in requirements.psd1, managedDependency is also enabled in host.json. But when executing functions in Azure, error "Could not load file or assembly…" shows up. Analysis: The problem is rooted in the compatibility issue between PS7(PowerShell Core 7) and module AzureAD and AzureADPreview. As of now, the Functions runtime with PowerShell 7 is being rolled out globally. If one wants to check the powershell Core Version, he/she can simply goes to Function Portal --> Configuration --> General settings. AzureAD works out of the box with Powershell 7! People need to import AzureAD with the -UseWindowsPowershell switch. Import-Module AzureAD -UseWindowsPowerShell Below is the detailed step one can use in order to install AzureAD and AzureADPreview module in Azure Function App. Step 1: In requirements.psd1, input the two modules with their versions, wildcard is recommend to get the latest version of module; @{ # 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' = '6.*' 'AzureADPreview' = '2.*' 'AzureAD' = '2.*' } Step 2: make sure “managedDependency” is set to true in host.json; { "version": "2.0", "logging": { "applicationInsights": { "samplingSettings": { "isEnabled": true, "excludedTypes": "Request" } } }, "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[1.*, 2.0.0)" }, "managedDependency": { "enabled": true } } Step 3: import module with below syntax: Import-Module AzureAD -UseWindowsPowerShell Import-Module AzureADPreview -UseWindowsPowerShell Results: Modules will be presented under C:\home\data\ManagedDependencies\xxxxxx.r. One can also invoke methods this module provides in his function code.35KViews6likes1CommentHow to deploy your Web App from Azure Pipeline with restricted access.
More and more users now choose to integrate App Service with Azure DevOps to streamline build and deployment process of their applications. The SCM site is the engine behind App Service for deployment, meaning that the release pipeline of Azure DevOps deploys code to the SCM site of an app. In most scenario, SCM site can be reached through public internet. Therefore, ensuring secure access to the site becomes more important. We can enable access restriction on SCM site or set up other firewall solutions to control incoming traffic to the site. Here we will introduce you on how to identify and whitelist deployment traffic from Azure pipeline to SCM site with access restriction. This article also applies when setting up the same rules in other firewall solutions.20KViews1like6CommentsManage Azure Resources using PowerShell Function App with Managed Identity
Briefly, this post will provide you a step to step guidance with sample code on how to leverage Azure PowerShell Function App to manage Azure resources and use managed identity for authentication to simplify the workflow. Azure PowerShell is a set of cmdlets for managing Azure resources directly from the PowerShell command line. Azure PowerShell is designed to make it easy to learn and get started with, but provides powerful features for automation. Azure Functions is a cloud service available on-demand that provides all the continually updated infrastructure and resources needed to run your applications. You focus on the pieces of code that matter most to you, and Functions handles the rest. Functions provides serverless compute for Azure. You can use Functions to build web APIs, respond to database changes, process IoT streams, manage message queues, and more. When we combine the Azure PowerShell and Azure Function App, it could make a magic. For example, we can make it automatic to restart a Virtual Machine(s) on schedule. Or update a rule in network security group with a HTTP request. In this post, we will take restoring Azure Web App from Snapshot regularly as an example to demonstrate the idea. The general workflow is as follow: Create PowerShell Function App -> Enable Managed identity -> Grant related resource permissions to the identity(Function App) -> Integrate Az module in functions -> Test and Run The topology is as below, we will grant role permission to Function App from source web app and Destination Web App. Then manage them from the function app. Steps: Create a Windows PowerShell Function App from portal Set up the managed identity in the new Function App by enabling Identity and saving from portal. It will generate an Object(principal) ID for you automatically. Now let's go to the source web app and add role assignment from Access control(IAM): To make it simple, we use the role "Contributor". Choose the Managed identity and find the Function App we just created. Repeat steps 3~5 for destination web app to grant permission for the function app. Alternatively, you can assign role at resource group(s) or subscription level. After finishing the role assignment. We will go ahead to install Az modules using managed dependencies by simply going to App files and choose requirements.psd1, then uncomment the line "# 'Az' = '7.*'". After then, when the first time we trigger the function, it will take some time to download these dependencies automatically. Now we can get back to the function app and go ahead to create a Timer trigger function, note that Azure Functions uses the NCronTab library to interpret NCRONTAB expressions. An NCRONTAB expression is similar to a CRON expression except that it includes an additional sixth field at the beginning to use for time precision in seconds: {second} {minute} {hour} {day} {month} {day-of-week} Reference: https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=csharp#ncrontab-expressions Leverage below sample code in the function. Sample Code: Replace the source and destination web app, resource groups with yours. # 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' property is 'true' when the current function invocation is later than scheduled. if ($Timer.IsPastDue) { Write-Host "PowerShell timer is running late!" } $srcWebappname = "SourceWebApp" $srcResourceGroupName = "SourceGroup" $dstWebappname = "DestinationWebApp" $dstResourceGroupName = "DestinationGroup" $snapshot = (Get-AzWebAppSnapshot -ResourceGroupName $srcResourceGroupName -Name $srcWebappname)[0] Write-Host "Start restoring Snapshot from $srcWebappname to $dstWebappname" Restore-AzWebAppSnapshot -ResourceGroupName $dstResourceGroupName -Name $dstWebappname -InputObject $snapshot -RecoverConfiguration -Force Write-Host "Done" # Write an information log with the current time. Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime" Test and Run: When we manually trigger it, it should be shown like as below: All done. Thanks for reading! I hope you have fun in it!11KViews3likes3CommentsPowershell script to download and restore the web app
If you would like to download the azure app service contents to on-prem server and restore back to azure app service using powershell script, you can refer following steps. First, we can use KUDU Zip REST API download the folders as ZIP files. GET /api/zip/{path}/ For more details, here is a document for your reference. https://github.com/projectkudu/kudu/wiki/REST-API#zip Since we need to use automated method way to do this, we can use service principal to connect azure account, then generate the token to call REST API. For service principal, you can refer following document to create service principal. https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal In order to call REST API, powershell usually use the Invoke-RestMethod module to call API. However, Invoke-RestMethod may have some problem when the site contains a lot of files. This was raised in github issue as following link. https://github.com/projectkudu/kudu/issues/1448#issuecomment-253796347 There is a workaround posted in above link you can refer. It looks like it's tied to Invoke-RestMethod and Invoke-WebRequest though, it seems to work fine when using System.Net.WebClient instead, so that can be a workaround for this. So the final script would be as following: $resourceGroupName = "henryapprg" $webAppName = "freewinhe" $slotName = "" $localPath = "c:\test\henry.zip" $ClientSecret = "serviceprincipalclientsecret" $ApplicationID = "serviceApplicationID" $TenantID = "tenantid" #use service principal to connect Azure Account $passwd = ConvertTo-SecureString $ClientSecret -AsPlainText -Force $pscredential = New-Object System.Management.Automation.PSCredential($ApplicationID, $passwd) Connect-AzAccount -Credential $pscredential -Tenant $TenantID -ServicePrincipal #generate token with Azure Account. $azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile $context =Get-AzContext $profileClient = New-Object Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient($azProfile) Write-Debug ("Getting access token for tenant" + $currentAzureContext.Subscription.TenantId) $token = $profileClient.AcquireAccessToken($context.Subscription.TenantId) $token.AccessToken $kuduApiAuthorisationToken = 'Bearer {0}' -f $token.AccessToken if ($slotName -eq ""){ $kuduApiUrl = "https://$webAppName.scm.azurewebsites.net/api/zip/site/wwwroot/" } else{ $kuduApiUrl = "https://$webAppName`-$slotName.scm.azurewebsites.net/api/zip/site/wwwroot/" } $virtualPath = $kuduApiUrl.Replace(".scm.azurewebsites.", ".azurewebsites.").Replace("/api/zip/site/wwwroot", "") Write-Host " Downloading File from WebApp. Source: '$kuduApiUrl'. Target: '$localPath'..." -ForegroundColor DarkGray #Call zip Rest API to download the Zip file from webapp. ` $WebClient = New-Object System.Net.WebClient $WebClient.Headers.Add('Authorization', $kuduApiAuthorisationToken) $WebClient.Headers.Add('ContentType', 'multipart/form-data') $WebClient.DownloadFile($kuduApiUrl, $localPath) Second, there is a document that introduce a powershell command to zip deploy. https://docs.microsoft.com/en-us/azure/app-service/deploy-zip#with-powershell Publish-AzWebapp -ResourceGroupName <group-name> -Name <app-name> -ArchivePath <zip-file-path> So the restore script would be like this: $localPath = "c:\test\henry.zip" $ClientSecret = "serviceprincipalclientsecret" $ApplicationID = "serviceApplicationID" $TenantID = "tenantid" #use service principal to connect Azure Account $passwd = ConvertTo-SecureString $ClientSecret -AsPlainText -Force $pscredential = New-Object System.Management.Automation.PSCredential($ApplicationID, $passwd) Connect-AzAccount -Credential $pscredential -Tenant $TenantID -ServicePrincipal Publish-AzWebapp -ResourceGroupName "henryapprg" -Name "phpwinhenry" -ArchivePath $localPath -Force7.3KViews1like0CommentsSteps to Manually Add PowerShell Modules in Function App
When using Azure Function Apps on a Consumption plan, you may encounter issues with dependency management due to the 500 MB temp storage limit, causing module installation failures. To avoid upgrading to a more expensive premium plan, you can manually add PowerShell modules using the provided steps.5.7KViews4likes2Comments