Tuesday, September 29, 2020

Azure: Encrypting VM disks with Powershell using Azure key vault

 Encrypting disks in Azure for virtual machines can be a good idea if you have sensitive data on them. At current client the decision is to encrypt disks for domain controllers but not for general purpose VMs (as it adds a bit of administrative overhead and might impact performance - I don't have specific numbers on this).

If you have a key vault in place with the -EnabledForDiskEncryption parameter set it is relatively easy to configure on the VM. The VM has to be already running so it is a post step after install.

From the VM deploy script you can add the below code snippet to your script:

# Encrypt VM disks (should only be done for AD VMs and VMs with highly sensitive data)
Write-host "Checking if disks are encrypted on VM"

# Get key vault
$KeyVault = Get-AzKeyVault -VaultName $kvname -ResourceGroupName $secrgname

# Check if disk already encrypted, if not then encrypt it
if (Get-AzVmDiskEncryptionStatus -VMName $VMName -ResourceGroupName $ResourceGroupName | Where-Object {$_.OsVolumeEncrypted -eq "Encrypted"}){
    Write-host "Disk already encrypted"
else {
    Write-host "Encrypting disks"
    Set-AzVMDiskEncryptionExtension -ResourceGroupName $ResourceGroupName `
     -VMName $VMName `
     -DiskEncryptionKeyVaultUrl $KeyVault.VaultUri `
     -DiskEncryptionKeyVaultId $KeyVault.ResourceId `


  • $kvname: Name of the key vault
  • $secrgname: Name of the resource group where key vault resides
  • $VMName: Name of the VM
  • ResourceGroupName: Name of resource group where VM resides
Assuming you have the correct permissions set on the key vault, then the secret will be created automatically in the key vault. During the encrypt process the VM will reboot and it takes about 10 minutes depending on the size of the disks.

Wednesday, September 23, 2020

Azure: Delete tags on resource groups and resources with Powershell

 At current client we've been pushing out standard tags via Azure Policy to both resource groups and resources. One policy adds tags to the resource groups and another poicy inherits the tags from the resource groups to the resources (to only have to update tags in one place).

After some evaluation we found that we'd pushed too many tags and needed to delete some of them from some of the subscriptions.

There is no easy way to do this in bulk from the portal but it can be done with Powershell.

The logical command to use would be Remove-AzTag but apparently that is only for unused tags and so it won't work if you've added values to your tags.

To delete tags with values added to them, you need two different scripts. One for resource groups and one for the resources.

If you have an 'inherit tags' policy enabled that force changes on updates, then make sure to delete first the tags on the resource groups and then on the resources. Otherwise the tags will be re-written to the resources immediately on update.

Both scripts below will traverse all or selected subscriptions and delete tags.


# This script will delete the specified tag including values only on resources groups.

# Update this variable with tag name to be deleted. No tag value required.
$DeleteTag = "ContactEmail"

# Get all subscriptions in tenant
# $subscriptions = Get-AzSubscription
# To get all subscriptions except subscription named: SUBS NAME
# Replace -notlike with -eq to get a specific subscription
$subscriptions = Get-AzSubscription | Where-Object {$_.Name -notlike "SUBS NAME"}

# Traverse through all subscriptions
Foreach ($subscription in $subscriptions ) {

# Select a subscription    
Select-AzSubscription -subscriptionid $subscription

# Get list of resource groups in subscription
$rg = Get-AzResourceGroup
# For each resource group, get the associated tags and put into a variable
Foreach ($i in $rg.ResourceGroupName)
 $Tags = (Get-AzResourceGroup -Name $i).Tags
 # Remove the tag with the Name specified
 # Set the tags on the resource group
 Set-AzResourceGroup -Name $i -Tag $Tags



# This script will delete tags on all resources in all subscriptions, 
# however not on the resource groups, see DeleteTagsOnRGs.ps1 for that.
# Must run as .ps1 script, pasting into Cloud Shell will not work.
# Note, there can be a delay of 20-30 mins from running script until Tags appear 
# as deleted in the Portal
# Before running this script, ensure that tags are deleted at RG level first 
# otherwise they'll be re-added via the Inherit policy (if applied)

# To get all subscriptions
# $subs = Get-AzSubscription
# Get only a specific subscription
# $subs = Get-AzSubscription | Where-Object {$_.Name -eq "SUBS NAME"}
# To get all subscriptions except SUBS NAME
$subs = Get-AzSubscription | Where-Object {$_.Name -notlike "SUBS NAME"}

# Specify tag name
$tagname = "ContactEmail"
# Specify tag value
$tagvalue = "person@companyemail.com"

# Through all subscriptions, get resources with specified tag and value, 
# remove the tag from the array and update the resource
$subs | ForEach-Object {
    Set-AzContext $_
    $rs = Get-AzResource -TagName $tagname -TagValue $tagvalue
    $rs | ForEach-Object {
        $_ | Set-AzResource -Force

That's it.

Wednesday, September 16, 2020

Activate new Visual Studio subscription and start using credits in a new Azure AD tenant

 If you want to test code in Azure or you just want a sandbox to try things out, then having a Visual Studio (VS) subscription (formerly MSDN) is a good idea. This gives you a certain amount of dollars (or credits) to spend each month in Azure.

There are two types of subscriptions:

  • Visual Studio Professional (50 USD/month in credits)
  • Visual Studio Enterprise (150 USD/month in credits)
The subscription is personal to the employee and is typically acquired by the employer and assigned to the employee on the employee email address (you will receive an email with activation info from Microsoft). See pricing details here.

Activate Visual Studio subscription

Once you have been assigned a VS subscription, it has to be activated. Go to below link to activate:

Log in with your company email, if you don't have an account already, then create one (using company email).

Activate the monthly credits under the Featured Benefits section, see below:

You can view your subscription details under the Subscriptions tab:

Create new Azure AD tenant

When you log into Azure using your company credentials, you will typically see the company's AD tenant under Azure Active Directory, e.g. companyname.onmicrosoft.com. Since you'll likely have limited permissions in this tenant (AD tenant is similar to an AD domain, just in the cloud. It's also referred to as Directory) and since the aim it to create an isolated sandbox for testing, then a new AD tenant has to be created and the VS subscription associated with this tenant.

To create a new AD tenant, go to:

Go to: Create a resource -> Identity -> Azure Active Directory (see below):

Give your new AD tenant (or organisation) a name and click create:

Note that this will not affect the existing company AD tenant. Even though you create it while logged in with your company email, it will have no cost for the company and will only be manageable by you. I note this as I have discussed this with both colleagues and clients where they worry that they might break something in the company Azure AD. They won't.

Move your VS subscription to the new AD tenant

Once your new Azure AD is created, you can go to your VS subscription and change the directory so that the subscription will be associated with your new tenant.

  • Go to Subscriptions and choose your VS subscription
  • Under "Overview" choose "Change directory"
  • Choose your newly create Azure AD tenant (as opposed to the company AD tenant)
  • Click OK, see below two screen dumps:

Note that it can take a few hours before the changes kick in.

To switch around between tenants and also to choose your default tenant, click on your profile in upper right corner and choose your directory/tenant and/or default tenant, see below:

That's it! Now you can start using your monthly credits in a tenant that you have full control over.

To get an overview of current spending and to know when the monthly credits reset, see this post.

Thursday, September 10, 2020

Azure Firewall drops traffic to on-prem S2S VPN

We're currently setting up an Azure Firewall at a client site. Initial implementation was done by following the MS documentation: 


After deployment and after attaching a given subnet to the default route table (to force all outbound traffic to pass through the Azure Firewall), then there was no communication from the Azure subnet and to the local VPN gateway (S2S VPN to on-premises). Other subnets that weren't attached to the route table worked fine.

It seemed that new default route (see example below) might be overriding the existing default routes in Azure. And that the way forward would be to create additional routes to specify traffic to the VPN.

$routeTableDG = New-AzRouteTable `

-Name Firewall-rt-table ` -ResourceGroupName Test-FW-RG ` -location "East US" ` -DisableBgpRoutePropagation #Create a route Add-AzRouteConfig ` -Name "DG-Route" ` -RouteTable $routeTableDG ` -AddressPrefix ` -NextHopType "VirtualAppliance" ` -NextHopIpAddress $AzfwPrivateIP ` | Set-AzRouteTable

It turns out that the standard routes were fine. Only the default route to the internet is overridden (which is expected), the other two remain in use:

These are the standard routes that Azure creates:

"Each virtual network subnet has a built-in, system routing table. The system routing table has the following three groups of routes:
Local VNet routes: Directly to the destination VMs in the same virtual network.
On-premises routes: To the Azure VPN gateway.
Default route: Directly to the Internet. Packets destined to the private IP addresses not covered by the previous two routes are dropped."

The problem was that the property setting: "Propagate gateway routes" was set to "No", see below. This means that the VPN gateway routes are not visible/propagated to the subnets. To turn it on you can either do it from the portal or configure it via Powershell.

To do this in Powershell, simply remove the line: -DisableBgpRoutePropagation from the New-AzRouteTable command so it looks like below :

-Name Firewall-rt-table ` -ResourceGroupName Test-FW-RG ` -location "East US" #-DisableBgpRoutePropagation

This will set the property to: "False" which in the portal corresponds to "Yes".  You can see the "false" setting under Route table -> Export template.

When done, the published routes from the virtual gateway become visible under Route tables -> "your route table" -> Effective routes, like below, and traffic will flow to the on-prem site via VPN as well.

How to check Visual Studio limits and reset date in Azure

With a Visual Studio subscription (formerly MSDN) in Azure you get a monthly usage quoata which can be used for testing purposes. There are two types of subscription:

  • Visual Studio Professional (50 USD/month)
  • Visual Studio Enterprise (150 USD/month)

The subscription is personal to the employee and is typically acquired by the employer and assigned to the employee on the employee email address.

You can manage your subscription and activate it from here:


Once you start using the subscription (typically assicioated with a new Azure AD tenant that you create), you can see the current usage in https://portal.azure.com/ by going to:

Subscriptions -> Overview -> Scroll to the bottom of the page

Below image shows limit in local currency.

If you want to know when your monthly reset is (if you're running low), then on the same page click on the "Manage" button marked in green above.

This will take to https://account.azure.com/ where you can see reset date and cost breakdown, see below: