Azure Automation

Auditing Azure VMs Add Results to Azure Tables | Azure PowerShell

Having read Paulo Marques article Working with Azure Storage Tables from PowerShell I decided to make the edits to my auditing scripts and push the results into Azure Tables to act as a repository I have the ability to keep but also one that gives me more options. Moving forward we can look to update or pull this information out on demand or use it as a basis of a comparison.  I find it quite useful to have an independent record of the starting and end state of an environment pre and post any work undertaken.

There are a number of ways you can audit an Azure environment. With most of my customers I have implemented OMS, often using a combination of paid and free tiers to achieve the reporting they need to meet their own requirements and standards.

I’m a big fan of OMS, this script represent only one way to gather information and a chance to try something new in PowerShell.

To get started you’ll need to follow the instructions in Paulo’s article to install the correct module and from there I suggest following his guide as this will give you a good understanding how the commands operate. Once competed it is a straight forward process to integrate this in to any auditing script you currently have. The example below already has a table created.


# Variables for the environment set up 
# PLEASE NOTE the Azure Table has already been set up
$subscriptionName = "Subscription Name"
$resourceGroup = "Resource Group"
$storageAccount = "Storage Account"
$tableName = "Table"
$PartitionKey = "Partition Key"
$table = Get-AzureStorageTableTable -resourceGroup $resourceGroup -tableName $tableName -storageAccountName $storageAccount


