Developing Azure Automation Runbooks–using correct modules

When developing Runbooks for Azure Automation I noticed that it’s important to use the same (Global) PowerShell Module versions as available as Asset in Azure Automation. But let’s first talk about Azure  Automation Assets a bit more.

Automation Assets

Automation Assets are various resources that are globally available to be used in or associated with a Runbook. Assets include Schedules, Modules, Certificates, Connections, Variables and Credentials.

image_thumb

For more information about the Automation Assets check the following Automation Documentation page: https://azure.microsoft.com/en-us/documentation/services/automation/

Modules

If look at the Modules Asset we see some default available Global modules and some Integration Modules. The Global Modules have been updated automatically by the Automation Service.
You cannot remove Global Modules.

image_thumb[1]

If we retrieve some more details from one of the Global Modules (example. AzureRM.Storage) we get the following info.

image_thumb[5]

So why would you care about this info?

If you are like me, you always want to use the latest and greatest tools as soon as they are available. This is also true for my PowerShell Modules. I regularly check the PowerShell Gallery for the latest available PowerShell Modules.

Let’s check what the latest available version of the AzureRM.Storage Module is on the PowerShell Gallery.

Code Snippet

  1. Find-Module -name AzureRM.Storage

Result:
image

 

So what does this tell us? On the PowerShell Gallery there is a newer version of the AzureRM.Storage Module available. If you use this latest version in one of the Azure Automation Runbooks you are developing it could fail when using the Global AzureRM.Storage module on Azure Automation.

That’s why I was looking for a way to retrieve the Global Module versions being used in Azure Automation and download those modules from the PowerShell Gallery when developing and testing my Runbooks locally.

Let see the script in Action first.

AASaveModules

Here is the script I used to download the same Global Modules used in Azure Automation locally.  After Saving you still need to install these modules in your PSModulePath Environment variable folders.

Code Snippet

  1. #requires -Version 3 -Modules PowerShellGet

  2.  

  3. # ---------------------------------------------------

  4. # Script: C:\Users\stefstr\OneDrive - Microsoft\Scripts\PS\Azure\Automation\ShowAzureAutomationModulesInfo.ps1

  5. # Version: 0.1

  6. # Author: Stefan Stranger

  7. # Date: 06/15/2016 09:15:31

  8. # Description: Show Azure Automation Module Info and Download the same Modules as used in Azure Automation

  9. # Comments:

  10. # Changes:  

  11. # Disclaimer:

  12. # This example is provided "AS IS" with no warranty expressed or implied. Run at your own risk.

  13. # **Always test in your lab first**  Do this at your own risk!!

  14. # The author will not be held responsible for any damage you incur when making these changes!

  15. # ---------------------------------------------------

  16.  

  17. #Login to Azure

  18. Add-AzureRmAccount

  19. #Select Azure Subscription

  20. $subscription =

  21. (Get-AzureRmSubscription |

  22.     Out-GridView `

  23.     -Title 'Select an Azure Subscription ...' `

  24. -PassThru)

  25. Set-AzureRmContext -SubscriptionId $subscription.subscriptionId -TenantId $subscription.TenantID

  26. #Select ResourceGroup

  27. $ResourceGroup = Get-AzureRmResourceGroup | Out-GridView -PassThru

  28.  

  29. #Select AutomationAccount

  30. $AutomationAccountName = Get-AzureRmAutomationAccount -ResourceGroupName $ResourceGroup.ResourceGroupName | Out-GridView -PassThru

  31. #Retrieve all used Azure Modules within Azure Automation

  32. $ModulesOutput = Get-AzureRmAutomationModule -ResourceGroupName $ResourceGroup.ResourceGroupName -AutomationAccountName $AutomationAccountName.AutomationAccountName | Where-Object -FilterScript {

  33. $_.Name -like '*Azure*'

  34. }

  35.  

  36. $endresult = @()

  37. foreach ($Module in $ModulesOutput)

  38. {

  39.      $Module = Get-AzureRmAutomationModule -Name $Module.Name -ResourceGroupName $ResourceGroup.ResourceGroupName -AutomationAccountName $AutomationAccountName.AutomationAccountName

  40.      $obj = New-Object -TypeName PSObject

  41.      $obj | Add-Member -MemberType NoteProperty -Name ModuleName -Value $($Module.name)

  42.      $obj | Add-Member -MemberType NoteProperty -Name IsGlobal -Value $($Module.IsGlobal)

  43.      $obj | Add-Member -MemberType NoteProperty -Name Version -Value $($Module.version)     

  44.      $obj | Add-Member -MemberType NoteProperty -Name SizeInBytes -Value $($Module.SizeInBytes)

  45.      $obj | Add-Member -MemberType NoteProperty -Name CreationTime -Value $($Module.CreationTime)

  46.      $obj | Add-Member -MemberType NoteProperty -Name LastModifiedTime -Value $($Module.LastModifiedTime)

  47.      $obj = $obj | Add-Member -MemberType NoteProperty -Name ProvisioningState -Value $($Module.ProvisioningState) -PassThru

  48.      $endresult = $endresult + $obj

  49. }

  50.  

  51. $endresult

  52.  

  53. #Check if modules can downloaded from PSGallery

  54. $psgallery = @()

  55. foreach ($azuremodule in $endresult)

  56. {

  57.     $psgallerymodule = Find-Module -Name $azuremodule.ModuleName -MaximumVersion $azuremodule.version -ErrorAction SilentlyContinue

  58.     $obj = New-Object -TypeName PSObject

  59.     $obj | Add-Member -MemberType NoteProperty -Name Version -Value $($psgallerymodule.Version)

  60.     $obj | Add-Member -MemberType NoteProperty -Name Name -Value $($psgallerymodule.Name)

  61.     $obj | Add-Member -MemberType NoteProperty -Name Type -Value $($psgallerymodule.Type)

  62.     $obj | Add-Member -MemberType NoteProperty -Name Repository -Value $($psgallerymodule.Repository)

  63.     $obj = $obj | Add-Member -MemberType NoteProperty -Name Description -Value $($psgallerymodule.Description) -PassThru

  64.     $psgallery = $psgallery + $obj

  65. }

  66.  

  67. #Select Modules you want to download from PSGallery

  68. $psgallery |

  69. Out-GridView -Title 'Select Module to save' -OutputMode Multiple |

  70. ForEach-Object -Process {

  71. Save-Module -Name $($_.name) -MaximumVersion $($_.version)  -Path $env:TEMP

  72. }

Hope this helps.