modules/Public/InventoryModules/Compute/VirtualMachine.ps1
<#
.Synopsis Inventory for Azure Virtual Machine .DESCRIPTION This script consolidates information for all microsoft.compute/virtualmachines resource provider in $Resources variable. Excel Sheet Name: Virtual Machines .Link https://github.com/microsoft/ARI/Modules/Public/InventoryModules/Compute/VirtualMachine.ps1 .COMPONENT This powershell Module is part of Azure Resource Inventory (ARI) .NOTES Version: 3.6.0 First Release Date: 19th November, 2020 Authors: Claudio Merola and Renato Gregio #> <######## Default Parameters. Don't modify this ########> param($SCPath, $Sub, $Intag, $Resources, $Retirements, $Task, $File, $SmaResources, $TableStyle, $Unsupported) If ($Task -eq 'Processing') { $vm = $Resources | Where-Object {$_.TYPE -eq 'microsoft.compute/virtualmachines'} $nic = $Resources | Where-Object {$_.TYPE -eq 'microsoft.network/networkinterfaces'} $vmexp = $Resources | Where-Object {$_.TYPE -eq 'microsoft.compute/virtualmachines/extensions'} $disk = $Resources | Where-Object {$_.TYPE -eq 'microsoft.compute/disks'} $VirtualNetwork = $Resources | Where-Object { $_.TYPE -eq 'microsoft.network/virtualnetworks' } $VMExtraDetails = $Resources | Where-Object { $_.TYPE -eq 'ARI/VM/SKU' } $VMQuotas = $Resources | Where-Object { $_.TYPE -eq 'ARI/VM/Quotas' } if($vm) { $tmp = foreach ($1 in $vm) { $ResUCount = 1 $sub1 = $SUB | Where-Object { $_.id -eq $1.subscriptionId } $data = $1.PROPERTIES $timecreated = $data.timeCreated $timecreated = [datetime]$timecreated $timecreated = $timecreated.ToString("yyyy-MM-dd HH:mm") $dataSize = '' $StorAcc = '' $OSName = if(![string]::IsNullOrEmpty($data.extended.instanceView.osname)){$data.extended.instanceView.osname}else{$data.storageprofile.imagereference.offer} $OSVersion = if(![string]::IsNullOrEmpty($data.extended.instanceView.osversion)){$data.extended.instanceView.osversion}else{$data.storageprofile.imagereference.sku} # Extra VM Details $VMExtraDetail = $VMExtraDetails.properties | Where-Object {$_.Location -eq $1.location} $VMExtraDetail = $VMExtraDetail.SKUs | Where-Object {$_.Name -eq $data.hardwareProfile.vmSize} foreach ($Capability in $VMExtraDetail.Capabilities) { if ($Capability.Name -eq 'vCPUs') {$vCPUs = $Capability.Value} if ($Capability.Name -eq 'vCPUsPerCore') {$vCPUsPerCore = $Capability.Value} if ($Capability.Name -eq 'MemoryGB') {$RAM = $Capability.Value} if ($Capability.Name -eq 'MaxDataDiskCount') {$MaxDataDiskCount = $Capability.Value} if ($Capability.Name -eq 'UncachedDiskIOPS') {$UncachedDiskIOPS = $Capability.Value} if ($Capability.Name -eq 'UncachedDiskBytesPerSecond') {$UncachedDiskBytesPerSecond = ([math]::Round($Capability.Value / 1024) / 1024)} if ($Capability.Name -eq 'MaxNetworkInterfaces') {$MaxNetworkInterfaces = $Capability.Value} } # Quotas $Size = $VMExtraDetail.Family $Quota = $VMQuotas.properties | Where-Object {$_.SubId -eq $1.subscriptionId} $Quota = $Quota | Where-Object {$_.Location -eq $1.location} $RemainingQuota = (($Quota.Data | Where-Object {$_.Name.Value -eq $Size}).Limit - ($Quota.Data | Where-Object {$_.Name.Value -eq $Size}).CurrentValue) $Retired = Foreach ($Retirement in $Retirements) { if ($Retirement.id -eq $1.id) { $Retirement } } if ($Retired) { $RetiredFeature = foreach ($Retire in $Retired) { $RetiredServiceID = $Unsupported | Where-Object {$_.Id -eq $Retired.ServiceID} $tmp0 = [PSCustomObject]@{ 'RetiredFeature' = $RetiredServiceID.RetiringFeature 'RetiredDate' = $RetiredServiceID.RetirementDate } $tmp0 } $RetiringFeature = if ($RetiredFeature.RetiredFeature.count -gt 1) { $RetiredFeature.RetiredFeature | ForEach-Object { $_ + ' ,' } }else { $RetiredFeature.RetiredFeature} $RetiringFeature = [string]$RetiringFeature $RetiringFeature = if ($RetiringFeature -like '* ,*') { $RetiringFeature -replace ".$" }else { $RetiringFeature } $RetiringDate = if ($RetiredFeature.RetiredDate.count -gt 1) { $RetiredFeature.RetiredDate | ForEach-Object { $_ + ' ,' } }else { $RetiredFeature.RetiredDate} $RetiringDate = [string]$RetiringDate $RetiringDate = if ($RetiringDate -like '* ,*') { $RetiringDate -replace ".$" }else { $RetiringDate } } else { $RetiringFeature = $null $RetiringDate = $null } #Extensions $ext = @() $AzDiag = '' $Azinsights = '' $Lic = switch ($data.licenseType) { 'Windows_Server' { 'Azure Hybrid Benefit for Windows' } 'Windows_Client' { 'Windows client with multi-tenant hosting' } 'RHEL_BYOS' { 'Azure Hybrid Benefit for Redhat' } 'SLES_BYOS' { 'Azure Hybrid Benefit for SUSE' } default { $data.licenseType } } $Lic = if($Lic){$Lic}else{'None'} $ext = foreach ($vmextension in $vmexp) { if (($vmextension.id -split "/")[8] -eq $1.name) { $vmextension.properties.Publisher } } if ($null -ne $ext) { $ext = foreach ($ex in $ext) { if ($ex | Where-Object { $_ -eq 'Microsoft.Azure.Performance.Diagnostics' }) { $AzDiag = $true } if ($ex | Where-Object { $_ -eq 'Microsoft.EnterpriseCloud.Monitoring' }) { $Azinsights = $true } $ex + ', ' } $ext = [string]$ext $ext = $ext.Substring(0, $ext.Length - 2) } if(![string]::IsNullOrEmpty($data.osprofile.windowsconfiguration.enableautomaticupdates)) { if($data.osprofile.windowsconfiguration.enableautomaticupdates -eq 'True') { $Autoupdate = $true } else { $Autoupdate = $false } } elseif(![string]::IsNullOrEmpty($data.osprofile.linuxconfiguration.patchsettings.patchmode)) { if($data.osprofile.linuxconfiguration.patchsettings.patchmode -eq 'automaticbyos') { $Autoupdate = $true } else { $Autoupdate = $false } } if (![string]::IsNullOrEmpty($data.availabilitySet)) { $AVSET = $true }else { $AVSET = $false } if ($data.diagnosticsProfile.bootDiagnostics.enabled -eq $true) { $bootdg = $true }else { $bootdg = $false } #Storage if($data.storageProfile.osDisk.vhd.uri) { $OSDisk = 'Custom VHD' $OSDiskSize = $data.storageProfile.osDisk.diskSizeGB } else { foreach ($VMDisk in $disk) { if ($VMDisk.id -eq $data.storageProfile.osDisk.managedDisk.id) { $OSDisk = $VMDisk.sku.name } if ($VMDisk.id -eq $data.storageProfile.dataDisks.managedDisk.id) { $OSDiskSize = $VMDisk.properties.diskSizeGB } } } if ($data.storageProfile.dataDisks.managedDisk.id) { if ($data.storageProfile.dataDisks.managedDisk.id.count -ge 2) { $StorAcc = ($data.storageProfile.dataDisks.managedDisk.id.count.ToString() + ' Disks found.') foreach ($VMDisk in $disk) { if ($VMDisk.id -in $data.storageProfile.dataDisks.managedDisk.id) { $dataSize = ($VMDisk.properties.diskSizeGB | Measure-Object -Sum).Sum } } } else { foreach ($VMDisk in $disk) { if ($VMDisk.id -eq $data.storageProfile.dataDisks.managedDisk.id) { $StorAcc = $VMDisk.sku.name $dataSize = $VMDisk.properties.diskSizeGB } } } } else { $StorAcc = 'None' $dataSize = '0' } $Tags = if(![string]::IsNullOrEmpty($1.tags.psobject.properties)){$1.tags.psobject.properties}else{'0'} $VMNICS = if(![string]::IsNullOrEmpty($data.networkProfile.networkInterfaces.id)){$data.networkProfile.networkInterfaces.id}else{'0'} foreach ($2 in $VMNICS) { $vmnic = foreach ($netinterface in $nic) { if ($netinterface.id -eq $2) { $netinterface } } $vmnic = $vmnic | Select-Object -Unique $PIP = if(![string]::IsNullOrEmpty($vmnic.properties.ipConfigurations.properties.publicIPAddress.id)){$vmnic.properties.ipConfigurations.properties.publicIPAddress.id.split('/')[8]}else{''} $VNET = if(![string]::IsNullOrEmpty($vmnic.properties.ipConfigurations.properties.subnet.id)){$vmnic.properties.ipConfigurations.properties.subnet.id.split('/')[8]}else{''} $Subnet = if(![string]::IsNullOrEmpty($vmnic.properties.ipConfigurations.properties.subnet.id)){$vmnic.properties.ipConfigurations.properties.subnet.id.split('/')[10]} else {''} $vmnet = foreach ($VMVnet in $VirtualNetwork) { if ($VMVnet.subnets.id -eq $vmnic.properties.ipConfigurations.properties.subnet.id) { $VMVnet } } $vmnetsubnet = $vmnet.properties.subnets | Where-Object {$_.id -eq $vmnic.properties.ipConfigurations.properties.subnet.id} if(![string]::IsNullOrEmpty($vmnic.properties.dnsSettings.dnsServers)) { $DNSServer = $vmnic.properties.dnsSettings.dnsServers } else { $DNSServer = $vmnet.properties.dhcpoptions.dnsservers } if(![string]::IsNullOrEmpty($DNSServer)) { $FinalDNS = if ($DNSServer.count -gt 1) { $DNSServer | ForEach-Object { $_ + ' ,' } }else { $DNSServer } $FinalDNS = [string]$FinalDNS $FinalDNS = if ($FinalDNS -like '* ,*') { $FinalDNS -replace ".$" }else { $FinalDNS } $FinalDNS = ('VNET: ( ' + $FinalDNS + ')') } else { $FinalDNS = 'Default (Azure-provided)' } if(![string]::IsNullOrEmpty($vmnic.properties.networkSecurityGroup.id)) { $vmnsg = $vmnic.properties.networkSecurityGroup.id.split('/')[8] } elseif(![string]::IsNullOrEmpty($vmnetsubnet.properties.networksecuritygroup.id)) { $vmnsg = ('Subnet: ('+$vmnetsubnet.properties.networksecuritygroup.id.split('/')[8]+')') } else { $vmnsg = 'None' } if(![string]::IsNullOrEmpty($vmnic.properties.enableAcceleratedNetworking)) { $AcceleratedNetwork = $true } else { $AcceleratedNetwork = $false } foreach ($Tag in $Tags) { $obj = @{ 'ID' = $1.id; 'Subscription' = $sub1.Name; 'Resource Group' = $1.RESOURCEGROUP; 'VM Name' = $1.NAME; 'Location' = $1.LOCATION; 'Retiring Feature' = $RetiringFeature; 'Retiring Date' = $RetiringDate; 'Availability Zone' = [string]$1.ZONES; 'Zones Available in the Region' = [string]$VMExtraDetail.LocationInfo.ZoneDetails.Name; 'Availability Set' = $AVSET; 'VM Size' = $data.hardwareProfile.vmSize; 'Remaining Quota (vCPUs)' = [string]$RemainingQuota; 'vCPUs' = $vCPUs; 'vCPUs Per Core' = $vCPUsPerCore; 'RAM (GiB)' = $RAM; 'Max Remote Storage Disks' = $MaxDataDiskCount; 'Uncached Disk IOPS Limit' = $UncachedDiskIOPS; 'Uncached Disk Throughput Limit (MB/s)' = $UncachedDiskBytesPerSecond; 'Max Network Interfaces' = $MaxNetworkInterfaces; 'Image Reference' = $data.storageProfile.imageReference.publisher; 'Image Version' = $data.storageProfile.imageReference.exactVersion; 'Capabilities' = [string]$VMExtraDetail.LocationInfo.ZoneDetails.Capabilities.Name; 'Hybrid Benefit' = $Lic; 'Admin Username' = $data.osProfile.adminUsername; 'OS Type' = $data.storageProfile.osDisk.osType; 'OS Name' = $OSName; 'OS Version' = $OSVersion; 'Automatic Update' = $Autoupdate; 'Boot Diagnostics' = $bootdg; 'Performance Agent' = if ($azDiag -ne '') { $true }else { $false }; 'Azure Monitor' = if ($Azinsights -ne '') { $true }else { $false }; 'OS Disk Storage Type' = $OSDisk; 'OS Disk Size (GB)' = $OSDiskSize; 'Data Disk Storage Type' = $StorAcc; 'Data Disk Size (GB)' = $dataSize; 'VM generation' = $data.extended.instanceview.hypervgeneration; 'Power State' = $data.extended.instanceView.powerState.displayStatus; 'NIC Name' = [string]$vmnic.name; 'NIC Type' = [string]$vmnic.properties.nicType; 'DNS Servers' = $FinalDNS; 'Public IP' = $PIP; 'Virtual Network' = $VNET; 'Subnet' = $Subnet; 'NSG' = $vmnsg; 'Accelerated Networking' = $AcceleratedNetwork; 'IP Forwarding' = [string]$vmnic.properties.enableIPForwarding; 'Private IP Address' = [string]$vmnic.properties.ipConfigurations.properties.privateIPAddress; 'Private IP Allocation' = [string]$vmnic.properties.ipConfigurations.properties.privateIPAllocationMethod; 'Creation Time' = $timecreated; 'VM Extensions' = $ext; 'Resource U' = $ResUCount; 'Tag Name' = [string]$Tag.Name; 'Tag Value' = [string]$Tag.Value } if ($ResUCount -eq 1) { $ResUCount = 0 } $obj } } } $tmp } } else { If($SmaResources) { $TableName = ('VMTable_'+($SmaResources.'Resource U').count) $Style = @() $Style += New-ExcelStyle -HorizontalAlignment Center -AutoSize -NumberFormat '0' -VerticalAlignment Center $Style += New-ExcelStyle -HorizontalAlignment Left -Range AW:AW -Width 60 -WrapText $SheetName = 'Virtual Machines' $condtxt = @() #Automatic Updates $condtxt += New-ConditionalText false -Range V:V #Hybrid Benefit $condtxt += New-ConditionalText None -Range Y:Y #Boot Diagnostics $condtxt += New-ConditionalText false -Range AA:AA #Performance Agent $condtxt += New-ConditionalText false -Range AB:AB #Azure Monitor $condtxt += New-ConditionalText false -Range AC:AC #NSG $condtxt += New-ConditionalText None -Range AN:AN #Acelerated Network $condtxt += New-ConditionalText false -Range AQ:AQ #Retirement $condtxt += New-ConditionalText -Range M2:M100 -ConditionalType ContainsText $Exc = New-Object System.Collections.Generic.List[System.Object] $Exc.Add('Subscription') $Exc.Add('Resource Group') $Exc.Add('VM Name') $Exc.Add('VM Size') $Exc.Add('Remaining Quota (vCPUs)') $Exc.Add('vCPUs') $Exc.Add('vCPUs Per Core') $Exc.Add('RAM (GiB)') $Exc.Add('Max Remote Storage Disks') $Exc.Add('Uncached Disk IOPS Limit') $Exc.Add('Uncached Disk Throughput Limit (MB/s)') $Exc.Add('Max Network Interfaces') $Exc.Add('Retiring Feature') $Exc.Add('Retiring Date') $Exc.Add('Availability Zone') $Exc.Add('Zones Available in the Region') $Exc.Add('Capabilities') $Exc.Add('Location') $Exc.Add('OS Type') $Exc.Add('OS Name') $Exc.Add('OS Version') $Exc.Add('Automatic Update') $Exc.Add('Image Reference') $Exc.Add('Image Version') $Exc.Add('Hybrid Benefit') $Exc.Add('Admin Username') $Exc.Add('Boot Diagnostics') $Exc.Add('Performance Agent') $Exc.Add('Azure Monitor') $Exc.Add('OS Disk Storage Type') $Exc.Add('OS Disk Size (GB)') $Exc.Add('Data Disk Storage Type') $Exc.Add('Data Disk Size (GB)') $Exc.Add('VM generation') $Exc.Add('Power State') $Exc.Add('Availability Set') $Exc.Add('Virtual Network') $Exc.Add('Subnet') $Exc.Add('DNS Servers') $Exc.Add('NSG') $Exc.Add('NIC Name') $Exc.Add('NIC Type') $Exc.Add('Accelerated Networking') $Exc.Add('IP Forwarding') $Exc.Add('Private IP Address') $Exc.Add('Private IP Allocation') $Exc.Add('Public IP') $Exc.Add('Creation Time') $Exc.Add('VM Extensions') $Exc.Add('Resource U') if($InTag) { $Exc.Add('Tag Name') $Exc.Add('Tag Value') } $noNumberConversion = @() $noNumberConversion += 'OS Version' $noNumberConversion += 'Image Version' $noNumberConversion += 'Private IP Address' $noNumberConversion += 'DNS Servers' [PSCustomObject]$SmaResources | ForEach-Object { $_ } | Select-Object $Exc | Export-Excel -Path $File -WorksheetName $SheetName -TableName $TableName -TableStyle $tableStyle -MaxAutoSizeRows 100 -ConditionalText $condtxt -Style $Style -NoNumberConversion $noNumberConversion } } |