I stumbled upon this great post by Ian Farr the other day about Automagically Keep the Azure PowerShell Module Up-To-Date. In this post Ian tells us how keeps his help and azure module up to date by starting a background job from his profile script. In the end, Ian mentions that he recently added the command Update-AzureRM to his job and that it updates the AzureRM modules each time even if he already has the latest version.
I've run the Update-AzureRM command a few times and noticed the same frustrating fact, it takes almost 40 minutes to run even if all my modules are up to date!
My general solution to this has been to run Update-Module -Name Azure* and just update all modules with a name beginning with Azure (this also keeps AzureAutomationAuthoringToolkit up to date). But this time I got curious and thought ‘Wonder if I can speed things up with Update-AzureRM?'.
Examining the command
The first thing I do is examining the command using Get-Command like this:
Get-Command -Name Update-AzureRM
This tells me that the command is actually a function that is part of the module AzureRM, let's have a look at that module:
Get-Module -Name AzureRM | Select-Object -Property Name, Path
Turns out this is a script module written in PowerShell so I might be able to do something about it.
Opening up the function I can see that Update-AzureRM is changing the repository policy, calling Install-ModuleWithVersionCheck once for each module that should be updated and then sets my repository policy back to whatever it was before. This leads me to believe that the problem of updating lies within Install-ModuleWithVersionCheck which happens to reside in the same psm1 file.
This function will search for the specified module on my computer, if it is installed it will set the variable $ModuleAction to “updated” and run Install-Module using the parameter -Force, if it is not already available in my computer it will set $ModuleAction to “installed” and run Install-Module without using -Force.
I think I've found the problem here, let's look up the parameter Force in the help for Install-Module:
Get-Help -Name Install-Module -Parameter Force
It seems like the Force parameter is only necessary if I want to overwrite a module of the same name and version. My own testing with the parameter also shows that using -Force will override the confirmation message when InstallationPolicy for a repository is set to Untrusted (as reported on UserVoice). This leads me to conclude that removing -Force from install module would prevent it from downloading and reinstalling any module that already is up to date. I only want to forcefully download and install a module if I use the parameter -Force on Update-AzureRM.
To change the behavior I first add a Force parameter to Install-ModuleWithVersionCheck and calls it from Update-AzureRM using -Force:$Force. This will pass thru the Force parameter to Install-ModuleWithVersionCheck.
The second step is to do the same thing for Install-Module within Install-ModuleWithVersionCheck.
To make sure it works as intended I run the command Update-AzureRm and now it takes 2 minutes instead of 38. And all I had to do was a small change on five rows! Once I'm at it I also added a help description for -Force on Update-AzureRM.
Since the AzureRm PowerShell module is open source and published on GitHub I submitted an issue describing the problem with forced updates and my suggested change of the code. Hopefully you will all have this new functionality in the next release.
In the next post I will describe the process of submitting suggested changes to an open source project.