skip to Main Content

I am trying to export VM data from Azure and below script is working perfect if subscription has VMs however it does create a .csv if there is no data (VMs) and I need that even if there is no data powershell should create a blank csv. Below is my script which is working fine if subscription has VMs created in it.

function create($path) {
    $exists = Test-Path -path $path
    Write-Host "tried the following path: $path, it" $(If ($exists) {"Exists"} Else {"Does not Exist!"}) 
    if (!($exists)) { New-Item $path -itemType Directory }
}

# reading file contents 
$subs_file =  "C:ScrptingSubscriptionsSubscriptions.xlsx"
$azSubs = Import-Excel $subs_file
$azSubs
$output_folder = "C:audit-automation"
# creating folder for outputing data 
create("$output_folder")
# New-Item $output_folder -itemType Directory

# iterating over subscriptions 
ForEach ( $sub in $azSubs ) {
    # sub
    $azsub = $sub.Subscription
    # app
    $app = $sub.Application
    $azsub
    $app
    # creating folder to save data for apps  
    # New-Item $output_folder$app -itemType Directory
    # setting config for azure 
    Set-AzContext -SubscriptionName $azsub
        # GET VM INFO
    $vms = Get-AzVM
    $vmrg = Get-AzVM | Select-Object "ResourceGroupName"
    $nics = get-AzNetworkInterface | Where-Object { $_.VirtualMachine -NE $null }
    # creating folder to save 
    # New-Item $output_folder$appvm_info -itemType Directory
    create("$output_folder$app")
    ForEach ($nic in $nics) {
        $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
        $vm = $vms | ? -Property Id -eq $nic.VirtualMachine.id
        $info.NICName = $nic.Name
        $info.VMName = $vm.Name
        $info.SubscriptionID = $azsub
        $info.ResourceGroupName = $vm.ResourceGroupName
        $info.PrivateIPAddress = $nic.IpConfigurations.PrivateIpAddress
        $PublicIPAddress =
        (Az vm list-ip-addresses --name $vm.Name --resource-group $vm.ResourceGroupName | ConvertFrom-Json).virtualMachine.network.publicIpAddresses.ipaddress
        $info.PublicIPAddress = if ($null -eq $PublicIPAddress ) { "Not Assigned" } else { $PublicIPAddress }
        $info.OS = $vm.StorageProfile.osDisk.osType
        $info.Status = ((Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses[1]).code
        $info | Export-Csv -Path $output_folder$app$app-vm_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append
    }}

2

Answers


  1. add outside the loop, since $vms may be empty

    if (!($vms)){
        $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
        $info | Export-Csv -Path $output_folder$app$app-vm_data$((Get-Date).ToString("yyyy-MM-dd")).csv -Append
    

    }

    Login or Signup to reply.
  2. You can remove the function create and replace that with just the one line $null = New-Item $output_folder -ItemType Directory -Force.
    On file system, the -Force makes the cmdlet return either the DirectoryInfo object of an existing folder or create a new folder and return that.
    (don’t use this on registry keys!)

    Next, if you capture the output you want in the CSV file first, it is easy enough to check if there is output or not and if not, write an empty csv file (only the headers will be in there)

    Something like this:

    # reading file contents 
    $subs_file = "C:ScrptingSubscriptionsSubscriptions.xlsx"
    $azSubs    = Import-Excel $subs_file
    #$azSubs
    $output_folder = "C:audit-automation"
    # creating folder for outputing data 
    $null = New-Item $output_folder -ItemType Directory -Force
    
    # iterating over subscriptions 
    foreach($sub in $azSubs) {
        # sub
        $azsub = $sub.Subscription
        # app
        $app = $sub.Application
        $azsub
        $app
    
        # setting config for azure 
        Set-AzContext -SubscriptionName $azsub
        # GET VM INFO
        $vms  = Get-AzVM
        $vmrg = Get-AzVM | Select-Object "ResourceGroupName"
        $nics = Get-AzNetworkInterface | Where-Object { $null -ne $_.VirtualMachine }
        # creating folder to save 
        $null = New-Item (Join-Path -Path $output_folder -ChildPath $app) -ItemType Directory -Force
    
        # capture the output of the foreach loop
        $result = foreach ($nic in $nics) { 
            $info = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
            $vm   = $vms | ? -Property Id -eq $nic.VirtualMachine.id
            $info.NICName = $nic.Name
            $info.VMName  = $vm.Name
            $info.SubscriptionID    = $azsub
            $info.ResourceGroupName = $vm.ResourceGroupName
            $info.PrivateIPAddress  = $nic.IpConfigurations.PrivateIpAddress
            $PublicIPAddress = (Az vm list-ip-addresses --name $vm.Name --resource-group $vm.ResourceGroupName | 
                                ConvertFrom-Json).virtualMachine.network.publicIpAddresses.ipaddress
            $info.PublicIPAddress = if ($null -eq $PublicIPAddress ) { "Not Assigned" } else { $PublicIPAddress }
            $info.OS     = $vm.StorageProfile.osDisk.osType
            $info.Status = ((Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses[1]).code
            # output the object to be collected in variable $result
            $info
        }
        # test if you actually have data now in the $result variable
        if (!@($result.Count)) {
            # no data; create an empty csv with just the headers
            $result = "" | Select VMName, ResourceGroupName, OS, PrivateIPAddress, PublicIPAddress, SubscriptionID, Status, NICName
        }
        $outFile = Join-Path -Path $output_folder -ChildPath ('{0}{0}-vm_data{1:yyyy-MM-dd}.csv' -f $app, (Get-Date))
        $result | Export-Csv -Path $outFile -NoTypeInformation
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search