Add a NIC to an Azure IaaS VM

At the moment if you want to add a new NIC to a VM, you will need to complete the attachment via PowerShell. You should be aware that a VM may need to be offline before you add the NIC too it.  You can follow the below to add your multiple NIC’s to your Azure VM’s.

N.B. Not all the virtual machines sizes support multiple NICs. Check if your VM size is supported ( https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-size-specs/)

 

#Get the VNET to which to connect the NIC
$VNET = Get-AzureRmVirtualNetwork -Name ‘<vNet>’ -ResourceGroupName ‘<ResourceGroup>’

#Get the Subnet ID to which to connect the NIC
$SubnetID = (Get-AzureRmVirtualNetworkSubnetConfig -Name ‘Subnet’ -VirtualNetwork $VNET).Id

#NIC Name
$NICName = ‘<vmname-ethvalue>’

#NIC Resource Group
$NICResourceGroup = ‘<ResourceGroup>’

#NIC creation location
$Location = ‘<Region>’

#Enter the IP address
$IPAddress = ‘<IP>’

#Create now the NIC Interface
New-AzureRmNetworkInterface -Name $NICName -ResourceGroupName $NICResourceGroup -Location $Location -SubnetId $SubnetID -PrivateIpAddress $IPAddress

$VMname = ‘<Name>’
$VMRG =  ‘<ResourceGroup>’

#Get the VM
$VM = Get-AzureRmVM -Name $VMname -ResourceGroupName $VMRG

#Add the second NIC
$NewNIC = Get-AzureRmNetworkInterface -Name $NICName -ResourceGroupName $NICResourceGroup
$VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $NewNIC.Id

#Show the Network interfaces
$VM.NetworkProfile.NetworkInterfaces

#We have to set one of the NICs to Primary, i will set the first NIC in this example
$VM.NetworkProfile.NetworkInterfaces.Item(1).Primary = $true

Convert VM’s to use Azure Hybrid Benefit for Windows Server with Azure PowerShell

As most people we always want to drop costs in our IT Infrastructure, with the new Azure Hybrid Benefit for Windows Server this is another way to save money.

Azure Hybrid Benefit for Windows Server allows you to use your on-premises Windows Server licenses and run Windows virtual machines on Azure at a reduced cost. This has been added to the Azure Resource Manager VM deployment process. You can historically go back through your current VM’s and utilise these savings if you are applicable.

Be aware that some VM sizes are not supported, so you may run into this issue.

# To login to Azure Resource Manager
Login-AzureRmAccount

# To select a default subscription for your current session
Set-AzureRmContext -SubscriptionId “<Subscription-ID>”

$VMs = Get-AzureRMVM | Where-Object {$_.LicenseType -eq “”}

foreach ($VM in $VMs) {

$vm.LicenseType = “Windows_Server”
Update-AzureRmVM -VM $VM -ResourceGroupName $VM.ResourceGroupName

}

Export Azure Resource Manager NSG Configurations

The following code will output your NSG configuration to a .txt file for review/backup.

