Azure Arm Template – VM Domain Join Automation


In this post we’re going to look at the ARM template and steps needed to simply Domain Join a Windows VM using Powershell DSC and Azure Automation.

The Arm template will do the following;

  • Create an Automation Account
  • Add a Automation Credential
  • Add a Automation Variable
  • Import a Powershell module
  • Add a DSC Configuration

We’ll then use a simple powershell script to

  • Specify the ConfigData
  • Compile the DSC Node Configuration

Then we’ll take to the portal and tell a VM to use this config.

Arm template

Take particular note of the parameters. They set up the Automation variable that holds the domain name, and the credentials for the user account that has permission in the domain to perform domain join.

The script can also be found here on github:

Config. Compliation script

This Powershell script will connect to Azure and submit a compilation of the DSC Configuration defined in the Arm template.

Assign configuration to existing VM.

Now that the Configuration has compiled, it’s ready to be used.
To assign it to a VM that already exists, the quickest way is to use the Portal.
Follow the wizard instructions to complete the enrolment, wait whilst the config is applied.
DSC Nodes

Applying VM Config during VM Arm template build

If you wanted to domain join a VM or VM Scaleset which is created from an Arm template then you can leverage this script. The 3 variables that need to be set;

  1. automationRegistrationUrl – Registration url from your azure automation account
  2. automationKey – access key from your azure automation account
  3. automationConfiguration – name of the configuration to apply.

Arm templates – Importing modules from the Azure Automation gallery


In this post we’re going to look at referencing Powershell modules from the gallery, in your own Arm templates. This will save having manual steps to complete after your Azure Automation Account has been deployed.
If you are looking to package up your own modules, then this guide is not for you.

Using ARM templates to deploy any kinds of infrastrure is foundational when it comes to cloud skills.
As part of an ARM template i’ve been creating; I’m wanting to deploy an Azure Automation Account, fully configured to be able to domain join VM’s. A good first step in creating an ARM template is to manually create the infrastructure in the Azure Portal and copy out the Automation Script before neatening up. Unfortunately this doesn’t work so well with several of the assets in an Automation Account, modules being the first issue.

I tend to heavily use Modules from the gallery, but it’s a little akward in inserting them into an ARM template. The Automation Script generated in Azure offers you something like this;

Which if you look at it, seems reasonable. Its type has been set to Microsoft.Automation/automationAccounts/modules and the version looks good. However this won’t pull down the module from the gallery.
Here’s what you need to do…

Find the Module

For me, my module is v1.1 of xDSCDomainJoin

Root Template

So on this page; a link to “Deploy to Azure Automation”
Clicking the link, takes you to the Azure Portal with the template pre-loaded to deploy.

If you extract the TemplateUrl out, and UrlDecode it, you’re left with;
When you hit this url you get prompted to download

Once it’s downlaoded, rename the files extension back to .json from .zip
Here’s what’s inside;

This is a pretty simple template that calls another template on the url held in this variable;
"templatelink": "[concat('', parameters('New or existing Automation account'), 'AccountTemplate.json')]",

Because we’re going to be using this in a New Automation Account, lets compose the url properly;

As parameters for this template, it passes in the Name and Uri for the xDSCDomainjoin module. We’ll come back for these variables later.

New account template

Follow the url from above;
You’ll be prompted to download Again, rename the extension back to .json.
Open the file and you’ll see;

Snipping the bits that matter

It’s simply the module resource that we want to steal to lift into our Automation Account template. Grab that definition, and the two variables from the last file and you have enough to plug into your own Arm template.

"xDSCDomainjoin:1.1.0:Name": "xDSCDomainjoin",
"xDSCDomainjoin:1.1.0:Uri": ""

"name": "[parameters('xDSCDomainjoin:1.1.0:Name')]",
"type": "modules",
"apiVersion": "2015-10-31",
"location": "[parameters('accountLocation')]",
"dependsOn": [
"[concat('Microsoft.Automation/automationAccounts/', parameters('accountName'))]"
"tags": {},
"properties": {
"contentLink": {
"uri": "[parameters('xDSCDomainjoin:1.1.0:Uri')]"

Azure ARM templates – Example use of Outputs

The Outputs part of an ARM template allow data to be retrieved as part of that templates creation.

Given a simple example of creating an vNet, here’s what we get.
Defining 3 outputs of differing types,
– Virtual Network [Object]
– Virtual Network Addresses [Array]
– Virtual Network Address Prefix [String] (first string in the array)

We get this output.

Powershell script for deploying and retrieving values.

Taking a more practical example, retrieving the StaticIP’s from APIM after creation;


Powershell Output

Building an Azure FormFlow Bot – the Job Bot

The Bot framework is some amazing tech to play with. It has some real practical business applications, but you can also have some fun with it – which is what I’ve done.

There are many different types of bot, but I’ve chosen a Forms Bot as being the most applicable to the task. It uses FormFlow and I’ve chosen to use c#, but I could have also used the Node.js template.

The Job Bot.
So I designed this to be the first point of contact for recruiters that contact me about a job. The bot asks the questions I care about, and submits the answers to an Azure Logic App which is where the interest I will have in the job is calculated and then returned to the bot.
There is a lot of different channels that you can have the bot interact on, I’ve focussed solely on Web chat. I’ve then created a basic web page to host it in :

Good points of the demo
So here’s the features of the demo that I’ll call out as being useful to you when creating your own bot;
– Defining the forms elements explicitly
– Making some form questions dependant on the answers of previous questions
– Calling out to an http web service to submit the answers to
– Referencing the environment variables in order to get the url for the web service

Bad points of the demo
The first couple of real world outings of the bot weren’t especially smooth. The recruiters were confused. They also couldn’t understand why after answering the questions they received such a low score. As a technology exercise, it’s been great but I’m not sure if I’m completely happy tormenting recruiters with it.

Source code
It’s all on GitHub, with the exception of the logic app. For that you’ll just want to create a Request/Response logic app or a function app etc.

Try it!
Try the bot here :

Dealing with code view quotes in an Azure Logic App | JSON

The visual designer in Logic Apps is pretty good, but all too often you need to break out to the code view. For me, this is usually because I want to construct some Json to pass into an Azure Function for processing. What’s not entirely obvious is the correct way in which to deal with double quotes inside the code view. As ever, when I google something and find nothing – I’ll share a blog about the answer was, and this is no exception 🙂

The correct escape characterto use is a backslash.

This snippet shows the final version of what i’m doing. In this case i’m writing the json out to a blob storage (as a debug step), before sending to an azure function for basic JSON validation and then giving the data onward to PowerBi for visualisation.
dealing with quotes in logic app JSON

And here’s the text;
"body": "{\"tweetId\": @{triggerBody()?['TweetId']}, \"tweet\": @{triggerBody()}, \"cogSentiment\": @{body('Detect_Sentiment')}, \"cogKeyPhrases\": @{body('Key_Phrases')}}",