Azure Automation: VMList To Storage Account

2 minute read

Description:

So one task I wanted to setup after deploying an Automation Account via Terraform was to show an example of how I can use the Automation Account to write blobs to a Storage Account.

To Resolve:

  1. First, just add a few resources to main.tf from before and then redeploy to Azure.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    resource "azurerm_storage_account" "storage" {
       name                     = "storageaccountname"
       resource_group_name      = azurerm_resource_group.example.name
       location                 = azurerm_resource_group.example.location
       account_tier             = "Standard"
       account_replication_type = "GRS"
    }
    
    
    resource "azurerm_role_assignment" "storage_blob_contributor" {
       scope                = azurerm_storage_account.storage.id
       role_definition_name = "Storage Blob Data Contributor"
       principal_id         = azurerm_automation_account.aa.identity[0].principal_id
    }
    
    
  2. Next I wrote a script that will upload a blob of all VMs for all subscriptions that my System Identity has read access to :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    
    Import-Module Az.Automation
    Import-Module Az.Storage
    
    Try
    {
       "Logging in to Azure..."
       # https://docs.microsoft.com/en-us/azure/automation/enable-managed-identity-for-automation
       Disable-AzContextAutosave -Scope Process
       $AzureContext = (Connect-AzAccount -Identity).context
       $AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext
       "Logging in to Azure...Completed"
    }
    Catch 
    {
       Write-Error -Message $_.Exception
       throw $_.Exception
    }
    
    Set-AzContext -Subscription "my-subscription"
    
    Function Get-StorageAccountName
    {
       $val = (Get-AzAutomationVariable -Name "linked-storage-account" -AutomationAccountName "my-automation-account" -ResourceGroupName "my-automation-account-rg" -ErrorAction "Stop").value
       return $val
    }
    
    Try
    {
       $StorageAccountName = Get-StorageAccountName
    }
    Catch {
       Write-Output "Error while attempting to get StorageAccountName variable..."
       Write-Error "Exit"
    }
    
    # Generate a SAS so we can write to file later
    $StartTime = Get-Date
    $EndTime = $startTime.AddHours(1.0)
    $stgAccount = Get-AzStorageAccount -Name $StorageAccountName -ResourceGroupName "my-automation-account-rg" 
    Write-Output "Storage Account: $($stgAccount.StorageAccountName)"
    $SASToken = New-AzStorageAccountSASToken -Service "Blob" -ResourceType "Container","Object" -Permission "racwdlup" -startTime $StartTime -ExpiryTime $EndTime -Context $($StgAccount.Context)
    $stgcontext = New-AzStorageContext -storageAccountName $($stgAccount.StorageAccountName) -SasToken $SASToken
    
    $Subscriptions = Get-AzSubscription -DefaultProfile $AzureContext
    
    $VMList = [System.Collections.Generic.List[PSObject]]@()
    $Intro = 'Subscription,Subscription_ID,VM_Name,ResourceID' # Enter column names
    [void]$VMList.Add($Intro)
    
    Foreach ( $Subscription in $Subscriptions)
    {
       $CurrentContext = Set-AzContext -Subscription $($Subscription.Name)
    
       $SubscriptionName = $($CurrentContext.Subscription.Name)
       $SubscriptionID = $($CurrentContext.Subscription.Id)
       Write-Output "Current subscription: $SubscriptionName"
    
       $VMObjects = Get-AZVM -DefaultProfile $CurrentContext
       If ( $($VMObjects.count) -gt 0)
       {
          Foreach ( $VM in $VMObjects)
          {
             #Write-Output "Virtual machine name: $($VM.Name)" 
    
             $CSVRow = $SubscriptionName, $SubscriptionID, $($VM.Name), $($VM.Id) -join ","
             #Write-Output "Adding row to CSV: $CSVRow"
             [void]$VMList.Add($CSVRow)
             
          }
       }
       Else
       {
          Write-Output "Subscription has no VM objects" 
    
          $CSVRow = $SubscriptionName, $SubscriptionID, "null", "null" -join ","
          #Write-Output "Adding row to CSV: $CSVRow"
          [void]$VMList.Add($CSVRow)
       }
    }
    
    # 
    $OutputFileName = ((Get-Date -Format "yyyy-MM-dd") + "-vmlist.csv")
    Write-Output "Output file: $OutputFileName"
    $VMList | Out-File $OutputFileName -Encoding "ascii"
    
    Write-Output "Writing CSV and exiting..."
    Set-AzStorageBlobContent -File $OutputFileName -Container "vminventory" -Context $stgcontext -Force
    Write-Output "Writing CSV and exiting...Completed"