Jason Haley

Ramblings from an Independent Consultant

What I’m using to stay up to date on Azure news

Happy New Year!

Yeah, yeah I know - January is almost over already. You aren't tired and letting up on your resolutions yet are you? I know sometimes when I start a new year with a plan to make lots of changes and to be focused on a new year full of goals that really interest me … I start to run out of gas around the end of week 3.

Well it is now the beginning of week 4 - time to get back to it! Reread you goals and for those goals that have to do with keeping up to date and learning more about Azure - here are some resources for you that I just recently discovered.

We have a "pandemic puppy", whose name is Duncan (he is the one in the photo above) and I now have a reason to take a drive and go on a walk every morning. The drive is key - about 30 minutes each way - it gives me around 1 hour a day when I can easily listen to podcasts or audiobooks.

Here are the Azure podcasts I'm currently listening to:

Azure Podcast
Website: http://azpodcast.azurewebsites.net/
YouTube: https://www.youtube.com/c/TheAzurePodcast/featured
Hosted by: Cynthia Kreng @cynthiaKrenG, Kendall Roden @KendallRoden, Cale Teeter @CaleTeeter, Evan Basalik @EvanBasaliK, Russell Young @youngr6 & Sujit D'Mello (couldn't find on twitter)

Azure security Podcast
Website: https://azsecuritypodcast.net/
Hosted by Mark Simos @marksimos, Sarah Young @_sarahyo, Michael Howard @michael_howard and Gladys Rodriguez @Cyber_batgirl

Website: https://ctrlaltazure.com/
Hosted by Tabias Zimmergren @zimmergre and Jussi Roine @jussiroine

Azure for Executives
Website: https://azure.microsoft.com/en-us/industries/podcast/
Hosted by David Star @ElegantCoder

I'm probably one of the last people in the tech industry to have just started listening to podcasts and am curious - do you have any favorite Azure podcasts?

Last week I also discovered two Azure "news sites" I hadn't come across before that I'm going to start looking at on a regular basis:

