Sunday, September 20, 2020

Azure: Determining the Parameters to Change in Azure Resource Manager (ARM) Templates


In the post "Azure: Azure Resource Manager (ARM) templates for creating Virtual Machines for Standard Window's SKU's" it was shown how to create an Azure Resource Manager (ARM) template that can be used to create a virtual machine. Also shown was how to generate the template's parameter file. There are dozens of parameters so what this post demonstrates is how to determine which parameters to modify.

Reading the parameters file it can be seen that one parameter, adminPassword is assigned to null as it is a password. The adminPassword parameter's value was excluded when the parameter file was created as is shown below:

The name of the VM specified when the ARM template was created was Machine04. The parameters tied to this machine name are:

  • networkInterfaceName
  • networkSecurityGroupName
  • publicIpAddressName
  • virtualMachineName
  • virtualMachineComputerName

A simple way to determine the parameters requiring modification is to:

  1. Create a copy of the parameters file
  2. In the copy of the parameters file change the text value of Machine04 to Machine123
  3. Perform a diff on the original parameters file and the modified copy of the parameters file
The remainder of this post is a list of tools that are useful in determining the parameters that need to be updated when deploying an ARM templet.

Visual Studio Code: File Compare

A handy online way to diff two text files is to use I like this site because the diff has options defined as follows: shows the differences as follows:

The site,, allows to Json objects (the parameters files are just Json objects) to be compared. The aforementioned site identifies how many differences there are between the Json objects:

The site,, also allows navigation between all differences detected:

Saturday, September 19, 2020

Visual Studio Code: Comparing Text Files

Visual Studio Code has built in, albeit unintuitively, file comparison. To diff two files, from Explorer right click on the first file to compare and choose Select for Compare from the context menu:

In the screen snippet above the ParametersW10.json file was clicked on initially. To choose the second file to diff, from Explorer right click on a file and choose Compare with Selected:

In the screen snippet above the 20200919072819442ParametersW10.json file was selected to be compared to ParametersW10.json. 

The difference between the two files is shown as follows:

The upper right corner of the diff provides some handle tools for managing the file compare:

The options are defined as follows:

  • Up arrow: navigate to previous difference
  • Down Arrow: navigate to next difference
  • Backwards P:Show leading/trailing whitespace differences

Sunday, September 6, 2020

Azure/PowerShell: Finding and Removing Orphaned Network Interfaces

When an Azure virtual machine is deleted via the portal ( any network interfaces associated with the VM are not deleted. This can lead to the pool of IP addresses associated with a subnet to be exhausted and no new VMs can be created as there are no IP addresses to assign to the new VMs.

The Get-AzNetworkInterface cmdlet returns all network instances for an Azure subscription and the Remove-AzNetworkInterface cmdlet removes a specific network interface. The following code uses Get-AzNetworkInterface in conjunction with Where-Object to get all orphaned network interfaces. Each network interface is represented by an instance of type PSNetworkInterface

[string] $subID = 'put subscription ID here'

Select-AzureRmSubscription `
 -Subscriptionid $SubID | Out-Null

[Microsoft.Azure.Commands.Network.Models.PSNetworkInterface []] ` 
 $nics =
   Get-AzNetworkInterface |
   Where-Object {
     ($_.VirtualMachine -eq $null) -And
     (($_.PrivateEndpointText -eq $null) -Or
      ($_.PrivateEndpointText -eq 'null'))}

foreach ($nic in $nics)
     "Removing Orphaned NIC $($nic.Name) $($nic.resourcegroupname)"
 Remove-AzNetworkInterface `
   -Name $nic.Name `
   -ResourceGroupName $nic.resourcegroupname `
   -Force }

The Get-AzNetworkInterface | Where-Object code returns only network interfaces:

  • Not associated with virtual machines
  • Not associated with private endpoints 

This script snippet detects if a network interface is not associated with a virtual machine:

($_.VirtualMachine -eq $null)

This script snippet detects if a network interface is not associated with a private endpoint:

     (($_.PrivateEndpointText -eq $null) -Or 
      ($_.PrivateEndpointText -eq 'null'))}

Not being associated with a virtual machine appears to identify a network interface as orphaned having formally been assigned to a now deleted VM. There are network interfaces that were never associated with a virtual machine such as a network interface associated with a private endpoint. This is why there is an additional check to insure the PSNetworkInterface.PrivateEndpointText property is not assigned. Private endpoints are ancillary germane to detecting/removing orphaned network interfaces. More information on private endpoints can be found at What is Azure Private Endpoint?.

Saturday, September 5, 2020

PowerShell: Expanding Object Properties in Strings using Subexpression Operator

Expanding variables inside a double quoted string is useful as shown below but this approach works with variables and not with object properties:

[string] $hostName = 'Executive Officer Kane'

Write-Output "Host name: $hostName"

The output from the above script snippet is as follows:

The script below expands object properties using the subexpression operator in a string that is passed to the Write-Host cmd-let (see the last line of code, Write-Host, in the script below):

The subexpression operation, $(), means that code in the parenthesis is invoked first hence the property is evaluated and then expanded in the string:

"Orphaned $($nic.Name) $($nic.resourcegroupname)"

The subexpression operator is documented in About Operators as follows:

Double quoted strings are useful for variable and object/property expansion but recall the previous post PowerShell: Use Single Quotes Where Possible,