Recently VM running Server Technical Preview were added Azure Gallery and I thought of deploying a VM running it joined to my test domain (see my post on using PowerShell to deploy a DC on Azure ), But I wanted to do that using Azure Automation.
Azure Automation is a highly scalable workflow engine offering where we can have Runbooks (PowerShell workflows) to automate long running , error prone tasks.
I first saw this in action at one of the sessions by Ravi Sir [PowerShell MVP] at one of the PowerShell Bangalore User Group meet where he used Runbooks to demonstrate really cool stuff.
Note - Azure Automation is still in preview so you might have to sign up for it by navigating to https://account.windowsazure.com/PreviewFeatures
Divided the post into 3 steps:
1. Get the Ground work ready
2. Create the Assets
3. Create a RunBook to deploy the VM (and add it to the domain)
First of all create an Azure Automation account from the portal (no PowerShell cmdlet for that at the moment). Once done it should show up in the Azure portal like below :
So before we start doing anything else we need a mechanism in place to authenticate to Azure against my subscription. There are two ways to achieve that (links in Resource section) :
In my opinion using Azure AD for the authentication is better and easier to explain (am gonna use that for this post) . The below steps of using Azure AD for Authentication are borrowed from the Azure blog found here.
Now Let's head to our Azure Active Directory > Default Directory > Users > Add User.
Then after this you will see a wizard to add a User, Key in the UserName:
Click Next, Be careful and do not enable Multi-Factor auth.
On next screen , Click "Create Temporary password". Make a note of Complete Username and temporary password. We will change it in next step.
Now logout of the browser or open another web browser and navigate to https://manage.windowsazure.com/ .
Now on the Sign-in page , you have to specify the username of the User you created above (that's why we had to make a note of the Username and Password).
After this you will be asked to enter password (key in the temporary password). Log-in and you will be asked to change your password, do that.
But before we get ahead of ourselves we have few important questions to answer here.
This is where the Assets kick in (no Cmdlets as of now ).
We will have to create 3 Credential assets (stores Username and Password) to tackle this problem at hand. Creating Assets is very straight ahead :
Navigate to Azure Automation > Your Automation Account > Assets > Click on "Add Setting" (at the bottom). After this you will be presented with a page like below :
Select "Add Credential"
Give a Name to the Asset, have kept the Asset name same as the Azure AD User name.
In the next screen give the User name and Password of the User we added in the first step to Azure AD.
The first asset is created, Now I will similarly add 2 mores credentials asset named "DomainDexterPOSH" of a User in my Domain dex.com which has permissions to add a Machine to my domain and another set of credential called "LocalDexterPOSH" to set the local admin username and password for the New VM which our workflow will provision.
Under the Automation account in Azure portal, I can create a new RunBook from Scratch (supports authoring workflows) or create a workflow locally and upload it using the Azure Automation cmdlets. The Azure Automation cmdlets are evolving at the moment , So for this post let's focus more on using the portal to author RunBooks.
Let's get familiarize with how a runbook looks like in the Azure portal.
To create a new runbook in portal you can click "New" and give it a name (see below)
Your runbook name should be unique among your runbooks.
Once done you will see the Runbook sitting in your Azure Automation account.
Click on it and it lands you to the editing area for the Runbook. See the below screenshot :
Notice that the Workflow Name and the Runbook name has to be the same.
The Workflow editor is pretty cool, you can play with that. This is one way of authoring things up in the Web browser.
Now the Runbooks in Azure Automation are essentially PowerShell workflows and they have few differences from the workflows which we author locally (if you have done that ). The whole workflow is available at the below link:
https://gist.github.com/DexterPOSH/e9dceb72a6f171bd3d97
Basically you copy the whole workflow and paste it in your runbook.
Once you have your workflow authored and tested well, you can Publish it. This way you can use that Runbook inside another runbooks too.
Once the workflow is Published, you can run it by clicking on the "Start" button at the end (this only shows up after you publish it...If you want to run a workflow while authoring it then there is "Test" button see above pic):
Clicking on "Start" will prompt you to supply arguments to the parameters, like below:
After this you can view the Job
Below is an attempt to explain what the workflow does.
the parameters our Runbook will take:
So the Workflow named New-TestVM (Note here that the workflow name and the Runbook name should be the same) will take 4 parameters for specifying the below :
The first step in a Runbook is to authenticate to Azure this is where we use the below code snippet :
In the above code snippet we retrieve all of the Assets we created then we use one of them $cred to authenticate to Azure. After that we select the Subscription against which our workflow will run (& automate stuff). One more thing as we are going to create a new VM we will need to specify the storage account as well.
Now the below code snippet will :
This will take some time and after the machine is provisioned, we have another task at hand of adding the new VM to our domain. This can be achieved by opening a PSSession to the new VM and performing the action.
Below is the code which will open a PSSession to the machine using the LocalCred Asset and perform the domain join passing the DomainCred as argument to the Scriptblock:
Resources:
Use Azure AD to authenticate to Azure
http://azure.microsoft.com/blog/2014/08/27/azure-automation-authenticating-to-azure-using-azure-active-directory/
Azure Automation is a highly scalable workflow engine offering where we can have Runbooks (PowerShell workflows) to automate long running , error prone tasks.
I first saw this in action at one of the sessions by Ravi Sir [PowerShell MVP] at one of the PowerShell Bangalore User Group meet where he used Runbooks to demonstrate really cool stuff.
Note - Azure Automation is still in preview so you might have to sign up for it by navigating to https://account.windowsazure.com/PreviewFeatures
Divided the post into 3 steps:
1. Get the Ground work ready
2. Create the Assets
3. Create a RunBook to deploy the VM (and add it to the domain)
Get the Ground work ready
First of all create an Azure Automation account from the portal (no PowerShell cmdlet for that at the moment). Once done it should show up in the Azure portal like below :
So before we start doing anything else we need a mechanism in place to authenticate to Azure against my subscription. There are two ways to achieve that (links in Resource section) :
- Using Azure Active Directory
- Using Certificate Based Authentication
In my opinion using Azure AD for the authentication is better and easier to explain (am gonna use that for this post) . The below steps of using Azure AD for Authentication are borrowed from the Azure blog found here.
Now Let's head to our Azure Active Directory > Default Directory > Users > Add User.
Then after this you will see a wizard to add a User, Key in the UserName:
Click Next, Be careful and do not enable Multi-Factor auth.
On next screen , Click "Create Temporary password". Make a note of Complete Username and temporary password. We will change it in next step.
Now logout of the browser or open another web browser and navigate to https://manage.windowsazure.com/ .
Now on the Sign-in page , you have to specify the username of the User you created above (that's why we had to make a note of the Username and Password).
After this you will be asked to enter password (key in the temporary password). Log-in and you will be asked to change your password, do that.
Create the Assets
Let's look at what we are trying to do here, We are going to author a PowerShell Workflow which will deploy a VM with Server Technical Preview on Azure and then add the machine to my domain :)But before we get ahead of ourselves we have few important questions to answer here.
- How does my workflow authenticate to Azure to add a new VM to my Cloud service ?
- How to set Local Admin Username and Password for the VM deployed ? (We can hardcode these).
- Once the VM is up how to add it to the domain using another set of Credentials ?
This is where the Assets kick in (no Cmdlets as of now ).
We will have to create 3 Credential assets (stores Username and Password) to tackle this problem at hand. Creating Assets is very straight ahead :
Navigate to Azure Automation > Your Automation Account > Assets > Click on "Add Setting" (at the bottom). After this you will be presented with a page like below :
Select "Add Credential"
Give a Name to the Asset, have kept the Asset name same as the Azure AD User name.
In the next screen give the User name and Password of the User we added in the first step to Azure AD.
The first asset is created, Now I will similarly add 2 mores credentials asset named "DomainDexterPOSH" of a User in my Domain dex.com which has permissions to add a Machine to my domain and another set of credential called "LocalDexterPOSH" to set the local admin username and password for the New VM which our workflow will provision.
Create a RunBook to deploy the VM
Under the Automation account in Azure portal, I can create a new RunBook from Scratch (supports authoring workflows) or create a workflow locally and upload it using the Azure Automation cmdlets. The Azure Automation cmdlets are evolving at the moment , So for this post let's focus more on using the portal to author RunBooks.
Let's get familiarize with how a runbook looks like in the Azure portal.
To create a new runbook in portal you can click "New" and give it a name (see below)
Your runbook name should be unique among your runbooks.
Once done you will see the Runbook sitting in your Azure Automation account.
Click on it and it lands you to the editing area for the Runbook. See the below screenshot :
Notice that the Workflow Name and the Runbook name has to be the same.
The Workflow editor is pretty cool, you can play with that. This is one way of authoring things up in the Web browser.
Now the Runbooks in Azure Automation are essentially PowerShell workflows and they have few differences from the workflows which we author locally (if you have done that ). The whole workflow is available at the below link:
https://gist.github.com/DexterPOSH/e9dceb72a6f171bd3d97
Basically you copy the whole workflow and paste it in your runbook.
Once you have your workflow authored and tested well, you can Publish it. This way you can use that Runbook inside another runbooks too.
Once the workflow is Published, you can run it by clicking on the "Start" button at the end (this only shows up after you publish it...If you want to run a workflow while authoring it then there is "Test" button see above pic):
Clicking on "Start" will prompt you to supply arguments to the parameters, like below:
After this you can view the Job
Note - The workflow is very specific to my test LAB on Azure and you will have to substitute values and tweak the workflow for your own environment.
Below is an attempt to explain what the workflow does.
the parameters our Runbook will take:
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 |
workflow New-TestVM
{ param( [parameter(Mandatory)] [String] $AzureConnectionName, [parameter(Mandatory)] [String] $ServiceName, [parameter(Mandatory)] [String] $VMName, [parameter()] [String] $InstanceSize = "Medium" ) |
So the Workflow named New-TestVM (Note here that the workflow name and the Runbook name should be the same) will take 4 parameters for specifying the below :
- Subscription Name ($AzureConnectionName)
- Cloud Service Name ($ServiceName)
- Name of the new VM to provision ($VMname)
- Instance size of the VM ($InstanceSize which by default is Medium)
The first step in a Runbook is to authenticate to Azure this is where we use the below code snippet :
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 |
$verbosepreference = 'continue'
#Get the Credentials to authenticate agains Azure Write-Verbose -Message "Getting the Credentials" $Cred = Get-AutomationPSCredential -Name "AuthAzure" $LocalCred = Get-AutomationPSCredential -Name "LocalDexterPOSH" $DomainCred = Get-AutomationPSCredential -Name "DomainDexterPOSH" #Add the Account to the Workflow Write-Verbose -Message "Adding the AuthAzure Account to Authenticate" Add-AzureAccount -Credential $Cred #select the Subscription Write-Verbose -Message "Selecting the $AzureConnectionName Subscription" Select-AzureSubscription -SubscriptionName $AzureConnectionName #Set the Storage for the Subscrption Write-Verbose -Message "Setting the Storage Account for the Subscription" Set-AzureSubscription -SubscriptionName $AzureConnectionName -CurrentStorageAccountName "dexterposhstorage" |
In the above code snippet we retrieve all of the Assets we created then we use one of them $cred to authenticate to Azure. After that we select the Subscription against which our workflow will run (& automate stuff). One more thing as we are going to create a new VM we will need to specify the storage account as well.
Now the below code snippet will :
- Get the Image details using Get-AzureVMImage and store the ImageName property in a variable
- Then we derive the Username and Password from the LocalCred which stores one of the Credential Asset
- Finally we specify all the configurations to the cmdlet New-AzureQuickVM (e.g SubnetName, Username, Password, ImageName etc.). Note the user of -WaitForBoot switch will pass on the control to next activity once the VM is up and running.
- After this let's do a checkpoint so that if something fails in our workflow past this point, it should be able to resume from here.
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 |
#Select the most recent Server 2012 R2 Image
Write-Verbose -Message "Getting the Image details" $imagename = Get-AzureVMImage | where-object -filterscript { $_.ImageFamily -eq “Windows Server Technical Preview” } | Sort-Object -Descending -Property PublishedDate | Select-Object -First 1 | select -ExpandProperty ImageName #use the above Image selected to build a new VM and wait for it to Boot $Username = $LocalCred.UserName $Password = $LocalCred.GetNetworkCredential().Password New-AzureQuickVM -Windows -ServiceName $ServiceName -Name $VMName -ImageName $imagename -Password $Password -AdminUsername $Username -SubnetNames "Rest_LAB" -InstanceSize $InstanceSize -WaitForBoot Write-Verbose -Message "The VM is created and booted up now..Doing a checkpoint" #CheckPoint the workflow CheckPoint-WorkFlow Write-Verbose -Message "Reached CheckPoint" |
This will take some time and after the machine is provisioned, we have another task at hand of adding the new VM to our domain. This can be achieved by opening a PSSession to the new VM and performing the action.
Below is the code which will open a PSSession to the machine using the LocalCred Asset and perform the domain join passing the DomainCred as argument to the Scriptblock:
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 |
#Call the Function Connect-VM to import the Certificate and give back the WinRM uri $WinRMURi = Get-AzureWinRMUri -ServiceName $ServiceName -Name $VMName | Select-Object -ExpandProperty AbsoluteUri InlineScript { do { #open a PSSession to the VM $Session = New-PSSession -ConnectionUri $Using:WinRMURi -Credential $Using:LocalCred -Name $using:VMName -SessionOption (New-PSSessionOption -SkipCACheck ) -ErrorAction SilentlyContinue Write-Verbose -Message "Trying to open a PSSession to the VM $VMName " } While (! $Session) #Once the Session is opened, first step is to join the new VM to the domain if ($Session) { Write-Verbose -Message "Found a Session opened to VM $using:VMname. Now will try to add it to the domain" Invoke-command -Session $Session -ArgumentList $Using:DomainCred -ScriptBlock { param($cred) Add-Computer -DomainName "dex.com" -DomainCredential $cred Restart-Computer -Force } } } } #Workflow end |
Resources:
Use Azure AD to authenticate to Azure
http://azure.microsoft.com/blog/2014/08/27/azure-automation-authenticating-to-azure-using-azure-active-directory/