Export info about all VM's within an Azure subscription

So I found this script below and its leaving me with a blank csv.

param(
    [string]$tenantId="",
    [string]$file="Azure-ARM-VMs.csv"
) 

if ($tenantId -eq "") {
    login-azurermaccount 
    $subs = Get-AzureRmSubscription 
} else {
    login-azurermaccount -tenantid $tenantId 
    $subs = Get-AzureRmSubscription -TenantId $tenantId 
}


$vmobjs = @()

foreach ($sub in $subs)
{
    
    Write-Host Processing subscription $sub.SubscriptionName

    try
    {

        Select-AzureRmSubscription -SubscriptionId $sub.SubscriptionId -ErrorAction Continue

        $vms = Get-AzureRmVm 

        foreach ($vm in $vms)
        {
            $vmInfo = [pscustomobject]@{
                'Subscription'=$sub.SubscriptionName
                'Mode'='ARM'
                'Name'=$vm.Name
                'ResourceGroupName' = $vm.ResourceGroupName
                'Location' = $vm.Location
                'VMSize' = $vm.HardwareProfile.VMSize
                'Status' = $null
                'AvailabilitySet' = $vm.AvailabilitySetReference.Id }
        
            $vmStatus = $vm | Get-AzureRmVM -Status
            $vmInfo.Status = $vmStatus.Statuses[1].DisplayStatus

            $vmobjs += $vmInfo

        }  
    }
    catch
    {
        Write-Host $error[0]
    }
}

$vmobjs | Export-Csv -NoTypeInformation -Path $file
Write-Host "VM list written to $file"

This results in the following error

 

Processing subscription XXXX
Account                      SubscriptionName           TenantId                             Environment
-------                      ----------------           --------                             -----------
XXXX XXXX XXXX XXXX 

Name               : XXXX
Account            : XXXX
Environment        : XXXX
Subscription       : XXXX
Tenant             : XXXX
TokenCache         : Microsoft.Azure.Commands.Common.Authentication.ProtectedFileTokenCache
VersionProfile     : 
ExtendedProperties : {}

Cannot index into a null array.
Processing subscription XXXX

Name               : XXXX
Account            : XXXX
Environment        : XXXX
Subscription       : XXXX
Tenant             : XXXX
TokenCache         : Microsoft.Azure.Commands.Common.Authentication.ProtectedFileTokenCache
VersionProfile     : 
ExtendedProperties : {}

VM list written to Azure-ARM-VMs.csv

Keep in mind I am a complete idiot when it comes to scripting and powershell.

#1 rule - never, ever run, any code from any where that you do not fully understand what it does and why it does it the way it does.

If you do not, you can seriously harm your system / your enterprise and put yourself in an RPE error (Resume Producing Event).

As for this…

Keep in mind I am a complete idiot when it comes to scripting and powershell.

I know, we are all time crunched and just need to get things done, but it is vital that you get yourself ramped up on PowerShell before getting in to doing stuff with it, especially when it comes to enterprise use cases.

There are tons for no-cost options to do so. One just needs to take that time to use it, to limit / avoid frustration, misconceptions, confusion, errors, bad habits that you are going to encounter (back on that). See the post I made here for someone asking for learning resources.

Now, as for your current use case. You need to break down the script into it’ pieces, and step thru it to make sure you are getting any results first, well, before thinking about creating output. Here is a simple way to do this with the script.

Function Get-BasicAzureInfo
{
    param
    (
        [string]$tenantId = "",
        [string]$file = "Azure-ARM-VMs.csv"
    ) 

    if ($tenantId -eq "") 
    {
        login-azurermaccount 
        $subs = Get-AzureRmSubscription
    } 
    else 
    {
        login-azurermaccount -tenantid $tenantId 
        $subs = Get-AzureRmSubscription -TenantId $tenantId
    }

$subs | Out-GridView -Title 'Azure subscriptions accociated with your TenantId'
}

Get-BasicAzureInfo -tenantId 'EnterYour TenantID' -file 'Enter your fully qualified file path'



# If you get results from the above, you are all good there, then lets move next


# Comment this out for now, as it is moot, unitl you know you are getting something at all
# $vmobjs = @()

# Are you getting baseline info back
foreach ($sub in $subs)
{
    
    Write-Host Processing subscription $sub.SubscriptionName

    try
    {
        Select-AzureRmSubscription -SubscriptionId $sub.SubscriptionId -ErrorAction Continue

        $vms = Get-AzureRmVm 
        $vms

# Comment this out for now, as it is moot, unitl you know you are getting something at all
<#
        foreach ($vm in $vms)
        {
            $vmInfo = [pscustomobject]@{
                'Subscription'=$sub.SubscriptionName
                'Mode'='ARM'
                'Name'=$vm.Name
                'ResourceGroupName' = $vm.ResourceGroupName
                'Location' = $vm.Location
                'VMSize' = $vm.HardwareProfile.VMSize
                'Status' = $null
                'AvailabilitySet' = $vm.AvailabilitySetReference.Id }
        
            $vmStatus = $vm | Get-AzureRmVM -Status
            $vmInfo.Status = $vmStatus.Statuses[1].DisplayStatus

            $vmobjs += $vmInfo

        }  
#>
    }
    catch
    {
        # Change this to get the full error message - if any
        Write-Host $error[0] | Format-List -Force
    }
}

# Comment this out for now, as it is moot, unitl you know you are getting something at all
<#
$vmobjs | Export-Csv -NoTypeInformation -Path $file
Write-Host "VM list written to $file"
#>

# If you are getting stuff back from just the above. Then good, if not, you need to figure out why.