Azure Info Hub
Url: https://azureinfohub.azurewebsites.net
Looks to be created by: Holger Sirtl (@hsirtl - https://twitter.com/hsirtl/)

Azure Notes
Url: https://www.azurenotes.tech/
Looks to be created by Derek Martin (@thebookofdoodle - https://twitter.com/thebookofdoodle)

This month I'm experimenting with using daily learning topics, where I'll spend any spare time listening, reading, etc. to content on a singular topic - one of which is Azure. For example I'll start the day listening to Azure podcasts during our commute to the beach/woods for a walk and back, then later on I'll check out any Azure news and maybe watch a YouTube video or just read Azure related content. So far this daily topic experiment is working pretty well to help me slowly get up to date in several topics … I'll keep you posted on how this experiment goes.

Do you have any tips on keeping up to date on Azure related topics?

Learning containers, Docker and Kubernetes

This blog has been quiet for a while, mainly because I have been busy learning containers, Docker and Kubernetes. In the past year and a half, the learning has often been side projects and presentations – but this year things have changed and I’m now using this stuff on a daily basis. I still have a lot to learn but I think it is time to start sharing some of what I have learned.

My motivations for understanding and using containers has evolved from focusing on a new deployment solution (ie. Docker containers) to running applications in an environment that assumes everything is already containerized (ie. Kubernetes). In between those two are new DevOps techniques to connect the them and in the end my life as a developer easier.

However, I’m still on the journey and have a lot more to learn.

Containers and Docker are the basics

Step one in this journey really is learning what containers are. Step two is taking the container concept and using Docker to apply it.

First start out with pulling and running existing Docker images from DockerHub. Donavan Brown has a nice blog on Fun with SQL Server Containers that requires little knowledge of how it all works and shows you the practical nature of how to use containers. It will get those gears in your head turning.

After you have played with Docker for a while, the next challenge is to go from source code to a running container. For this, you’ll need an introduction to Dockerfile.

If you use Visual Studio, the easiest way to get started is to create a new .NET Core ASP.NET project and check the “Enable Docker Support” checkbox. Then run your application.

After that is really learning what the Dockerfile does and some Best practices for writing Dockerfiles so you can start customizing it when needed.

Running in Kubernetes is the goal

With Kubernetes, there are options for to get started:

1. Use Kubernetes with Docker Desktop – this is the quickest, free and runs on your local machine.

2. Use Azure Kubernetes Service - this compares to Kubernetes the Easy Way and will put your application in the cloud.

3. Kubernetes The Hard Way - this will give you the ultimate understanding of how the platform works, since you’ll need to build it all.

If your goal is like mine, running your application in Kubernetes, then I would recommend #1 and then move to #2. Eventually I’d recommend trying out #3 to get a deeper dive once you are familiar with using Kubernetes.

Recently I discovered the Kubernetes Learning Path that walks you through videos, articles and hands on practice – I highly recommend starting with it.

What’s next

Watch this blog. I’m going to start regularly posting on containers, Docker and Kubernetes. I’m working on a sort of blog series about general tips and tricks I’ve learned along the way and new things as I discover them.

If you are an application developer and learning containers, Docker or Kubernetes and have a topic you’d like to see please contact me on Twitter @haleyjason.

Virus Scan File Uploads Using Multi-Container Web App

This month at the Microsoft Build conference, the Azure App Service team announced multi-container support for Linux Web Apps. This capability enables you to deploy multiple containers in a single Web App.

In the session PaaS and Container Innovation – What’s new with App Service members of the App Service team show a demo of a Web App that has three containers: Nginx, WordPress and Redis.

The multi-container capability isn’t designed to compete with Kubernetes or other orchestrators but to just allow the ability to easily add that one or two more containers that will help support your containerized web application (like a cache for example).

This past weekend I was working on an Azure Functions extension that I’m planning on using to provide virus scanning for a website – when the thought crossed my mind that multi containers would enable me to provide virus scanning to a web app even easier. So, I took a detour from working on my extension and worked on this sample instead.


Often web sites need the ability to upload files. However, if you have been through a secure code review or penetration testing, you’ll know that to safely provide that functionality to your users you need to scan any uploaded files for viruses. This is one of those parts of an implementation people put off until later – especially if they don’t already have a solution for the virus scanning – then find out implementing it isn’t as easy as it should be.

In Azure you can upload files easily to blob storage, ensure the transport is secure and even ensure the files are encrypted at rest. But scanning those saved blobs for viruses is one of those features you have to implement yourself.

A couple of options for virus scanning via an API:

  • VirusTotal – a third party API that would require passing the file out of Azure to the service
  • ClamAV – an open source anti-virus scanning server (GNU GPL v2 license)

For my scenario, I have the following constraints:

  • I need to be able to integrate the virus scanning into my codebase using C#
  • I cannot transfer the files out of the data center just to scan for viruses
  • I don’t want to have a VM running 24/7 that is only used to scan less than 100 files a month

The Solution: Linux Web App with Two Containers

After doing some research, I’ve found a way to stay within my constraints and easily add virus scanning to a Web App.

  1. Use ASP.NET Core so I can run the site in a Linux container
  2. Use a second container to run the mkodockx/docker-clamav image (utilize the Nuget nClam package as a client to the ClamAv server)
  3. No need for a VM since we can now run multiple containers in a single Web App


Creating the demo web app

To verify things work the way I want, I created a simple web app that uploads files and then displays the results of the virus scan. In order to save time, I started with the Asp.Net Core Web application template, ripped the majority of the views and actions out and then used some code from the ASP.NET Core documentation for the file upload logic: File uploads in ASP.NET Core

I put a copy of the code in GitHub if you want to see the full web site code: https://github.com/JasonHaley/file-upload-demo

Here’s the code that takes the uploaded file(s), passes them off to the ClamAV server container and returns the results:

public async Task UploadFiles(List files)
    var log = new List();

    foreach (var formFile in files)
        if (formFile.Length > 0)
            var clam = new ClamClient("clamav-server", 3310);
            var result = await clam.SendAndScanFileAsync(formFile.OpenReadStream());

            log.Add(new ScanResult()
                FileName = formFile.FileName,
                Result = result.Result.ToString(),
                Message = result.InfectedFiles?.FirstOrDefault()?.VirusName,
                RawResult = result.RawResult
    var model = new UploadFilesViewModel();
    model.Results = log;
    return View(model);

The important thing to note with using the ClamClient– is the communication between the web site and the clamav-server container uses the container’s name, not an IP address.


You can follow these rest of this entry if you want to get it going yourself. In order to do this, you will need Docker for Windows running on your machine and a recent version of Visual Studio 2017.

Once you have the file upload logic in your ASP.NET Core Web application, you need to add the Docker support to the project.

1. Right click on the WebApp in the Solution Explorer

2. Choose Add -> Docker Support


This will add a Dockerfile to your Web project and a docker-compose project to the solution.


In your docker-compose project, open the docker-compose.yml file and add the clamav-server to the services, like shown below:

version: '3.4'

    image: mkodockx/docker-clamav
    image: ${DOCKER_REGISTRY}webapp
      context: .
      dockerfile: WebApp/Dockerfile

Now run the debugger (hit F5) to start the web application. The first run will take a little while to start since it has to pull down the ClamAV image and update the virus definitions.

Once it starts you should see a file upload page like shown here:


Select a file to upload and see if it has a virus in it:


If you want to test for a virus you can find the Eicar virus text for a test file here: http://www.eicar.org/86-0-Intended-use.html

Push the Docker Image to a Docker Hub

Now that the code works locally, the next step is to put the web project’s container into a repository so you can configure a Web App in Azure to use it.

For the purposes of this demo, I put my web app in docker hub at: https://hub.docker.com/r/haleyjason/file-upload-demo/

If you want to create your own image to put in docker hub, change your build to a Release build then start the application again. This will create the release images locally.

You will also need to have a Docker Hub account and create a repo to push the image to.

Once you have the Docker Hub repo ready, complete the following steps at a command line:

  1. List your Docker containers to get the container id and name
    docker ps
  2. Login by using the following and entering your Docker Hub username instead of <username>
    docker login –username <username>
    Then enter your password when prompted
  3. Tag your image using your container id and repo name
    docker tag <container> <dockerhub account>/<docker hub repo>:<tag>
    I used something like:
    docker tag 0c98 haley/file-upload-demo:latest
  4. Push the image to the repo
    docker push <dockerhub account>/<docker hub repo>

You should now have the web app container in Docker Hub.

Create the Azure Web App

The last step is to create a Web App and a Docker Compose file to connect the images.

First create a docker-compose.yml file that just connects the containers. The file contents should be similar to the following:

version: '3.4'

    image: haleyjason/file-upload-demo
    image: mkodockx/docker-clamav

Save this file somewhere so you can upload it to the Web App in the next part.

  1. In the Azure portal, Click on the plus in the upper left corner -> Web -> Web App
  2. On the Web App blade:
    - Provide an App name
    - Select your subscription
    - Select or create a new Resource Group
    - For OS, select Docker
    - For demo purposes, stay with the Generated App Service plan
  3. Click on the Configure container menu, then the Docker Compose (Preview) tab
  4. In the Configuration text box –> clik the folder icon and select the docker-compose.yml file you created earlier that connects the two containers.
  5. Click OK
  6. Check the Pin to dashboard checkbox
  7. Click the Create button to get the process of creating the web app started
  8. Once the web app is ready, in the Overview blade, click on the URL in for the application

Now wait 5 – 10 minutes … the first load takes several minutes – but once it is up and running it responds normally. 

When I select a couple of files:


I now get the scanned results:



The new multi-container capability of Azure App Service Linux Web Apps seems like a promising way to provide that ability to host a virus scanning server along side your web application.

Setup OWASP Juice Shop in Azure Container Instances (Part 3 of 3)

In the second part of this series we walked through using Web App for Containers as a way to get the OWASP Juice Shop Project up and running. 

In this part, I want to provide a step-by-step reference in how to get it running using Azure Container Instances.

Using the Azure Portal

1. Login to your Azure Subscription at https://portal.azure.com

2. Click on the Create Resource (plus) button in the upper left corner, select Containers, then Azure Container Instances


3. On the Create Azure Container Instances Basics blade enter values for the following:

  • Container name: unique name for your container (not the name from the container registry)
  • Select Public for the container image type
  • Container image: bkimminich/juice-shop
  • Subscription: choose your subscription
  • Resource Group: select an existing or enter a new one
  • Select a location near you
  • Click OK


4. On the Configuration blade

  • Select Linux for the OS Type
  • Select 1 for Number of cores
  • Select 1.5 GB for Memory
  • Select Yes for Public IP Address
  • Enter 3000 for the Port number
  • Click OK


5. Click OK on the Summary blade


Once the container is stared you will be able to navigate to the instance and find the IP Address in the upper right corner of the Overview panel. 


If you copy this IP address and add :3000 on the end for the port in a browser you will now get Juice Shop running.


Using the Azure CLI or Cloud Shell

If you are using Azure CLI - you will need to do step 0 to login and if you are using Cloud Shell – you will need to do step 0 to open the shell.

Azure CLI – Only

0. In a command window type the following and press enter

Then open a browser and type the code shown to you for authenticating and click Continue

You can know close that browser window.

Cloud Shell – Only

0. Click on the Cloud Shell button in the upper right of the portal image


The remaining steps are the same for both the CLI and the Cloud Shell.

1. Create a resource group using the az group create command giving it a resource name and location and hit enter


2. Create a new container using the az container create command giving it values for:

  • --resource-group juiceshop-cli-demo
  • --name juiceshop-cli-aci1
  • --image bkimminich/juice-shop
  • --dns-name-label juiceshop-cli-aci
  • --ports 3000
  • --ip-address public


Once the container is up and running, you can use this pattern to access the site: http://<dns-name-label>.<datacenter>.azurecontaner.io:3000


That is all it takes to get the Juice Shop up and running in Azure Container Instance – just 2 commands (1 if you already have a resource group).  Pretty nice.

Setup OWASP Juice Shop in Web App for Containers (Part 2 of 3)

If you want to know more about Web App for Containers, you can see Part 1 of this series for a brief feature outline or even better the documentation for Web App for Containers (also often referred as App Service on Linux) for more detail.

In this part I want to provide a step-by-step reference in how to get the OWASP Juice Shop Project setup and running in Web App for Containers.

Using the Azure Portal

1. Login to your Azure subscription at https://portal.azure.com

2. Click on the Create Resource (plus) button in the upper left corner, select Web + Mobile, then Web App for Containers


3. On the Web App for Containers Create blade enter the following:

  • App Name: enter unique name for app
  • Subscription: choose your subscription
  • Resource Group: select an existing or enter a new one

4. Click on the App Service plan

  • Click on Create New
  • Enter a name for the App Service Plan
  • Select a location near to you
  • Click Ok

5. Click on configure container

  • Select Docker Hub for the Image source
  • Select Public for Repository Access
  • Enter bkimminich/juice-shop for the Image name
  • Click OK


6. Check Pin to dashboard and click Create

Once the Web App loads and the overview blade is showing, click on the url in the upper right corner of the Overview


That should launch the Juice Shop in a browser:


Using the Azure CLI or Cloud Shell

If you are using the Azure CLI, you will need to do step 0 below (with the Cloud Shell there is no need to login)

Azure CLI - Only

0. In a command window type the following and press enter

az login


Then open a browser and type the code shown to you for authenticating and click Continue


You can know close that browser window.

Cloud Shell – Only

0. Click on the Cloud Shell button in the upper right of the portal image


Ok, the remaining steps will work with both the CLI and the Cloud Shell

1. Create a resource group using the az group create command giving it a resource name and location and hit enter


2. Create an app service plan using the az appservice plan create command giving it values for:

  • --name
  • --resource-group (same one you just created)
  • --sku
  • --is-linux


3. Create the web app using the az webapp create command giving it values for:

  • --resource-group (same group as above)
  • --plan (same name as plan you just created)
  • --name
  • --deployment-container-image-name NOTE: This is: bkimminich/juice-shop


Once the app is ready you can open a browser and navigate to the first url in the enabledHostNames section of the json retuned.  In my example it was https://juiceshop-web-cli.azurewebsites.net


That was the Web Apps for Container, now we can move onto Setup OWASP Juice Shop in Azure Container Instances

How to Setup OWASP Juice Shop on Azure (Part 1 of 3)

Last year when I was working on my Securing Your Web Application in Azure with a WAF talk, I was looking for a way to avoid writing my own site that exposed things like SQL injection and cross site scripting (XSS) and happened to find the Juice Shop project (I think it was Bill Wilder that introduced me to it but I’m not 100% sure).  The OWASP Juice Shop Project is a great site for testing your exploit skills on a modern web app … or in my case testing the effectiveness of a Web Application Firewall (WAF).

There are many resources on the web to find more information on the juice shop project and how to exploit it, I’m going to focus on the two easiest and quickest ways I’ve found in getting it running in Azure:

  • Web App for Containers
  • Azure Container Instances

For the individual walkthroughs, I want to cover both using the Azure portal and the Azure CLI in order to serve as a better reference – so to keep the length shorter I’m going to break this up into three parts:

First a little about these Azure products and their features.

Web App for Containers

Web App for Containers are similar to Web Apps and build on the App Service platform, but there isn’t feature parity between the two.  The most common features of Web Apps are supported including:

  • FTP capability
  • Deployment Slots
  • CI/CD integration
  • Application Settings (think environment variables that can be managed in the control plane)
  • Backups
  • Custom domains
  • SSL Certificates
  • Scale in/out (including autoscale)
  • Scale up/down (though not all App Service tiers are available)

Things special to Web App for Containers:

  • SSH to the container experience
  • Ability to deploy the site from a container registry

Currently only Linux containers are supported – which for the case of running Juice Shop is not a problem.

Web App for Containers seems designed for the scenario when you want to host a web site from a (Linux) container.

Azure Container Instances

Container Instances are basically Containers-as-a-Service and designed for single container workloads.  However you can run multiple containers in container groups (similar to a pod in Kubernetes).

  • Supports both Linux or Windows containers
  • Can run containerized tasks (not designed only for serving web sites that don’t return)
  • Ability mount Azure Files as volumes in a container
  • Can have multiple ports (and not just 80 and 443)
  • Public IP and DNS name labels are optional
  • Using the Kubernetes Connector, ACI can serve as a host in a burst scenario to handle excess capacity and host pods in container groups

Azure Container Instances seems more of a bare container product and designed for shorter run sites or tasks as well as extending existing Kubernetes clusters when needed.


Now that I’ve introduced the products, I will now provide the walkthroughs of the two different options. Next is Web App for Containers.

Talk: Securing Your Web Application in Azure with a WAF

Last night I spoke at the Boston Azure User Group. The slides are available here: Securing Your Web Application in Azure with a WAF

As I mentioned last night, this is the first edition of the talk, I plan on giving it to my user group next month (October) and again at the Boston Code Camp in November – so if you have any feedback please let me know I’d love to improve the content.

I want to work more demos into the presentation next time … and of course get them all to work (1 demo didn’t work last night).

Here are some of the useful links mentioned last night:

Next time for the demos I’m going to look at using the OWASP Juice Shop webapp

Talk: Design Azure Web Apps and Mobile Apps

Wednesday and Thursday of this week (Sept 27 – 28) I helped out with the second round of 70-534 Architecting Azure Solutions Event in NYC (the Boston event was Sept 14 - 15).  Microsoft is organizing these events in many cities currently in the mid-west and east coast.

My talk was on Web and Mobile Apps.  There were about 40 – 50 people in the room and around 200 on the simulcast.

BTW: if you are interested in having an event streamed you should check out Nelco Media.

One of the links I mentioned for people who are studying for the exam: Exam prep for Architecting Microsoft Azure Solutions, 70-534 it has the exam OD’s linked to the corresponding landing area in the Azure documents.

My presentation can be downloaded on github here and here are links to the labs for the Web Apps and the Mobile Apps

Azure Help: Traffic Manager–PowerShell Script to Add Traffic Manager Probe IP Addresses

If you are using Traffic Manager to route traffic between two data centers and the endpoints are inside of a VNET, you’ll need to add network security group rules for Traffic Manager’s probe IP Addresses or your endpoints will always show as degraded.


Once you think of the purpose of the probe … then it makes total sense why the endpoint shows as being “Degraded” – if traffic manager can’t get to the endpoint then it can’t make a decision of whether it should send traffic to it or not.

So in order to fix the, you need to add the Traffic Manager probe IP Addresses to the inbound NSG rules of you VNET.  That is simple to do in the portal (or via PowerShell) but – there are 23 of them!  Who really wants to manually enter 23 of them? … and don’t forget there are 2 data centers, so that is really 46 of them.

I certainly don’t enjoy entering that many NSG rules (even though it is easy) – so I created a script to do it.

In my case, I had east and west coast data center locations.  You’ll need to plug in your subscription, resource groups, nsg names and maybe change the probe port and the number to start the priority at (I have 150 – 173).

You should also verify the IP Addresses have not changed from the listing on this page: https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-faqs under the question “What are the IP addresses from which the health checks originate?” about 3/4 the way down the page.

The source code can be found here: https://github.com/JasonHaley/AzureHelp/blob/master/TrafficManager/AddTrafficManagerProbeRules.ps1

#Verify latest Probe IP Addresses at https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-faqs

$subscriptionId = "YourSubscriptionId"
$resourceGroupEast = "EastCoastResourceGroup"
$resourceGroupWest = "WestCostResourceGroup"
$nsgEast = "EastCoastNSG"
$nsgWest = "WestCoastNSG"
$probePort = 80 
$rulePriorityStart = 150
$rulePriority = $rulePriorityStart

$trafficManagerProbeIPs = @("",`
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `
                             "", `


Set-AzureRmContext -SubscriptionId $subscriptionId

$groupEast = Get-AzureRMNetworkSecurityGroup -ResourceGroupName $resourceGroupEast `
     -Name $nsgEast
$groupWest = Get-AzureRMNetworkSecurityGroup -ResourceGroupName $resourceGroupWest `
     -Name $nsgWest

For($i=0; $i -lt $trafficManagerProbeIPs.Length; $i++) {
    $ruleName = "Inbound-TMProbe" + $i.ToString() + "-Https-Allow"

    $rulePriority = $rulePriorityStart + $i

    $groupEast | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleName `
        -Description "Allow Traffic Manager Probe HTTPS" `
        -Access Allow -Protocol Tcp -Direction Inbound -Priority $rulePriority `
        -SourceAddressPrefix $trafficManagerProbeIPs[$i] -SourcePortRange * `
        -DestinationAddressPrefix * -DestinationPortRange $probePort

    $groupWest | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleName `
        -Description "Allow Traffic Manager Probe HTTPS" `
        -Access Allow -Protocol Tcp -Direction Inbound -Priority $rulePriority `
        -SourceAddressPrefix $trafficManagerProbeIPs[$i] -SourcePortRange * `
        -DestinationAddressPrefix * -DestinationPortRange $probePort
$groupEast | Set-AzureRmNetworkSecurityGroup
$groupWest | Set-AzureRmNetworkSecurityGroup

This script has saved me a lot of time.


Traffic Manager routing methods

Traffic Manager Frequently Asked Questions (FAQ)

Manage network security groups using PowerShell

Create network security groups using PowerShell

Add/Set/Remove NSG rules in ARM mode Azure Powershell

Azure Help: WebApps–Copying and Exporting Connection Strings and App Settings

When you create a WebApp in Azure’s App Service, you get a couple of important features with Application Settings:

  1. The ability for your developers not know the production app settings or connection strings values … or just the option to develop with settings that are not used once deployed (such as working with a local database)
  2. The ability to override values in the web.config that is deployed with the application

The first item is important for security reasons.  It makes it possible to control access to the production credentials.  The second item is really useful for changing settings for different environments – such as a staging db for a staging slot and a production db for the production slot.

I am a big fan of using Application Settings in my WebApps.

If you are not familiar with them, just look for the Application Settings menu item in your Web App (shown below).  The App settings and Connection strings sections are what I want to discuss below.


I’ve included some reference links at the bottom of this entry for you to learn more (if you are interested).

Problem 1:  Get a list of all the App Settings and/or Connection Strings of a deployed WebApp

The Azure portal will allow you to view all the settings, but sometimes you need the values for several app settings and/or connection strings – so viewing the values in the portal isn’t enough.

To solve this problem, I have created a PowerShell script that exports the values to two csv files (if I want both AppSettings and ConnectionString).  Usually it is just the AppSettings that I need, but you never know.

The source code can be found here:https://github.com/JasonHaley/AzureHelp/blob/master/WebApps/ExportConnectionStringsAndAppSettings.ps1

$subscriptionId = "<subscriptionId>"
$resourceGroupSource = "<source resource group>"
$webAppsource = "<source web app name>"
$slotSource = "<source slot>"

$appSettingsFileName = "appSettings.csv"
$connectionStringsFileName = "connectionStrings.csv"


Set-AzureRmContext -SubscriptionId $subscriptionId

# Load Existing Web App settings for source and target
$webAppSource = Get-AzureRmWebAppSlot -ResourceGroupName $resourceGroupSource `
   -Name $webAppsource -Slot $slotSource

# Create csv files if file names are set
If ($appSettingsFileName -ne "") {
    $webAppsource.SiteConfig.AppSettings | Select-Object -Property Name, Value | `
       Export-Csv -Path $appSettingsFileName -NoTypeInformation

If ($connectionStringsFileName -ne "") {
    $webAppsource.SiteConfig.ConnectionStrings | Select-Object -Property Name, Type, `
ConnectionString | Export-Csv -Path $connectionStringsFileName -NoTypeInformation }

The generated csv files look like this:


Problem 2:  Copy all the App Settings and/or Connection Strings to another WebApp

Once in awhile I need to move WebApps from one place to another or lately I’ve been upgrading clients from ASEv1 instances to ASEv2 instances – which means a new build of an environment (not an upgrade).  ASE stands for App Service Environment.

If I already have the values of the AppSettings and ConnectionStrings in a deployed WebApp … it would be nice to copy the values to the new one and not have to enter them one-by-one.

The important thing to note: AppSettings and ConnectionStrings are not in source control (unless you have complete ARM templates stored … which you wouldn’t want your secrets in – so that complicates matters) … so deploying the latest code to the new WebApp is only part of the solution of spinning up a new environment.

To solve this problem, I have created a PowerShell script that will copy over all the AppSettings and/or ConnectionStrings of one WebApp to another WebApp.

The source code can be found here: https://github.com/JasonHaley/AzureHelp/blob/master/WebApps/CopyConnectionStringsAndAppSettings.ps1

$subscriptionId = "<subscriptionId>"
$resourceGroupSource = "<source resource group>"
$resourceGroupTarget = "<target resource group>"

$webAppsource = "<source web app name>"
$webAppTarget = "<target web app name>"

$slotSource = "<source slot>"
$slotTarget = "<target slot>"


Set-AzureRmContext -SubscriptionId $subscriptionId

# Load Existing Web App settings for source and target
$webAppSource = Get-AzureRmWebAppSlot -ResourceGroupName $resourceGroupSource `
    -Name $webAppsource -Slot $slotSource

# Get reference to the source Connection Strings
$connectionStringsSource = $webAppSource.SiteConfig.ConnectionStrings

# Create Hash variable for Connection Strings
$connectionStringsTarget = @{}

# Copy over all Existing Connection Strings to the Hash
ForEach($connStringSource in $connectionStringsSource) {
    $connectionStringsTarget[$connStringSource.Name] = `
         @{ Type = $connStringSource.Type.ToString(); `
            Value = $connStringSource.ConnectionString }

# Save Connection Strings to Target
Set-AzureRmWebAppSlot -ResourceGroupName $resourceGroupTarget -Name $webAppTarget `
    -Slot $slotTarget -ConnectionStrings $connectionStringsTarget

# Get reference to the source app settings
$appSettingsSource = $webAppSource.SiteConfig.AppSettings

# Create Hash variable for App Settings
$appSettingsTarget = @{}

# Copy over all Existing App Settings to the Hash
ForEach ($appSettingSource in $appSettingsSource) {
    $appSettingsTarget[$appSettingSource.Name] = $appSettingSource.Value

# Save Connection Strings to Target
Set-AzureRmWebAppSlot -ResourceGroupName $resourceGroupTarget -Name $webAppTarget `
   -Slot $slotTarget -AppSettings $appSettingsTarget

These two scripts save me a lot of time due to the reality of there being several AppSettings that I need to work with (when I need to work with them).


Using App Settings in Azure Web Apps

Windows Azure Web Sites: How Application Strings and Connection Strings Work

Azure App Service Web Config Vs Application Settings

Easily Manage Azure Web App Connection Strings using PowerShell

Using Powershell to manage Azure Web App Deployment Slots