Recently I client ask me to enable application and http logging for more than 20 AzureRM Web Apps. Furthermore the client wanted the logs to be stored in a Storage Account.

Issues started when I decided to Use PowerShell to Enable Logging for Azure RM Web Apps, because there is no equivalent to the ASM Enable-AzureWebsiteApplicationDiagnostic cmdlet for ARM resources.

So how could I enable logging and the needed configuration? Well there is a handy cmdlet that can be used to set almost any property for an Azure ARM resource: Set-AzureRmResource

And how can anyone discover what properties must be set in order to enable or disable features? Well what I usually do is go to portal.azure.com and configure a service as specified. Then I browse with Resource Explorer to find the properties and values I need for the desired configuration.

In my clients case I needed to set the following properties:

  • applicationLogs.azureBlobStorage.level
  • applicationLogs.azureBlobStorage.sasUrl
  • applicationLogs.azureBlobStorage.retenionDays
  • httpLogs.azureBlobStorage.level
  • httpLogs.azureBlobStorage.sasUrl
  • httpLogs.azureBlobStorage.retenionDays
  • httpLogs.azureBlobStorage.enabled

So for the solution I just need to create a storage account and set those properties for every Web App found inside a Resource Group. This is the script I used:

  1function Add-IndexNumberToArray (
  2    [Parameter(Mandatory = $True)]
  3    [array]$array
  4) {
  5    for ($i = 0; $i -lt $array.Count; $i++) { 
  6        Add-Member -InputObject $array[$i] -Name "#" -Value ($i + 1) -MemberType NoteProperty 
  7    }
  8    $array
  9}
 10
 11# Enable Web App Service Logs
 12function Enable-WebAppServiceLogs() {
 13    Add-AzureRmAccount
 14
 15    [array]$SubscriptionArray = Add-IndexNumberToArray (Get-AzureRmSubscription) 
 16    [int]$SelectedSub = 0
 17
 18    # use the current subscription if there is only one subscription available
 19    if ($SubscriptionArray.Count -eq 1) {
 20        $SelectedSub = 1
 21    }
 22    
 23    # Get SubscriptionID if one isn't provided
 24    while ($SelectedSub -gt $SubscriptionArray.Count -or $SelectedSub -lt 1) {
 25        Write-host "Please select a subscription from the list below"
 26        $SubscriptionArray | Select-Object "#", Id, Name | Format-Table
 27        try {
 28            $SelectedSub = Read-Host "Please enter a selection from 1 to $($SubscriptionArray.count)"
 29        }
 30        catch {
 31            Write-Warning -Message 'Invalid option, please try again.'
 32        }
 33    }
 34
 35    # Select subscription
 36    Select-AzureRmSubscription -SubscriptionId $SubscriptionArray[$SelectedSub - 1].Id
 37
 38    # Ask for the resource group.
 39    $resourceGroupName = Read-Host 'Resource Group name'
 40
 41    # Ask for the storage account name
 42    $storageAccountName = Read-Host 'Storage account name'
 43
 44    # Exit if resource group does not exists...
 45    $resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
 46    if (!$resourceGroup) {
 47        Write-Verbose "$resourceGroup does not exists..."
 48        Exit 
 49    }
 50
 51    # Create a new storage account.
 52    $storage = Get-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName -ErrorAction SilentlyContinue
 53    if (!$storage) {
 54        $storage = New-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName -Location $resourceGroup.Location -SkuName "Standard_ZRS"
 55    }
 56
 57    # Create a container for the app logs 
 58    New-AzureStorageContainer -Context $storage.Context -Name "webapp-logs" -ErrorAction Ignore
 59
 60    # Get a SAS token for the container
 61    $webSASToken = New-AzureStorageContainerSASToken -Context $storage.Context `
 62        -Name "webapp-logs" `
 63        -FullUri `
 64        -Permission rwdl `
 65        -StartTime (Get-Date).Date `
 66        -ExpiryTime (Get-Date).Date.AddYears(1)
 67
 68    # Create a container for the http logs
 69    New-AzureStorageContainer -Context $storage.Context -Name "http-logs" -ErrorAction Ignore
 70
 71    # Get a SAS token for the container
 72    $httpSASToken = New-AzureStorageContainerSASToken -Context $storage.Context `
 73        -Name "http-logs" `
 74        -FullUri `
 75        -Permission rwdl `
 76        -StartTime (Get-Date).Date `
 77        -ExpiryTime (Get-Date).Date.AddYears(1) 
 78    
 79    # Get all web app  in the resource group
 80    $resources = (Get-AzureRmResource).Where( {$_.ResourceType -eq "Microsoft.Web/sites" -and $_.ResourceGroupName -eq $resourceGroupName})
 81
 82    # For each web app enable application and http logs 
 83    foreach ($resource in $resources) {
 84        # Property Object holding the log configuration.
 85        $propertiesObject = [ordered] @{
 86            'applicationLogs' = @{
 87                'azureBlobStorage' = @{
 88                    'level'           = 'Error' 
 89                    'sasUrl'          = [string]$webSASToken
 90                    'retentionInDays' = 30
 91                }
 92            }
 93            'httpLogs'        = @{
 94                'azureBlobStorage' = @{
 95                    'level'           = 'Error' 
 96                    'sasUrl'          = [string]$httpSASToken
 97                    'retentionInDays' = 30
 98                    'enabled'         = $true
 99                }
100            }
101        } 
102
103        # Set the properties. Note that the resource type is: Microsoft.Web/sites/config and the resource name: [Web App Name]/logs
104        Set-AzureRmResource `
105            -PropertyObject $propertiesObject `
106            -ResourceGroupName $resourceGroupName `
107            -ResourceType Microsoft.Web/sites/config `
108            -ResourceName "$($resource.ResourceName)/logs" -ApiVersion 2016-03-01 -Force          
109    }
110}
111
112Enable-WebAppServiceLogs

If you save the script in a file (i.e Enable-WebAppServiceLogs.ps1) you can run it as follows:

1.\Enable-WebAppServiceLogs.ps1

The script will ask you to:

  • login to your Azure account
  • select a subscription
  • write the name of the resource group containing the web apps
  • write the name of the storage account to hold the logs

Get the code here: https://github.com/cmendible/azure.powershell.samples/tree/main/Enable-WebAppServiceLogs

Hope it helps!