Search code examples
azurepowershellvirtual-machineazure-storageazure-storage-account

Merge Storage Account Name and SKU with VM Name in Powershell


I want to add StorageAccountName and its SKU to my report, this is the code I'm having now:

VMs = Get-AzureRmVM -Status

 $vmOutput = $VMs | ForEach-Object {
 [PSCustomObject]@{
 "VM Name" = $_.name
 "Private IP" =""
 "VM Type" = $_.StorageProfile.osDisk.osType
 "VM Profile" = $_.HardwareProfile.VmSize
 "Environment" = $_.Tags.Environment
 "Application" = $_.Tags.Application
 "Decommission Date" = $_.Tags.Decomission
 "OS Disk Size" = $_.StorageProfile.OsDisk.DiskSizeGB
 "Data Disks Total Size" = ($_.StorageProfile.DataDisks.DiskSizeGB | Measure -Sum).Sum
 "Data Disks Amount" = ($_.StorageProfile.DataDisks | Measure ).Count
 "Managed OS Disk" = ($_.StorageProfile.OSDisk.ManagedDisk | Measure).Count
 "Managed Data Disks" = ($_.StorageProfile.DataDisks.ManagedDisk | Measure).Count
 "Powerstate" = $_.PowerState
 }
 }

 $nics = get-azurermnetworkinterface | where VirtualMachine -NE $null
 $ips =@{}

 foreach($nic in $nics){
 $vm = $VMs | Where-Object -Property id -EQ $nic.VirtualMachine.id
 $prv = $nic.IpConfigurations | select-object -ExpandProperty PrivateIpAddress
 $ips.Add($vm.Name,$prv)
 }

 foreach($vm in $vmOutput)
 {
 if($ips.ContainsKey($vm."VM Name"))
 {
 $vm."Private IP"=$ips[$vm."VM Name"]
 }
 }

 $vmOutput | sort "Environment", "VM Type", "VM Profile", "Application" | export-csv VMReport.csv -delimiter ";" -force -notypeinformation

I tried to do it more less the same way IP addresses were implemented into this code, but it's much harder than I expected, as Get-AzureRmStorageAccount cmdlet doesn't store VirtualMachine.Id property like Get-AzureRMNetworkInterface cmdlet does.

Any ideas how can I merge it into one table? Is there any key upon which I can join both information? What I want to achieve is to add StorageAccountName and SKUName columns into the $vmOutput table.

Update:

$sat =@{}

$OutFile = "..."

#part1

foreach ($vmdetails in $VMs)
{
$ResourceGroupName=$vmdetails.ResourceGroupName
$VMName=$vmdetails.name
$storage=$vmdetails.StorageProfile.OsDisk.Vhd.Uri
$DataDiks=$vmdetails.StorageProfile.OsDisk.Name
$ss=$storage.split('/')[2]

$OSStorageAccountName=$ss.split('.')[0]
$DiskType="OSDisk"
$StroageAccountLocation=($StroageAccDetail | where  {$_.StorageAccountName -eq $OSStorageAccountName }).location
$StorageAccountType=($StroageAccDetail | where  {$_.StorageAccountName -eq $OSStorageAccountName }).AccountType
"$sub,$ResourceGroupName,$VMName,$DataDiks,$DiskType,$OSStorageAccountName" | Out-File -FilePath $OutFile -Append

$vmdatadisks=$vmdetails.StorageProfile.DataDisks

if($vmdatadisks -ne $null){
foreach($vmDatadsik in $vmdatadisks)
{
$vmDatadsikss=$vmDatadsik.vhd.uri
$DiskType="DataDisk"
$ss=$vmDatadsikss.split('/')[2]
$DataDiks=$vmDatadsik.Name
$dataStorageAccountName=$ss.split('.')[0]
"$sub,$ResourceGroupName,$VMName,$DataDiks,$DiskType,$OSStorageAccountName" | Out-File -FilePath $OutFile -Append
}
}
}

#part2

$VMs = Get-AzureRmVM -ResourceGroupName "..." -Name "..."
$storageAccountName = $VMs.StorageProfile.OsDisk.Vhd.Uri.Split("/")[2].Split(".")[0]
Get-AzureRmStorageAccount -StorageAccountName $storageAccountName -ResourceGroupName "..."

Solution

  • Please correct me if I'm misunderstanding you.

    Assume the sku you refer to the account storage's sku, you can also add placeholders in the $vmOutput for SA Name and SKUName.

     $VMs = Get-AzureRmVM -Status  
    
     $vmOutput = $VMs | ForEach-Object {
     [PSCustomObject]@{
     "VM Name" = $_.name
     "ResourceGroupName" =$_.ResourceGroupName #you must include this parameter
     "storage" = $_.StorageProfile.OsDisk.Vhd.Uri #you must include this parameter
     #your other property
     #add placeholder for SA Name and SKUName like below
     "StorageAccountName" =""
     "StorageAccountSKUName" =""
    }
    }
    

    Then, iterate all the vms in $vmoutput, and find the related storage account and sku, then add value to the $vmoutput:

    foreach($v in $vmOutput){
    $resourceGroups = $v.ResourceGroupName
    $storage=$v.storage
    
    if($storage -ne $null)
    {
    $ss=$storage.split('/')[2]
    $OSStorageAccountName=$ss.split('.')[0]
    
    $s1 = Get-AzureRmStorageAccount -ResourceGroupName $resourceGroups -StorageAccountName $OSStorageAccountName
    
    #add the value to $vmoutput
    $v.StorageAccountName =$OSStorageAccountName
    $v.StorageAccountSKUName=$s1.Sku.name
    }
    else
    {
    $v.StorageAccountName ="no value"
    $v.StorageAccountSKUName="no value"
    }
    }