function Get-AzureNSGConfiguration{

Login-AzureRmAccount
$subscriptionId = (Get-AzureRmSubscription |
Out-GridView `
-Title “Select an Azure Subscription” -OutputMode Single
).SubscriptionId
Select-AzureRmSubscription -SubscriptionId $subscriptionId

$outputArray = @()

foreach($AzureRmNetworkSecurityGroup in (Get-AzureRmNetworkSecurityGroup)){

foreach($SecurityRule in $AzureRmNetworkSecurityGroup.SecurityRules){

$NSG = New-Object -TypeName PSObject
$NSG | Add-Member -MemberType NoteProperty -Name Name -Value $SecurityRule.Name
$NSG | Add-Member -MemberType NoteProperty -Name Protocol -Value $SecurityRule.Protocol
$NSG | Add-Member -MemberType NoteProperty -Name SourcePortRange -Value $SecurityRule.SourcePortRange
$NSG | Add-Member -MemberType NoteProperty -Name DestinationPortRange -Value $SecurityRule.DestinationPortRange
$NSG | Add-Member -MemberType NoteProperty -Name SourceAddressPrefix -Value $SecurityRule.SourceAddressPrefix
$NSG | Add-Member -MemberType NoteProperty -Name DestinationAddressPrefix -Value $SecurityRule.DestinationAddressPrefix
$NSG | Add-Member -MemberType NoteProperty -Name Access -Value $SecurityRule.Access
$NSG | Add-Member -MemberType NoteProperty -Name Direction -Value $SecurityRule.Direction
$NSG | Add-Member -MemberType NoteProperty -Name SecurityGroup -Value $AzureRmNetworkSecurityGroup.Name
$outputArray += $NSG

}

 

}

$outputArray

}

Move an Azure IaaS VM between vNets

Recently i had a requirement to move a number of VM’s from one Azure vNet to another. This isnt possible in the current Azure Portal (although hopefully is coming based on the comments on the Azure Advisory forums – https://feedback.azure.com/forums/34192–general-feedback), therefore you will need to use PowerShell to do this.

Warning: This action does incur downtime, the method will remove the VM, keeping the disk and create a new VM attaching the kept disk. The disk should keep any installed applications, features or roles.

<# 

Author: HP, July 2017.

 
 

Move a VM that has un-managed disks between vNets: 

 
 

1. Delete VM from the portal. 

2. Create a NIC in the new vNet. 

3. Get the NIC name and add it to variable: $NIC1. 

4. Ensure all other variables are filled out 

5. Ensure that the correct subscription is your default with (Get-AzureRmContext).Subscription.  

   If wrong set with Set-AzureRmContextSubscriptionName “SUBID” –TenantId “TENANTID” 

6. Run below script. 

 
 

#> 

 
 

# To login to Azure Resource Manager 

Login-AzureRmAccount 

          

# To view all subscriptions for your account 

#Get-AzureRmSubscription 

          

# To select a default subscription for your current session 

#Get-AzureRmSubscriptionSubscriptionID “SUBID” | Select-AzureRmSubscription 

          

$RGName = “Resource_Group_Name 

$VMLocation = “VM_Location 

$VMSize = “Enter_VM_Size 

$VMName = “VM_Name 

$VM = New-AzureRmVMConfigVMName $VMNameVMSize $VMSize; 

           

$NIC1 = Get-AzureRmNetworkInterface -Name (“VM_Name“) –ResourceGroupName $RGName; 

$NIC1Id = $NIC1.Id; 

#Uncomment if deploying with Multiple NICs 

#$NIC2 = Get-AzureRmNetworkInterface -Name (“NIC2Name”) –ResourceGroupName $RGName; 

#$NIC2Id = $NIC2.Id; 

           

$VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $NIC1Id; 

#Uncomment if deploying with Multiple NICs 

#$VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $NIC2Id;              

           

$osDiskName = “Disk_Name 

$osDiskVhdUri = “Enter_VHD_URL.vhd 

           

$VM = Set-AzureRmVMOSDisk -VM $VM –VhdUri $osDiskVhdUri -name $osDiskNameCreateOption attach -Windows 

           

New-AzureRmVMResourceGroupName $RGName -Location $VMLocation -VM $VM -Verbose 

In total this will take around 20 minutes a VM. There are ofcourse some things to be mindful of, and i will list them below:

  • You will need to reconfigure your VM Extensions to any VM’s you move.
  • NIC’s in the new vNet will need to be re-created.
  • You will need to have necessary permissions to the relevant subscriptions to move resources.
  • Always test a move pre doing this in your live environment.

Manipulate Azure AutoShutdownSchedule runbook for Azure IaaS Patching

When on a customer site recently, one requirement the customer was looking to achieve was to incorporate their IaaS virtual machines into their monthly patching policy. Their Iaas VM’s were shutdown nightly and all day on a weekend by a runbook.

This can be done with a relatively simple PowerShell script split into two functions; Start-AzurePatching and Stop-AzurePatching. The logic of the Start-AzurePatching function is as follows:

  • Connect into Azure PowerShell and choose the subscription you want to work with.
  • First the script will aggregate the VM properties inside each resource group.
  • The runbook being used to shut down your VM’s is looking to interact with a Tag named “AutoShutdownSchedule”
  • If it finds any VM with the tag “AutoShutdownSchedule”  it will remove it, replacing it with one that will allow it to start on a Saturday.
  • The new tags will be set against the virtual machine
  • The VM’s will be started.

The logic of the Stop-AzurePatching is similar:

  • The script will again aggregate all the VM’s settings, specifically looking for VM’s with the “AutoShutdownSchedule” tag.
  • The tag set by Start-AzurePatching will be replaced with a tag that includes the original shutdown settings, meaning the VM’s will be shutdown on a saturday and sunday.
  • The new tags will then be applied to the VM’s.

There isn’t a need to then shut the machines down via this script, as the runbook upon its next cycle will identify these machines as being VM’s that should be offline, and shut them down for you.

<#
Azure Patching PowerShell script.
#>

Function Start-AzurePatching {

Login-AzureRmAccount
$subId = ( Get-AzureRmSubscription |
Out-GridView `
-Title “Select an Azure Subscription” -OutputMode Single
).SubscriptionId
Select-AzureRmSubscription -SubscriptionId $subId

foreach($AzureRmVm in (Get-AzureRmResourceGroup | Get-AzureRmVm))
{
if($AzureRmVm.Tags.Keys -like “*AutoShutdownSchedule*”)
{
$AzureRmVm.Tags.Remove(‘AutoShutdownSchedule’) | Out-Null
$AzureRmVm.Tags.Add(‘AutoShutdownSchedule’,’8PM -> 5AM, Sunday, December 25′) | Out-Null

Set-AzureRmResource -ResourceGroupName $AzureRmVm.ResourceGroupName -Name $AzureRMVm.Name -Tag $AzureRmVm.Tags -ResourceType ‘Microsoft.Compute/VirtualMachines’
}

}

Start-AzureRmVM -Name $AzureRmVm.Name -ResourceGroupName $AzureRmVm.ResourceGroupName
}

