PowerShell Script to Generate the Virtual Machine Inventory Hosted in Azure ARM

PowerShell Script to Generate the Virtual Machine Inventory Hosted in Azure ARM

Overview

This is a PowerShell script to create reports for all Virtual machines in a subscription including its Resource Group / Virtual Network /IP/NIC/Data disk/Storage/Tags to readable .csv format to help you to identify the deviation and make them standard.

The following guide assumes that the user has basic knowledge of using Windows and PowerShell.  Although some familiarity with the Azure Portal would be beneficial, it is absolutely not necessary, as a step by step approach will be provided.

How the Script works

  • Enter the script subscription name for which report to be prepared.
  • Login to Azure from PowerShell window and execute the script.
  • Script will Select subscription
  • Fetch all the Resource Group /Virtual Machines/Storage account/NICs/Tags values and results will be placed in .CSV file.

Pre-requisites

The following prerequisites must be met, before performing the Core capacity check steps.

  1. Internet connection
  2. Valid Azure Subscription
  3. The person who will perform the below steps must have one of the following roles in the Azure subscription
    • Owner
    • Contributor
  4. Some familiarity with the Azure Portal would be beneficial, although not necessary
  5. Latest version of Microsoft .NET Framework (download link)
  6. Latest version of Microsoft Windows Management Framework (download link)
  7. Latest version of Microsoft PowerShell (download link including detailed installation guide)
  8. Latest version of Azure cmdlets (installation guide), although steps are provided below
  9. Some familiarity with PowerShell ISE, although not necessary (documentation)
  10. Some familiarity with the Azure Portal would be beneficial, although not necessary
  11. Some familiarity with PowerShell scripting would be beneficial, although not necessary

Windows PowerShell scripts can also be used for fetching the VM details in an azure subscription. It minimizes the human efforts and errors. It can be used to fetch information for all the VM in a particular subscription, therefore saving a lot of time. Windows Azure PowerShell module should be installed to use azure based commend lets (as mentioned in pre requisites). Follow the following link to download and configure the module –                                                        https://azure.microsoft.com/en-in/documentation/articles/powershell-install-configure

  1. The script is provided later in the blog
  • Open PowerShell ISE as Administrator and type below command to enter the Azure portal access email account and password
# connecting your azure account to powershell
Add-AzureRMaccount
  • Once your account is added, Copy and paste the provided script into untitled editor window, save it with a file name (.ps1).
  • Provide the Azure subscription name in Line 2 where <Azure Subscription Name>, save the script and execute the script
  • You will get an output in the same folder where the .ps1 file is saved.

PowerShell Script

#Provide the subscription name for which data needs to be fetched.
$subscription = '<Azure Subscription Name>' 
$VMDetails = @()

#######Getting the script path for exporting the outfile#########
$CurrentPath = Split-Path $MyInvocation.MyCommand.Definition
$date = Get-Date -UFormat "%d-%m-%Y-%H-%M"
$Outputfile = $CurrentPath + "\" + "VM_Details_" + $subscription.split('-')[-2] + '_' + $date + ".csv"

########Selecting the azure subscription#########
Select-AzureRmSubscription -SubscriptionName $subscription | Out-Null
write-host "Fetching details for" $subscription.split('-')[-2] "subscription......Please wait!!!!" -ForegroundColor Yellow

#######Getting all the RGs in the selected subscription#######
$resourcegroups = (Get-AzureRmResourceGroup).resourcegroupname

#######Getting all the blobs(files) in the selected subscription######
try{
foreach($resourcegroup in $resourcegroups)
{
if(($resourcegroup -like 'AZ-RG-??-BKP001') -or ($resourcegroup -like 'Az-RG-??-BKPC001') -or ($resourcegroup -like 'Az-RG-???-BKP001') -or ($resourcegroup -like 'Az-RG-???-BKPC001')){}
else{
Start-Sleep 3
$AllVHD = Get-AzureRmStorageAccount -ResourceGroupName $resourcegroup | Get-AzureStorageContainer | Get-AzureStorageBlob 
$AllVHDs = $AllVHDs + $AllVHD
}}}
catch
{
 if($_.exception.message -like "*The request is being throttled*")
 {Write-Verbose "Please close the powershell and re-run"} 
}

