For Azure Automation

Windows Update Runbook

For Azure Automation

Windows Update Runbook

I am aware that there is a better way to manage your windows updates, Update Management, but this way is more fun and challenging.

The purpose of this post is not solely a “how to automate windows updates”, but in general a “how to automate jobs using runbooks”.

First of all, kudos to Marc Schweigert who inspired me with his runbook from  

To follow this guide you will have to have created in advance 3 simple resources. An automation account, a virtual machine and a keyvault. You will also need to download everything from the github link above.

Keyvault will be demonstrated soon in another guide of mine.

I will be brief because there is a lot ground to be covered, so buckle up !

You have to install the required modules for DSC (Desired State Configuration). Navigate to your automation account resource Modules and click on browse gallery.

Search for PackageManagementProviderResource, click on Import and OK.

After some seconds the module’s status will change from “extracting” to “available”.

Now navigate again to your automation account, DSC configuration and click on add a configuration.

Upload InstallPSWindowsUpdateAndTaskRunner.ps1 from your downloaded items.

Click on it and then on compile. Of course accept and wait for the compilation to be completed.

Let’s go on the DSC nodes, that the above configuration will be applied. Add your VM and check that is running. Enter the below configuration and press OK.

Keep pressing refresh until you see that your VM is compliant.

You can remotely access your VM to be sure that Task Runner and PSWindows update have been added to the Powershell location.


Again on the automation account blade, select credentials and add your credentials for the VM. I used local admninistrator’s credentials.

Prepare your VM for PowerShell remoting via WinRM.

Head to your VM’s network security group and add an inbound security rule. Add the configuration below.

Connect through RDP and create an inbound windows firewall rule for port 5986 as well.


Create a self signed certificate the safe way.

Log in with RDP and open powershell with elevated privileges on your VM.

New-SelfSignedCertificate -DnsName <your server dns name> -CertStoreLocation Cert:\LocalMachine\My

After the creation, copy the certificate thumbprint.

Next, open cmd as administrator.

winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname=”<your server dns name>”; CertificateThumbprint=”<paste your certificate’s thumbprint>”}


Disclaimer: Follow these instructions in a test environment. While experimenting with multiple scripts, my VM was unable to launch.

Create a self signed certificate the hard way.

Open powershell and run:

$certificateName = “enter a name”

$thumbprint = (New-SelfSignedCertificate -DnsName $certificateName -CertStoreLocation Cert:\CurrentUser\My -KeySpec KeyExchange).Thumbprint

$cert = (Get-ChildItem -Path cert:\CurrentUser\My\$thumbprint)

$password = Read-Host -Prompt “enter a password” -AsSecureString

Export-PfxCertificate -Cert $cert -FilePath “.\$certificateName.pfx” -Password $password

Log in your Azure account from powershell.


Upload your certificate to your Keyvault. It needs transformation firstly.

$fileName = “C:\your certificate’s path\your certificate’s name.pfx”
$fileContentBytes = Get-Content $fileName -Encoding Byte
$fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes)

$jsonObject = @”
“data”: “$filecontentencoded”,
“dataType” :”pfx”,
“password”: “enter your certificate’s password”

$jsonObjectBytes = [System.Text.Encoding]::UTF8.GetBytes($jsonObject)
$jsonEncoded = [System.Convert]::ToBase64String($jsonObjectBytes)

$secret = ConvertTo-SecureString -String $jsonEncoded -AsPlainText –Force
Set-AzureKeyVaultSecret -VaultName “your vault’s name” -Name “desired certificate name on vault” -SecretValue $secret

The creation details, will provide you with a URL. Keep it !

If you miss your certificate’s ID, Get-AzureKeyVaultSecret -VaultName “your vault’s name” -Name “your certificate’s name”

Last step is to push the certificate on your VM without remotely accessing it. Use this script.

$resourceGroup = “resource group name”
$vm = Get-AzureRmVM -ResourceGroupName $resourceGroup -Name [VM name]
$vaultId = “/subscriptions/[subscription guid]/resourceGroups/$resourceGroup/providers/Microsoft.KeyVault/vaults/[vault name]”
$certStore = “My”
$certUrl = “KeyVault secret URL w/ version id”
Add-AzureRmVMSecret -VM $vm -SourceVaultId $vaultId -CertificateStore $certStore -CertificateUrl $certUrl

Update-AzureRmVM -ResourceGroupName $resourceGroup -VM $vm



Enable WinRM

Open powershell with elevated privileges and run:

Enable-PSRemoting -Force

Test your connectivity before proceeding further.

$so = New-PsSessionOption –SkipCACheck -SkipCNCheck

Enter-PSSession -ComputerName <your server dns name> -Credential <your local administrator username> -UseSSL -SessionOption $so

You will be prompt for password, type it and continue. Now you should be connected.

Next, on the automation account select runbook and add a runbook. Upload InvokeWindowsUpdateAzureRmVM.ps1 from your downloaded files.

Select your runbook and click on Edit. Now hit publish

Your runbook is published and you can run a job. Hit start and type



PSCREDENTIALNAME: Enter the credential we created on the automation account.

It’s about time to enjoy your runbook running. Click on output and watch it shine.


Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: