top of page

Browse PowerShell Azure VM SKUs and Marketplace Images with Get-AzVMSku

  • Writer: Christoffer Windahl Madsen
    Christoffer Windahl Madsen
  • Jun 29
  • 12 min read

Hi all - It has been such a long time since my last post - Apologies, I have been very busy with life the past year but I am now finally ready to once again embark on an exciting topic!


Today we will be looking into the world of the PowerShell module "Get-AzVMSku" The first and only module that allows you to see Microsoft Azure Virtual Machine Image SKUs and offerings directly from your terminal.


Now... When do you need this kind-of information ? Well - Everytime you need to deploy an Azure Virtual Machine from ANY vendor available from the Azure Market place using Infrastructure-as-code regardless of language.


Topics in chronological order of this post:


Chapter 1 - Getting started with the module

First of - The module must be run using PowerShell Core, because the underlying dependencies cannot run using native PowerShell.


Install PowerShell to be used to get Azure VM SKUs

To get help on how-to install PowerShell Core (For any operating-sytem), please visit => Microsoft official documentation on PSCore


With that installed - Simply open the terminal, and make sure that indeed it is PowerShell Core running and NOT 5.1. Also - If your running from a Linux or MacOS operating-system, you simly open the terminal and type "pwsh" To execute PowerShell Core (Make sure to have the executable in your PATH environmental variable)


PSVersion table of PS Core
Builtin PowerShell version variable

Install the module directly via PSGallery - Then verify that the module is installed:

Install module Get-AzVMSku
Default PowerShell install command

There is a full helper-file attached to the module, which we wont go over in this blog, but it contains all possible parameters that can be set + Plenty of examples. To see this in its entirety run:

Get-AzVmSku helper-file
Default PowerShell helper system on module

With the module successfully installed we need to make sure we have an active Azure context, otherwise the module will throw an error asking for an active Azure context. Use command "Connect-AzAccount" Or its alias "Login-AzAccount" To make sure a valid context is present in the terminal.


Now - Finishing this chapter the module offers 2 different show-commands to help us understand:


  1. What locations we can parse to the "Location" Parameter - We CANT simply use the command "Get-AzLocation" Because the underlying API's used to retrieve VM information does NOT support all regions.

  2. Azure Virtual machine family information - Meaning the module can spit out the family-names and descriptions about them directly from Microsoft.


If we run the switch "ShowLocations" We will get: (Requires Az context)

Get-AzVMSku to show allowed locations
Get-AzVMSku using show-command ShowLocations

To engage the switch 'ShowLocations" You must be logged in to a valid Azure context as described a little above, otherwise the module will throw an error.


And finally, lets see the last show-command for 'ShowVMCategories"

Get-AzVMSku to show available VM family-categories in Azure
Get-AzVMSku show-command ShowVMCategories

The 'ShowLocations' Switch will always tell us exactly what locations are allowed by the module, please remember to always use the names from column 'Name to use' Or the underlying Microsoft API will throw an error. For the other show-command, we can directly use information about the different family-names to search for only specific VMs when running the module in mode of retrieving VM image information. We have a filter parameter named 'VMPattern' Available which will be show-cased in this image



Now with the introduction done, lets dive into how to actually retrieve VM image.


Chapter 2 - Using Get-AzVmSku interactively


The only required parameter is "Location" - We will parse "westeurope" What will happen next is that since we do not parse any filter information, the module will retrieve every single possible Azure Market place publishers / vendors for Virtual machine images, which at the time of writing is 2366


Get-AzVMSku used with no filters
Get-AzVMSku run with no filters, showing all publishers

Whats important to note is because we do not provide ANY parameters to help search for something specific, the module is forced to interactively show you what is essentially a catalogue of all possible options available - If we then select one, lets say 1 for "netfoundryinc"

Get-AzVMSku on a specific vendor showing versions available for an image
Get-AzVmSku asking for a specific version of SKU

We end up being asked about what specific version we would like. Now, what we essentially have here is a tool to dynamically look through every single possible vendor, their SKUs, offerings and their respective versions - Essentially giving us a cool and new way of peaking into the "belly of the beast" When it comes to the Azure Image Market place for Virtual machines.