$VHDs = @()

#######Filtering the blobs which has .vhd extention########
ForEach ($AllItems in $AllVHDs)
{
 if($AllItems.Name.Split(".")[-1] -eq 'vhd')
 {
 $VHDs = $VHDs + $AllItems
 }
}

#######Fetching the details for each VM#########
foreach($resourcegroup in $resourcegroups)
{
 $names = (Get-AzureRmVM -ResourceGroupName $resourcegroup).Name #Getting all the VM names in the selected RG.
 foreach($name in $names)
 {
 $vm = Get-AzureRmVM -ResourceGroupName $resourcegroup -Name $name #Getting properties of VM.
 $out = ""|select Name,ResourceGroup,TotalDisk,Disks-Size,TotalSize,ProvisionState,DisplayStatus,Instance,Nics,Subnet,VNet,VnetResourceGroup,NicName,PrivateIP,PIPs,OSDiskName,OSDiskUri,DataDiskName,DataDiskUri,TagName0,TagValue0,TagName1,TagValue1,TagName2,TagValue2,TagName3,TagValue3,TagName4,TagValue4,TagName5,TagValue5,TagName6,TagValue6,TagName7,TagValue7,TagName8,TagValue8,OSDisk,OSDiskSize,DataDisk1,DataDisk1Size,DataDisk2,DataDisk2Size,DataDisk3,DataDisk3Size,DataDisk4,DataDisk4Size,DataDisk5,DataDisk5Size,DataDisk6,DataDisk6Size,DataDisk7,DataDisk7Size,DataDisk8,DataDisk8Size,DataDisk9,DataDisk9Size,DataDisk10,DataDisk10Size,DataDisk11,DataDisk11Size,DataDisk12,DataDisk12Size,DataDisk13,DataDisk13Size,DataDisk14,DataDisk14Size,DataDisk15,DataDisk15Size,DataDisk16,DataDisk16Size,DataDisk17,DataDisk17Size,DataDisk18,DataDisk18Size,DataDisk19,DataDisk19Size,DataDisk20,DataDisk20Size,DataDisk21,DataDisk21Size,DataDisk22,DataDisk22Size,DataDisk23,DataDisk23Size,DataDisk24,DataDisk24Size,DataDisk25,DataDisk25Size,DataDisk26,DataDisk26Size,DataDisk27,DataDisk27Size,DataDisk28,DataDisk28Size,DataDisk29,DataDisk29Size,DataDisk30,DataDisk30Size,DataDisk31,DataDisk31Size,DataDisk32,DataDisk32Size,DataDisk33,DataDisk33Size
 $out.DisplayStatus = (Get-AzureRmVM -ResourceGroupName $resourcegroup -Name $name -Status).statuses[1].displaystatus
 $out.Name = $vm.Name
 $out.ResourceGroup = $vm.ResourceGroupName
 $out.ProvisionState = $vm.ProvisioningState
 $tagcount =$vm.tags.count
 $out.Instance = $vm.HardwareProfile.VmSize #Getting instance size of VM.
 $out.Nics = $vm.NetworkInterfaceIDs.count #Getting total NICs attached to a VM.
 if($vm.NetworkProfile.NetworkInterfaces.id.count -gt 1){
 $Vnet = ($vm.NetworkProfile.NetworkInterfaces.id[0]).split("/")[-1]}
 else{$Vnet = ($vm.NetworkProfile.NetworkInterfaces.id).split("/")[-1]}
 $out.NicName = $Vnet #Getting primary NIC attached to a VM.
 $NetConf = (Get-AzureRmNetworkInterface -ResourceGroupName $resourcegroup -Name $Vnet).IpConfigurations
 $out.Subnet = $NetConf.subnet.id.split('/')[-1] #Getting the VM subnet.
 $out.VNet = $NetConf.subnet.id.split('/')[-3] #Getting Vnet Name.
 $out.VNetResourceGroup = $NetConf.subnet.id.split('/')[4] #Getting Vnet RG.
 $out.PrivateIP = $NetConf.privateipaddress #Getting IP address of VM. 
 $out.PIPs = $NetConf.publicipaddress.count #Getting Public IP address count.
 $out.OSDiskName = $vm.StorageProfile.OsDisk.vhd.Uri.Split('/')[-1].split('.')[-2] #Getting Os disk name.
 $out.OSDisk = $vm.StorageProfile.OsDisk.vhd.Uri.Split('/')[-1].split('.')[-2] 
 $out.OSDiskUri = $vm.StorageProfile.OsDisk.vhd.Uri #Getting Os disk Uri.
 $out.DataDiskName = $vm.StorageProfile.DataDisks.name-join(',,') #Getting Data Disk Name. 
 $out.DataDiskUri = $vm.StorageProfile.DataDisks.vhd.Uri -join(',,') #Gettign data disk Uri.
 $out.TotalDisk = ( $vm.StorageProfile.OsDisk.vhd.Uri).count + ($vm.StorageProfile.DataDisks.vhd.Uri).Count #Getting total disk count attached to a VM.
 $diskCount = ($vm.StorageProfile.DataDisks).count

#######Getting names of all the data disk attached to the VM#####
 for($i = 1; $i -le $diskCount; $i++)
 {
 $out."DataDisk$i" = $vm.StorageProfile.DataDisks[$i-1].name 
 }
 
 ########Getting OS disk size of the VM###########
 foreach($VHD in $VHDs)
 {
 if($vm.StorageProfile.OsDisk.vhd.uri.Split("/")[-1] -eq $VHD.Name)
 {
 $out.OSDiskSize = "{0:f0}" -f ($VHD.Length/1024/1024/1024) 
 }
 }

######Getting size of the data disk attached to a VM######## 
 for($i = 1; $i -le $diskCount; $i++)
 {
 ForEach ($VHD in $VHDs)
 {
 if($vm.StorageProfile.DataDisks[$i-1].vhd.uri.Split("/")[-1] -eq $VHD.Name )
 {
 $DiskSize = 'DataDisk'+$i+'Size' 
 $out."DataDisk$i" = $vm.StorageProfile.DataDisks[$i-1].Name
 $out.$DiskSize = "{0:f0}" -f ($VHD.Length/1024/1024/1024)
 }
 }
 }

#######Getting the disk sizes in desired format########
 $dataSize = 0
 for($i = 1; $i -le $diskCount; $i++){$DiskSize = 'DataDisk'+$i+'Size'
 $DataSize = $DataSize + $out.$DiskSize
 $d = $d + '|' + $out.$DiskSize
 }
 $out.TotalSize = $DataSize + $out.OSDiskSize
 $out.'Disks-Size' = $out.OSDiskSize + $d
 if($d -ne $null){
 clear-variable d}
 
 #########Fetching tag values of VM#########
 if($subscription.split('-')[-2] -eq 'DEV' -or $subscription.split('-')[-2] -eq 'UAT')
 {
 $out.TagName0 = 'OS'
 $out.TagName1 = 'Tier'
 $out.TagName2 = 'Role'
 $out.TagName3 = 'CR'
 $out.TagName4 = 'Owner'
 $out.TagName5 = 'Forest'
 $out.TagName6 = 'AZ-TAG-'+$subscription.split('-')[-2]+'-AutoShutdownSchedule'
 $out.TagName7 = 'AZ-TAG-'+$subscription.split('-')[-2]+'-Exclude'
 $out.TagName8 = 'ExcludeDesc'

$out.TagValue0 = $vm.Tags.os
 if($out.TagValue0 -eq $null){$out.TagValue0 = $vm.Tags.OS}
 if($out.TagValue0 -eq $null){$out.TagValue0 = $vm.Tags.Os}
 if($out.TagValue0 -eq $null){$out.TagValue0 = $vm.Tags.oS}

$out.TagValue1 = $vm.Tags.tier
 if($out.TagValue1 -eq $null){$out.TagValue1 = $vm.Tags.Tier}
 if($out.TagValue1 -eq $null){$out.TagValue1 = $vm.Tags.TIER}

$out.TagValue2 = $vm.Tags.role
 if($out.TagValue2 -eq $null){$out.TagValue2 = $vm.Tags.Role}
 if($out.TagValue2 -eq $null){$out.TagValue2 = $vm.Tags.ROLE}

$out.TagValue3 = $vm.Tags.cr
 if($out.TagValue3 -eq $null){$out.TagValue3 = $vm.Tags.Cr}
 if($out.TagValue3 -eq $null){$out.TagValue3 = $vm.Tags.cR}
 if($out.TagValue3 -eq $null){$out.TagValue3 = $vm.Tags.CR}

$out.TagValue4 = $vm.Tags.owner
 if($out.TagValue4 -eq $null){$out.TagValue4 = $vm.Tags.Owner}
 if($out.TagValue4 -eq $null){$out.TagValue4 = $vm.Tags.OWNER}

$out.TagValue5 = $vm.Tags.forest
 if($out.TagValue5 -eq $null){$out.TagValue5 = $vm.Tags.Forest}
 if($out.TagValue5 -eq $null){$out.TagValue5 = $vm.Tags.FOREST}


 $autocheck1 = 'AZ-TAG-'+$subscription.split('-')[-2]+'-AutoShutdownSchedule'
 $autocheck2 = 'aZ-TAG-'+$subscription.split('-')[-2]+'-AutoShutdownSchedule'
 $out.TagValue6 = $vm.Tags.$autocheck1
 if($out.TagValue6 -eq $null){$out.TagValue6 = $vm.Tags.$autocheck2}
 
 $excludecheck1 = 'AZ-TAG-'+$subscription.split('-')[-2]+'-Exclude'
 $excludecheck2 = 'aZ-TAG-'+$subscription.split('-')[-2]+'-Exclude'
 $out.TagValue7 = $vm.Tags.$excludecheck1
 if($out.TagValue7 -eq $null){$out.TagValue7 = $vm.Tags.$excludecheck2}

$out.TagValue8 = $vm.Tags.excludedesc
 if($out.TagValue8 -eq $null){$out.TagValue8 = $vm.Tags.ExcludeDesc}
 if($out.TagValue8 -eq $null){$out.TagValue8 = $vm.Tags.Excludedesc}
 if($out.TagValue8 -eq $null){$out.TagValue8 = $vm.Tags.EXCLUDEDESC}
 }
 else
 {
 $out.TagName0 = 'OS'
 $out.TagName1 = 'Tier'
 $out.TagName2 = 'Role'
 $out.TagName3 = 'CR'
 $out.TagName4 = 'Owner'
 $out.TagName5 = 'Forest'

$out.TagValue0 = $vm.Tags.os
 if($out.TagValue0 -eq $null){$out.TagValue0 = $vm.Tags.OS}
 if($out.TagValue0 -eq $null){$out.TagValue0 = $vm.Tags.Os}
 if($out.TagValue0 -eq $null){$out.TagValue0 = $vm.Tags.oS}

$out.TagValue1 = $vm.Tags.tier
 if($out.TagValue1 -eq $null){$out.TagValue1 = $vm.Tags.Tier}
 if($out.TagValue1 -eq $null){$out.TagValue1 = $vm.Tags.TIER}

$out.TagValue2 = $vm.Tags.role
 if($out.TagValue2 -eq $null){$out.TagValue2 = $vm.Tags.Role}
 if($out.TagValue2 -eq $null){$out.TagValue2 = $vm.Tags.ROLE}

$out.TagValue3 = $vm.Tags.cr
 if($out.TagValue3 -eq $null){$out.TagValue3 = $vm.Tags.Cr}
 if($out.TagValue3 -eq $null){$out.TagValue3 = $vm.Tags.cR}
 if($out.TagValue3 -eq $null){$out.TagValue3 = $vm.Tags.CR}

$out.TagValue4 = $vm.Tags.owner
 if($out.TagValue4 -eq $null){$out.TagValue4 = $vm.Tags.Owner}
 if($out.TagValue4 -eq $null){$out.TagValue4 = $vm.Tags.OWNER}

$out.TagValue5 = $vm.Tags.forest
 if($out.TagValue5 -eq $null){$out.TagValue5 = $vm.Tags.Forest}
 if($out.TagValue5 -eq $null){$out.TagValue5 = $vm.Tags.FOREST}
 }
 $VMDetails = $VMDetails + $out 
 }
 $VMDetails | Export-Csv -Path $Outputfile -Force -NoTypeInformation #Exporting the output CSV to the desired location.
}

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Share via
Copy link