Import new (or update existing) PowerShell module (including its dependencies!) into Azure Automation Account using PowerShell

I work as System Administrator for more than 15 years now and I love to make my life easier by automating work & personal stuff via PowerShell (even silly things like food recipes list generation).
I bet you would agree that importing PowerShell modules to Azure Automation Account using GUI is super annoying.
Moreover, if such a module has some dependencies, you have to import them one by one beforehand and often in the correct order too. Not to mention that such modules can have their own dependencies 😱.
And the same pain goes for module updating.
These were the reasons why I created the PowerShell function New-AzureAutomationModule (part of my AzureResourceStuff module) which do all this heavy lifting for you 👍.
How does it work?
There is a (very simplified) diagram that can help you to understand how the function works

Let's say you want to import the module Microsoft.Graph.Groups. Therefore we will use the following command:
New-AzureAutomationModule -moduleName "Microsoft.Graph.Groups" -runtimeVersion "5.1" -resourceGroupName "<resourceGroupName>" -automationAccountName "<automationAccountName>"
We haven't specified the module version therefore the newest supported one will be imported. Right now it is 2.11.1.
Function New-AzureAutomationModule leverages built-in command Find-Module to find all dependencies of the Microsoft.Graph.Groups module directly from https://www.powershellgallery.com/. In this particular case, there is only one dependency and that is Microsoft.Graph.Authentication module in version 2.11.1, which will be installed automatically beforehand.

Because Microsoft.Graph.Authentication doesn't have any dependencies, no other modules will be imported.
Function therefore checks whether there is already an imported module Microsoft.Graph.Authentication in the version 2.11.1 and imports/updates it in case it isn't. The same goes for module Microsoft.Graph.Groups.
moduleVersion parameter, the newest supported version will be imported!What "supported" version mean?
PSH modules should contain in their manifest what PSH version (runtime) they support.
So when I am talking about "supported" version. I mean version of the module that officially supports given runtime (by default 5.1).
5.1, 7.2), New-AzureAutomationModule searches only for modules that support given runtime 👍7.1 is shown in Runbook GUI, but official commands don't support it, nor do I.Unfortunately, there can be a situation where the module author forgot to update the manifest file. Hence even though requires PSH Core (7.x) it doesn't say it. This breaks my function because if no specific version is specified, it searches for the newest one that supports a given runtime.
Like PnP.PowerShell module in versions 2.1.1 and 2.2.0. Those modules require PSH Core, but it is required in the manifest since 2.3.0 version.

To avoid this issue, there is a function parameter overridePSGalleryModuleVersion which by default forces the use of 1.12.0 module PnP.PowerShell version for 5.1 runtime, so in the case of PnP.PowerShell , you don't have to worry about it 👍.
But there can be other modules with the same problem too, so don't forget about this parameter 🙂.
How to use it
Prepare the environment
Install AzureResourceStuff module
Install-Module AzureResourceStuff
Connect to your Azure subscription where Automation Account is placed
Connect-AzAccount -Tenant "<contoso.onmicrosoft.com>" -SubscriptionName "<NameOfYourAutomationSubscription>"
Import/Update module to the newest supported version
# without specifying moduleVersion parameter, newest possible will be imported
New-AzureAutomationModule -resourceGroupName '<resourceGroupName>' -automationAccountName '<automationAccountName>' -moduleName Microsoft.Graph.Groups -runtimeVersion 5.1
And you should see something like this

Import/Update module to a specific version
New-AzureAutomationModule -resourceGroupName '<resourceGroupName>' -automationAccountName '<automationAccountName>' -moduleName Microsoft.Graph.Groups -moduleVersion 2.11.1 -runtimeVersion 5.1
Import fails, what can I do?
If you get the error "New-AzureAutomationModule : Import failed"

Search for the imported module in Azure Portal >> Automation Account >> Modules >> <nameOfTheModule>. And check its details.



In this particular case, the error says that the imported module isn't supported in the used 5.1 runtime.
Bonus: Analyze Runbook code dependencies to import just the right ones 😎
OK, so now you have the right tool to import your modules to the Azure Automation Account, but what about getting the list of the modules your Runbook code depends on? Don't worry I have you covered.
Let's meet the function Get-CodeDependency (part of DependencySearch module) which I will talk about in more detail another time.
This function allows you to analyze a given code to get all its dependencies (modules, pssnapins, admin privileges,...).
How to get the code dependencies
- Install DependencySearch module
Install-Module DependencySearch
Save your runbook code locally to the
ps1fileLet's say this is how the Runbook looks like

And I will save it to
C:\temp\runbookcode.ps1
Get the code dependencies using
Get-CodeDependencyfunction
Get-CodeDependency -scriptPath C:\temp\runbookcode.ps1 -unknownDependencyAsObject -Verbose
And you should see something like this

Which means that my example code requires three modules
Microsoft.Graph.Authentication,Microsoft.Graph.Users,Microsoft.Graph.Identity.DirectoryManagementwhich I can easily import to my Azure Automation Account using the following command
$resourceGroupName = '<resourceGroupName>'
$automationAccountName = '<automationAccountName>'
'Microsoft.Graph.Authentication', 'Microsoft.Graph.Users', 'Microsoft.Graph.Identity.DirectoryManagement' | % {
New-AzureAutomationModule -moduleName $_ -resourceGroupName $resourceGroupName -automationAccountName $automationAccountName
}
Summary
Now when you can use the function New-AzureAutomationModule (part of the AzureResourceStuff module), you should be no longer afraid of importing or updating any module into your Azure Automation Account anymore.
And at the same time using the function Get-CodeDependency (part of the DependencySearch module) you know, which modules your Runbooks need.
😎