The above example did only have 1 specific SKU that can be chosen from the vendor "netfoundryinc" Which makes the modul simply auto-select it and forwarding to the selection of version which as it can be seen above, have multiple options. After selecting a wanted version, say 1 again - The module will output:

Get-AzVMSku partial return information
Get-AzVMSku return information, partially

The return-object can conviently be parsed to a variable to use the return-data for any data-analysis later OR to parse any potential agreement stored in the return to the PowerShell Cmdlet "Set-AzVMSku" Which is a function that ships with the module-package and can assist you by seemingsly accepting the terms of any Azure Virtual Machine image which is required before it can be used in a deployment to Azure. We will cover this and much more in Chapter 3C.


Now... With the base understanding of how the module functions - Lets dive deeper and look at how we can use filters to make the search for specific vendors we might be interested in as looking through over 2300 vendors at once can be very overwhelming.


Chapter 3 - Deep-diving into the modules capabilities

While the above chapter focused on the overall browsing experience that the module can offer - Seeing its possible to go through every single option in the Azure Market Place we can on the contrary also focus on only specific vendors.


Chapter 3 A - Using the module with filters

Let's say we are very interested in Networking vendors, maybe even more specifically Palo-Alto. How can we try to filter through and see what they offer of Images? We cant even be sure that the vendor-name is actually Palo-Alto, so what do we do ?


Using filters - PublisherName & OfferName

Well - Lets see what happens if we use parameter "PublisherName" Which can accept parts of a vendor-name as we wont always know the EXACT name the vendor might have in Azure - The module will then do different wildcard searches and return a specific list based on the name we provided:

Get-AzVMSku using PublisherName filter with 'palo'
Get-AzVMSku using PublisherName 'palo'

Nice - Seems the 'palo' Keyword hit spot-on as only 1 Publisher / vendor match is found. As seen the actual name for the provider in Azure is called 'paloaltonetworks' Which the module is helping us find - Moreover we can now explore the concrete offerings from the vendor.


Going deeper in the example, lets say we want to look at 'panorama' So we select that 5 from the menu:

Get-AzVMSku on panorama showing all available versions for image
Get-AzVMSku looking at vendor paloaltonetworks

Notice that we have to "cut" The output because the possible versions for Palo-alto Panorama in the Azure Market place is 38 versions long... We can actually filter this even more, so that the output and choices becomes more bearable - Lets take a step back by running the command again BUT adding parameters 'OfferName' & 'Top10NewestVersions'


The 'OfferName' Parameter is a string-filter just like 'PublisherName' And will use wild-card searches. Since we know from the above search, the offer-name 'panorama' Should find the exact product we are looking for - If we combine that with switch Top10NewestVersions we essentially tell the module: Give me this specific offer, but ONLY show me the 10 newest versions and omit the rest:

Get-AzVMSku on image panorama but only top 10 newest versions
Get-AzVMSku with OfferName filter & version switch

Now both the list of versions is decreased to the 10 newest but also the module skipped all the way to directly decide on a version because we entered more filter-information. And this gives a lot of flexibility to us - We can use the module from searching through the entire vendor-list, then recall to look more specifically. Basically we can start looking very broadly because we do not know exact names in the Azure Market place, then quickly "zoom in" On what we want to find.


Looking at VM information returned from the module

Speaking of "zoom-in" More than filters for Publisher and Offer, we can look at filtering specific VM-sizes and their quotas which comes in the output when running the module to retrieve Image information.


As mentioned in the introduction we can use the parameter 'VMPattern' To specify only VM sizes / families which we want to see in the output, if we omit the filter-name, every single possible VM-size available in the location specified will be returned.


So, how does this VM output look? And what can it generally tell us?

Get-AzVMSku information about Virtual machine sizes and quotas
Get-AzVMSku showing VM-size information & concrete subscription quotas

If we dive a little deeper and take a look at the 'VMSizes' Propertery - Its a simple array of PSCustomObject

Get-AzVMSku return of a single element of VM sizes
Get-AzVMSku with specific element of the property VMSize

