Azure Virtual Machine creation process Blog Article
** Note ** Be careful when spinning up resources whether they are virtual machine, disk, network, etc. All of these consume some sort of cost and you should be aware of what the costs is and if you will overrun any budgetary concerns. Later in this series I will cover a way to monitor and manage your costs both in the portal for Azure as well as PowerShell. Some Azure Subscriptions are still outside of these reporting features so you may not be able to perform these tasks quite yet.

Now that we have that out of the way, let’s dive into PowerShell for work with Virtual Machines in Azure. The command base is ‘azvm’ and we can use this to fin that there are a total of 124 cmdlets.
So where do we start? ‘Get’ cmdlets. These cmdlets will help us explore what is here and what we have at our finger tips … a bonus is that there are only 30 cmdlets to start with.
Get-AzVmssDiskEncryptionStatus Get-AzVmssVMDiskEncryptionStatus Get-AzVM Get-AzVMAccessExtension Get-AzVMADDomainExtension Get-AzVMAEMExtension Get-AzVMBootDiagnosticsData Get-AzVMChefExtension Get-AzVMCustomScriptExtension Get-AzVMDiagnosticsExtension Get-AzVMDiskEncryptionStatus Get-AzVMDscExtension Get-AzVMDscExtensionStatus Get-AzVMExtension Get-AzVMExtensionImage Get-AzVMExtensionImageType Get-AzVMImage Get-AzVMImageOffer Get-AzVMImagePublisher Get-AzVMImageSku Get-AzVMRunCommandDocument Get-AzVMSize Get-AzVMSqlServerExtension Get-AzVmss Get-AzVmssDiskEncryption Get-AzVmssRollingUpgrade Get-AzVmssSku Get-AzVmssVM Get-AzVmssVMDiskEncryption Get-AzVMUsage
One of the core cmdlets here is Get-AzVm which will list any virtual machines that we have running. One this to keep in mind, like a lot of other AZ cmdlets, the Get-AzVM cmdlet also operates or can only retrieve information from its’ current Az Subscription. So if, for example, you have more than one Azure subscription, you would need to change that context to see VMs in each subscription.
See Azure Adventures 002 for how to change the Subscription you are working on – Azure Adventures 002 blog post
Now, if we want to see if any VMs in the environment we can use Get-AZVM and in a greenfield or new tenant there will be no VMs to list, obviously. If we have any VMs, the cmdlet will display them in a Format-List format by default. Which, if we want all the details of a VM is not a bad thing, however, if I need a quick table about our VMs, then we need to run the following:
Get-AzVm | Ft
Which would then provide a table like this:
If we have more than one subscription we can view all VMs for each subscription like this:
$AzSubIDs = (get-azsubscription).Id Foreach ($AzSubID in $AzSubIDs) { $AZSubscription = Select-AzSubscription -Subscription $AzSubId -ErrorAction SilentlyContinue Write-Host "Az VMs for the $AzSubID Azure Subscription:" -ForegroundColor Green $VMs = Get-AzVm | Ft If ($Null -eq $VMs) { Write-Host 'No Virtual machines location' -ForegroundColor Yellow } Else { $VMs } Write-Host '' }
Notice that one of the subscriptions is empty of VMs, but at least we have that visibility now as well.
We can now take one of these VMs and deep dive into its’ configuration and see what is revealed with PowerShell.
Get-AzVm | Ft Name
We can use one of the VM Names that are displayed with that one-liner –> ‘Web03e’
Get-AzVM Web03E | fl
Well. This cmdlet revealed some details. However, we notice some strange values like this:
Notice the values are prefaced with ‘Microsoft.Azure.Computer.Models’. These values contain more than they appear to. For example, let’s pick the ‘HardwareProfile’ property of this Virtual Machine.
OK. We know that this server was built off the Standard_A2 Azure VM template. Now what does the ‘NetworkProfile’ reveal:
OS Profile:
More details:
Storage Profile:
Deeper:
And:
Network Profile:
Diagnostics Profile:
We can see that there is definitely some hidden information that takes a bit of digging to pull out via PowerShell cmdlets. Now, what about all the other fields that are blank?
Well, nothing in PowerShell will reveal those properties as the values for this VM are truly empty. However, we do have a Status switch for the Get-AzVM cmdlet, what does this reveal? It reveals some new properties and places the information at the top of the list:
As we can see, there is a PowerState property as well as a MaintenanceRedeployStatus revealed by this cmdlet. Why is this done? Efficiency and time to return information. The less properties, the faster a cmdlet can run. We can use the PowerState property now, however, to reveal if a VM is off and possibly created a report around this value alone.
Let’s explore some more Get cmdlets:
Get-AzVMSize
* This cmdlet will provide a list of available VM Sizes for a particular region.
How do we know what region to look at? Well, we can get a list of regions like so:
Get-AZLocation
(sample from the list):
Currently there are 40 different Azure Regions to choose from. Ideally you will use one that is close to the users or process that will use that virtual machine. For our virtual machine ‘Web03’ that we were checking out previously, we see that is it in the EastUs2 region. We can use that information to get a list of available virtual machine sizes:
(Get-AzVMSize -Location EastUs2).Count
We get a list of 252 different sizes. A small sample is listed here:
Now we could potentially use this list to see what virtual machine images would provide us a base level of RAM and/or CPU count/:
Min cores = 16
Min RAM = 64GB
Get-AzVMSize -Location EastUs2 | Where {($_.NumberOfCores -ge 16) -and ($_.MemoryInMB -ge 65536)}
What we see is that there are 115 possible combinations at this size.
We can use this information to gather the size of each VM in our AZ Subscription. First, a one off:
Get-AzVMSize -Location EastUS2 | Where {$_.Name -eq 'Standard_A2'}
Now, what if wanted to check the size for each VM? And then report it?
$All = @() Foreach ($AllAzVM in $AllAzVMs){ $Location = $AllAzVM.location $VMSize=(($AllAzVM).HardwareProfile).VMSize $Name = $AllAzVM.Name $Specs = Get-AzVMSize -Location $Location | Where {$_.Name -eq $VMSize} $OutputObj = New-Object -Type PSObject $OutputObj | Add-Member -MemberType NoteProperty -Name VMName -Value $Name $OutputObj | Add-Member -MemberType NoteProperty -Name VMSize -Value $Specs.Name $OutputObj | Add-Member -MemberType NoteProperty -Name NumberOfCores -Value $Specs.NumberOfCores $OutputObj | Add-Member -MemberType NoteProperty -Name MemoryInMB -Value $Specs.MemoryInMB $OutputObj | Add-Member -MemberType NoteProperty -Name MaxDataDiskCount -Value $Specs.MaxDataDiskCount $OutputObj | Add-Member -MemberType NoteProperty -Name OSDiskSizeInMB -Value $Specs.OSDiskSizeInMB $OutputObj | Add-Member -MemberType NoteProperty -Name ResourceDiskSizeInMB -Value $Specs.ResourceDiskSizeInMB $OutputObj | FT -auto $All += $OutputObj } $All | ft
Which provides this nice table of results:
** Warning** This section is a bit of a rabbit hole and one that requires some digging to understand.
Az VM Images
There is a group of cmdlets that centers around the types of servers that can be installed. By type I mean operating system (in a loose sense). These cmdlets are as follows:
Get-AzVMImage Get-AzVMImageOffer Get-AzVMImagePublisher Get-AzVMImageSku
What we will see is that in order to get proper results and information about images available, we need some information. For example, if we rune GetAzVmImage, we get this strange result:
Well, if we review the parameters, we see that here are indeed multiple required parameters needed in order to get this cmdlet to work:
We already have a location ‘EastUs’, so how do we get other values? Well, other cmdlets. First, let’s look at ‘Get-AzVMImageOffer’:
OK. Well. That was a bust. We have the location (we can pull that from our VMs or from all locations if we need to), however, we do not have the correct PublisherName. How do we get that? Well, one more cmdlet – Get-AzVMImagePublisher.
Get-AzVMImagePublisher
However, there are 1232 Image Publishers. Yes, you read that right. Sample:
Let’s see if we can location anything with the keyword ‘Microsoft’ in the Publisher Name:
Get-AzVMImagePublisher -Location EastUs | Where {$_.PublisherName -like '*Microsoft*'}
That narrows it down to 322 Publishers. For Microsoft Windows however, we have three selections:
Get-AzVMImagePublisher -Location EastUs | Where {$_.PublisherName -like '*MicrosoftWindows*'}
Which provides this list:
MicrosoftWindowsDesktop
MicrosoftWindowsServer
MicrosoftWindowsServerHPCPack
In this case, we will choose ‘MicrosoftWindowsServer’ as our Publisher. Can we pull a Sku value at this point?
Nope. We still need an offer value. Let’s go back to Get-AzVMImageOffer.
Get-AzVMImageOffer -Location EastUs -Publisher MicrosoftWindowsServer
Success:
OK. Let’s pick one of these now ‘WindowsServer’ – Sounds pretty generic. Can we pull any details from it?
Not really. Ok. But we have an offer value. We need a SKU as well. Let’s see what that provides us:
Get-AzVMImageSku -Location EastUs -PublisherName MicrosoftWindowsServer -Offer WindowsServer
This provides us with a list of 57 possible images:
And the final reveal is that we have proper SKUs and a list of OS’s to work with from 2008 to 2019. Going back to our original goal we needed 5 bits of info – Location, Offer, PublisherName, SKUs and Version … However, it appears that version is actually optional:
Get-AzVMImage -Location EastUS -Offer WindowsServer -PublisherName MicrosoftWindowsServer -Skus2008-R2-SP1
Which provides this list:
As you can see, just from one example, there is a lot of cross connects and possible images.
Interesting side commands
Get-AzVMUsage -Location EastUS
This will list current CPU count in the EastUS Azure region:
Get-AzVMBootDiagnosticsData
This cmdlet will provide the boot screen of the virtual machine provided. If there are any issues, we would assume there might be a blue screen captured. Otherwise it looks like these two normal screenshots:
Example (1)
Get-AzVMBootDiagnosticsData -ResourceGroupName ResourceGroup03 -Name web03e -Windows -LocalPathc:\scripts\
Get-AzVMBootDiagnosticsData -ResourceGroupName ResourceGroup01 -Name Test2016 -Windows -LocalPath c:\scripts\
Get-AzVMDiskEncryptionStatus -ResourceGroupName ResourceGroup01 -vmName test2016
Get-AzVMRunCommandDocument -Location EastUS|FT
Not very descriptive, but that is because not all the fields are displayed … scrolling over in the same PowerShell window (I think my window size is like 300 ..) we see more interesting details:
So what exactly are these Azure Run Command Documents? With a bit of research we find that they are tied to this cmdlet ‘Invoke-AzVMRunCommand’: (from an example):
As we can see, one of the run documents is listed in the example ‘RunPowerShellScript’. Let’s explore this doc to see what we can find information on these docs:
It looks like this cmdlet will allow us to run a script on the destination VM and we need to specify the resource group, vm name, script path and any parameters. Full command from the example:
Invoke-AzVMRunCommand -ResourceGroupName 'rgname' -VMName 'vmname' -CommandId 'RunPowerShellScript' -ScriptPath 'sample.ps1' -Parameter @{param1 = "var1"; param2 = "var2"}
Looks like there 15 of these and no way to create more (no New-AzVMRunCommand cmdlet). If we manage Windows, then we have the vast majority of 12 of the 15 Run Command Docs whereas Linux only shows 3. Let’s look at one more ‘EnableRemotePS’ which could prove interesting if we need to open up Remote PS for management:
Nice. So it looks these are some common tasks that may need to be done in PowerShell for VM Management.
Conclusion
Well that was a lot for one article. In the next article we will cover some VMSS and Extension cmdlets in the AZ Compute module.