# Call the status of each server and upload into the Azure Table
$rowcounter = 1 
$RGs = Get-AzureRMResourceGroup 
  
  foreach($RG in $RGs) 
   { 
     $VMs = Get-AzureRmVM -ResourceGroupName $RG.ResourceGroupName 
     foreach($VM in $VMs)
      
     { 
      $VMDetail = Get-AzureRmVM -ResourceGroupName $RG.ResourceGroupName -Name $VM.Name -Status 
      
      foreach ($VMStatus in $VMDetail.Statuses) 
       {                                             
        $VMStatusDetail = $VMStatus.DisplayStatus                                               
                                           
       }
    
        Add-StorageTableRow -table $table `
        -partitionKey $PartitionKey `
        -rowKey ([guid]::NewGuid().tostring()) `
        -property @{"ResourceGroup"=$RG.ResourceGroupName;"computerName"=$VM.name;"status"=$VMStatusDetail}
       $rowcounter++  

       } 
    }

This second example updates the values in the Azure Table. To do this we have to pull out the Computer / Server status from the Table and add this to the collected information as before.

# Variables for the environment set up 
# PLEASE NOTE the Azure Table has already been set up
$subscriptionName = "Wade - Internal Consumption"
$resourceGroup = "rg-ause-test-platform"
$storageAccount = "rgausetestplatform626"
$tableName = "table01"
$PartitionKey = "AUSSite"
$table = Get-AzureStorageTableTable -resourceGroup $resourceGroup -tableName $tableName -storageAccountName $storageAccount


# Call the status of each server and upload into the Azure Table
$rowcounter = 1 
$RGs = Get-AzureRMResourceGroup 
  
  foreach($RG in $RGs) 
   { 
     $VMs = Get-AzureRmVM -ResourceGroupName $RG.ResourceGroupName 
     foreach($VM in $VMs)
      
     { 
      $VMDetail = Get-AzureRmVM -ResourceGroupName $RG.ResourceGroupName -Name $VM.Name -Status 
      
      foreach ($VMStatus in $VMDetail.Statuses) 
       {                                             
        $VMStatusDetail = $VMStatus.DisplayStatus                                               
                                           
       }
    
# Creating the filter and getting original entity
[string]$filter = [Microsoft.WindowsAzure.Storage.Table.TableQuery]::GenerateFilterCondition("computerName ",[Microsoft.WindowsAzure.Storage.Table.QueryComparisons]::Equal,$VM.Name)
$computer = Get-AzureStorageTableRowByCustomFilter -table $table -customFilter $filter

# Changing values
$computer.status = $VMStatusDetail

# Updating the content
$computer | Update-AzureStorageTableRow -table $table

# Getting the entity again to check the changes
Get-AzureStorageTableRowByCustomFilter -table $table -customFilter $filter 

       } 
    }

Remember there is always a better way to do things and the only way we find out is if you have a go at sharing. I look forward to your versions and updates. Happy scripting!

Disclaimer:  Please note although I work for Microsoft the information provided here does not represent an official Microsoft position and is provided as is.

Adding a Public IP to an Existing Azure ARM VM

If you are not running a jump host in your environment I find from time to time that I need to add a Public IP to a NIC and connect to my virtual machine.

PowerShell is by far the easiest way to complete this task. The small script below outlines how to do this.

# New-AzurePublicRmIAddress creates the new IP - Run this first. 

new-azurermpublicIPAddress -Name testip -ResourceGroupName wpbackup -AllocationMethod Static -Location "Southeast Asia"

# Set the variables but getting the properties you need 
$nic = Get-AzurermNetworkInterface -ResourceGroupName Nameof ResourceGroup -Name NameofNIC
$pip = Get-AzurermPublicIPAddress -ResourceGroupName wpbackup -Name testip
$nic.IPConfigurations[0].PublicIPAddress=$pip

# Finally set the IP address against the NIC
Set-AzureRmNetworkInterface -NetworkInterface $nic

Disclaimer:  Please note although I work for Microsoft the information provided here does not represent an official Microsoft position and is provided as is.

Creating a VM from an Azure Image | Azure

Working with Azure in the enterprise means you will quickly want to create your own custom images.  In this introductory article I will show you an example of how to create an image from an existing generalized imaged.

Please note:

  • This is utilising the ARM model and does not apply to Classic.
  • This assumes you have created a generalized image in Azure and know where it is!
  • This process is not considering on premises VMs.
  • This process uses Windows images.

The following documents and articles were used to create the script below.  Many thanks to the efforts and hard work of the authors.

Create a Virtual Machine from a User Image by Philo

Upload a Windows VM image to Azure for Resource Manager deployments by Cynthia Nottingham

Cynthia shows how to create the image and find the URL of the uploaded image.  She also gives detailed examples of the PowerShell scripts required to create the new VM.

Philo uses variables for existing networks which I found very useful and just comment out the pieces I do not need, e.g. when the vnet already exists.

Happy VM creating!


$cred = Get-Credential
$rgName = "ResourceGroupName"
$location = "Azure Location"
$pipName = "Public IP address Name"
$pip = New-AzureRmPublicIpAddress -Name $pipName -ResourceGroupName $rgName -Location $location -AllocationMethod Dynamic
$subnet1Name = "Subnet Name"
$vnetSubnetAddressPrefix = "Subnet address e.g. 10.1.0.0/24"
$vnetAddressPrefix = "vnet address e.g. 10.1.0.0/16"
$nicname = "Name of Nic"
$vnetName = "Name of vnet"
$subnetconfig = New-AzureRmVirtualNetworkSubnetConfig -Name $subnet1Name -AddressPrefix $vnetSubnetAddressPrefix
#$vnet = New-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $rgName -Location $location -AddressPrefix $vnetAddressPrefix -Subnet $subnetconfig
$nic = New-AzureRmNetworkInterface -Name $nicname -ResourceGroupName $rgName -Location $location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id
$vmName = "Name of VM"
$vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize "Standard_A4"
$computerName = "Nameof Cumputer"
$vm = Set-AzureRmVMOperatingSystem -VM $vmConfig -Windows -ComputerName $computerName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id
$osDiskName = "Name of Disk"
$osDiskUri = '{0}vhds/{1}{2}.vhd' -f $storageAcc.PrimaryEndpoints.Blob.ToString(), $vmName.ToLower(), $osDiskName
$urlOfUploadedImageVhd = "URL to generaized image https://somename.blob.core.windows.net/system/Microsoft.Compute/Images/templates/name-osDisk.00aaaa-1bbb-2dd3-4efg-hijlkmn0123.vhd"
$vm = Set-AzureRmVMOSDisk -VM $vm -Name $osDiskName -VhdUri $osDiskUri -CreateOption fromImage -SourceImageUri $urlOfUploadedImageVhd -Windows
$result = New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vm
$result

Disclaimer:  Please note although I work for Microsoft the information provided here does not represent an official Microsoft position and is provided as is.