So the module shows important details of each specific Azure VM-size which we can use to determine what VM matches our infrastructure requirements. Whats important to note here is that in Azure we work with whats called 'quotas' Which is Microsofts way of saying 'your specific Azure Subscription has x amount of CPU cores of each Virtual machine-family available'. This information about quotas is extremely important when planning our sizes of VMs, because just looking at sizes and deciding has the risk of Azure simply denying us the deployment due to missing quotas...


To get answers about quotas, we have another property available from the return-output of the module called 'VMQuotas'

Get-AzVMSku showing return og VM quotas
Get-AzVMSKU return property VMQuotas

As seen on the screenshot above a lot of information is derived from the module regarding VM-quotas in Azure. The first and most important information bit is the nested property 'vCPUsAvailable' Which tells us whether we have ANY available CPU-cores for this VM-family on the current Azure Subscription, if the number is 0, we can ask for a quota increase directly in Azure.


Furthermore, we can see the following nested properties:

  1. ArchitectureDescription => Same description as can be derived from show-command 'ShowVMCategories'

  2. vCPUPercentUsage => A calculation of how many %. of the total cores available for a given Azure Virtual machine family is actively in use on the Azure Subscription

  3. VMSizeDistribution => The module calculates how many of each VM size of a given family can be created BEFORE reaching the quota core limit on the VM family as a whole


All the above information from this section of the blog-post describes retrieving ALL possible Azure Virtual machine information, but what if you want to filter on it? Or even completely ignore VM data ?


As stated earlier, we have the parameter 'VMPattern' Available which works on the same wildcard strategy as defined in Chapter 3 A which we can use to control what Virtual machine-sizes we want from the module.