#Run this post patching, when you are ready for the servers to be turned off again.

function Stop-AzurePatching {

foreach($AzureRmVm in (Get-AzureRmResourceGroup | Get-AzureRmVm))
{
if($AzureRmVm.Tags.Keys -like “*AutoShutdownSchedule*”)
{
$AzureRmVm.Tags.Remove(‘AutoShutdownSchedule’) | Out-Null
$AzureRmVm.Tags.Add(‘AutoShutdownSchedule’,’8PM -> 5AM, Saturday, Sunday, December 25′) | Out-Null

Set-AzureRmResource -Confirm:$FALSE -ResourceGroupName $AzureRmVm.ResourceGroupName -Name $AzureRMVm.Name -Tag $AzureRmVm.Tags -ResourceType ‘Microsoft.Compute/VirtualMachines’
}
}

}

Login to Azure Powershell

I find this to be a handy addition to any Azure script or just to run when i open Azure Powershell, it allows me to sign into Azure along with using the Out-Grid to pick a subscription and Resource Group.

# Sign-in with Azure account credentials

Login-AzureRmAccount

# Select Azure Subscription

$subscriptionId =
(Get-AzureRmSubscription |
Out-GridView `
-Title “Select an Azure Subscription …” `
-PassThru).SubscriptionId

Select-AzureRmSubscription `
-SubscriptionId $subscriptionId

# Select Azure Resource Group

$rgName =
(Get-AzureRmResourceGroup |
Out-GridView `
-Title “Select an Azure Resource Group …” `
-PassThru).ResourceGroupName