Say we ONLY want VM-sizes containing D (General purpose VM's):

Get-AzVMSku on VM sizes using the parameter VM Pattern
Get-AzVMSku using parameter VMPattern

Same - If we take a look at the nested property 'VMQuotas' ONLY D related families are present:

Get-AzVMSku showing VM quotas after parameter VMPattern is used
Get-AzVMSku showing VMQuotas with the parameter VMPattern

As a final note on this chapter - We can also entirely skip the module working with anything VMsize / VMquota related by using parameter 'NoVMInformation' Which will DRASTICALLY decrease the module time to execute.


Chapter 3 B - Automation scenarios

As already show-cased the module is more than capable of "browsing" Through the different vendors available in the Azure Market place, but what about scenarios where something like a pipeline is to execute the module? In this scenario, we cannot rely on interactively responding to whatever the module needs an answer to, as this will break automatic flows.


To completely avoid any interaction we have different parameters that can assist us:

  1. PublisherName => Just like in chapter 2, we must filter on vendors

  2. OfferName => Also have to filter on vendor-offers

  3. NewestSkus => Tell the module to take the newest possible SKU from a specific Offer

  4. NewestSkusVersions => Tell the module to take the newest possible version of a SKU

  5. NoInteractive => Force the module to throw an error the moment an interaction is required on some specific data being processed

    1. This switch is essentially designed so that a controlled error can be thrown before something like a pipeline simply fails due to the module waiting for an interactive response


Lets built on the examples shown in chapter 3 A - But now we add functionality to proof it can run and simply complete computation and output the information we need in order to actually built an Azure VM

Get-AzVMSKU using switches to force the module not to ask for input by the user for automation scenarios
Get-AzVMSku with no interaction, useful in Automation

Whats important to note is the fact we need to know both a 'PublisherName' And 'OfferName' That is unique enough to only match 1 element each, otherwise the switch 'NoInteractive' Will force the module to fail. Also - The switch itself is not actually needed and is only there to ENFORCE the module NOT to ask for choices in case the information provided isn't unique enough. If we remove the flag from the example above, the module will still behave exactly the same and simply output the result directly, but ONLY because our information provided is unique-enough.


Say we change the 'OfferName' Parameter from 'panorama' To something like 'flex' Which contains more than 1 result, how will the error look ?

Get-AzVMSku error shown by parameter NoInteractive
Get-AzVMSku error show-case due to -NoInteractive is used

Notice how the error specifies which specific filter that causes the issue of requring user-input to continue which in this case is 'Image Offer' Which we control via the filter-name of 'OfferName' If we remove the switch 'NoInteractive' We can see exactly what the module will ask about, essentially showing us how we can make the filter more unique to be ready for Automation:

Get-AzVMSku showing the parameter OfferName which filters on 'flex'
Get-AzVMSku check what specifically caused -NoInteractive error

Arh, so as we can see - The error stemmed from the fact that the 'OfferName' Pattern of 'flex' Results in 2 possible options, hence why the module will always fail when using the switch 'NoInteractive' This means for this specific scenario, we need to make our filter even more unique, lets pick 'airs' And see if it will run without any interaction now:

Get-AzVMSku used in a context of not asking for user-input as enough information is parsed for the module to automatically select the newest SKU and version
Get-AzVMSku with no interaction, useful in Automation

Yep - That did it, and that specific module-call can be directly used in any Automation-tooling that supports PowerShell Core. As a final note for this chapter, the parameters 'NewestSKUs' And 'NewestSKUsVersions' Will always be needed in these scenarios, otherwise most SKUs and version's will contain more than 1 option, leading to errors, but with these switches set, the module will always auto-select the newest of each.


Notice how the output from the screenshot says 'Image agreement: True' - This basically tells us that this specific image has a legal-agreement bound to it, which MUST be accepted before an actual deployment with set image can take place - If we do not accept the terms first, any deployment using the image will fail. Luckily the module ships with a simple builtin function to handle exactly that called 'Set-AzVMSku' Which we will cover now in the next chapter.


Chapter 3 C - Accepting Azure Market place terms

So far we have only talked about 'Get-AzVMSku' But this function has a brother called 'Set-AzVMSku' Which can help us accept Azure Market place terms which are always required in order to deploy any image (that has terms) on any Azure Virtual machine... So, how do we do that?


Simple - Just pipe the module-call from Get-AzVMSku directly to Set like so:

Set-AzVMSku accepting Azure market-place terms for an Azure image
Set-AzVMSku showing market-place terms for a Palo-Alto image

The 'Set-AzVMSku' Module will ALWAYS post ALL legal terms present for ANY Azure Image with active terms that must be accepted - It is highly adviced to follow each policy link to read what is being accepted BEFORE proceeding.


If we press "y" To the above, we get:

Set-AzVMSku accepting agreement using user-input
Set-AzVMSku accepting agreement

The image can now be deployed to Azure - In case of Automation scenarios as talked about in Chapter 3 B, we can use the parameter "Force" To auto-accept any VM Image agreement.


As a final note on this chapter, incase a variable is defined to capture the output of 'Get-AzVMSku' If used directly with a pipe to 'Set-AzVMSku' We must use the parameter 'Passthru' To capture the return AFTER the agreement as been accepted, like so:

Set-AzVMSku accepting market-place terms using parameter Passthru

Chapter 4 - Conclusion

This module is the solution to any IT professionals nightmare of having to otherwise use Microsofts default method of retrieving all information required to deploy ANY Azure Virtual machine image contained in the Azure Market place. Before the development of this module, you risked being stuck having a hard-time figuring out exactly what vendor names are, what they offer and all information contained beneath that.

We now have a central solution that contains everything we need to always know what to exactly type in the infrastructure-as-code definitions for any given image that we want to deploy to an Azure Virtual machine. Furthermore, the module also retrieves and calculates our current Azure Subscription quotas which we need to know about before even attempting to deploy anything in the first place. Finally, with the addition of the helper-function 'Set-AzVMSku' We can seemingsly accept any Image terms directly in a one-liner making sure ALL perquisites are in place before we go from finding our next Azure image and to having it living directly on an Azure Virtual machine.


It has never been easier to gather everything required to both plan, design and deploy Azure Virtual machines using infrastructure-as-code and the only thing we need to get started is PowerShell core, an active Azure Subscription and the module-package 'Get-AzVMSku' Which is directly accessible via Microsofts public PowerShell gallery repository but also on Github.


Thank you so much for reading along and again - I expect this wont be the only post coming concerning this module and its capabilities.


If you're interested in Terraform, PowerShell or Automation in general, dont forget to browse the blog as it contains many different posts about many cool topics.

Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page