SharePoint Stuff

CISCO ASA RouteBase IKE V2 configuration

Written by Luke Smith. Posted in Microsoft

As of June 2017 update to the CISCO IOS you can now establish RouteBased VPN’s into Azure using VTI and IKEv2

RouteBased Connection was previously known as Dynamic Routing.

Minimum IOS Version: 9.8(1) Released 15th May 2017 (
Recommended IOS Version in a HA configuration: 9.8(1.5) (known bug in previous versions) or 9.8(2) released August 2017

Example below will create an Azure VpnGw1 VPN using an IPSec Custom Policy with BGP enabled (on the Azure End)

Below is the config sample for the CISCO ASA:

crypto ikev2 policy 3
crypto ikev2 policy 3
encryption aes-256
integrity sha
group 2
prf sha
lifetime seconds 28000

crypto ipsec ikev2 ipsec-proposal PROP-AZURE-PRD
protocol esp encryption aes-256
protocol esp integrity sha-1

crypto ipsec profile PROF-AZURE-PRD
set ikev2 ipsec-proposal PROP-AZURE-PRD
set pfs group24
set security-association lifetime kilobytes 102400000
set security-association lifetime seconds 27000

interface Tunnel 1

ip address
tunnel source interface outside
tunnel destination "Azure VPN Public IP"
tunnel mode ipsec ipv4
tunnel protection ipsec profile PROF-AZURE-PRD

tunnel-group "Azure VPN Public IP" type ipsec-l2l
tunnel-group "Azure VPN Public IP" ipsec-attributes
ikev2 remote-authentication pre-shared-key xxxxxx
ikev2 local-authentication pre-shared-key xxxxxx

route VPN-AZURE-PRD "Azure Address Space IP" "Azure Address Space Subnet" "Azure VPN Public IP"
route VPN-AZURE-PRD "Azure VPN Public IP"

Below is the powershell for an ARM based Azure VPN:

#based on

Select-AzureRmSubscription -SubscriptionName "Your Subscription Name" #Update Accordingly
$VirtualNetworkName = "Your VNET Name" #Update Accordingly
$ResourceGroup = "Your Resource Group Name" #Update Accordingly
$Location = "UK South" #Update Accordingly
$LocalGatewayName = "HeadOfficeVPN" #Update Accordingly
$HeadOfficeVPNIP = "Local VPN Public IP" #Update Accordingly
$LocalAddressPrefix = @("","","") #your local network ranges
$GatewayIpName = "Vnetgwpublicip1" #Update Accordingly
$GatewaySubnetName = "GatewaySubnet"
$GatewayIpConfigName = "Vnetgwconfig1" #Update Accordingly
$GatewayVPNType = "RouteBased" #Update Accordingly
$GatewaySKU = "VpnGw1" #Update Accordingly
$GatewayName = "VNetgw1" #Update Accordingly
$GatewayConnectionName = "VNetgw1toHeadOfficeVPN" #Update Accordingly
$PreSharedKey = "**************" #Your PreShared Key

#Create Local Network Gateway
New-AzureRmLocalNetworkGateway -Name $LocalGatewayname `
-Location "$location" -AddressPrefix $LocalAddressPrefix `
-GatewayIpAddress $HeadOfficeVPNIP -ResourceGroupName $ResourceGroup
#Create Public IP Address
$ipaddress = New-AzureRmPublicIpAddress -Name $GatewayIpName `
-ResourceGroupName $ResourceGroup -Location $location `
-AllocationMethod Dynamic

#Create Gateway IP addressing configuration
$subnet = Get-AzureRmVirtualNetworkSubnetConfig -Name $GatewaySubnetName -VirtualNetwork (Get-AzureRmVirtualNetwork -Name $VirtualNetworkName -ResourceGroupName $ResourceGroup)
$gwipconfig = New-AzureRmVirtualNetworkGatewayIpConfig -Name $GatewayIpConfigName -SubnetId $ -PublicIpAddressId $

#Create the VPN gateway

New-AzureRmVirtualNetworkGateway -Name $GatewayName -ResourceGroupName $ResourceGroup -Location $location -GatewaySKU $GatewaySKU -GatewayType Vpn -IpConfigurations $gwipconfig -EnableBgp $true -VpnType $GatewayVPNType

#IPSec Custom Policy

$ipsecpolicy = New-AzureRmIpsecPolicy -IkeEncryption AES256 -IkeIntegrity SHA1 -DhGroup DHGroup2 -IpsecEncryption AES256 -IpsecIntegrity SHA1 -PfsGroup PFS24 -SALifeTimeSeconds 27000 -SADataSizeKilobytes 102400000

#Gateway Name

$vnet1gw = Get-AzureRmVirtualNetworkGateway -Name $GatewayName -ResourceGroupName $ResourceGroup
$LocalGatewayName1 = Get-AzureRmLocalNetworkGateway -Name $LocalGatewayName -ResourceGroupName $ResourceGroup

New-AzureRmVirtualNetworkGatewayConnection -Name $GatewayConnectionName -ResourceGroupName $ResourceGroup -VirtualNetworkGateway1 $vnet1gw -LocalNetworkGateway2 $LocalGatewayName1 -Location $Location -ConnectionType IPsec -UsePolicyBasedTrafficSelectors $True -IpsecPolicies $ipsecpolicy -SharedKey $PreSharedKey

#Get GatewayPublicIP

Get-azurermpublicipaddress -name $gatewayipname -resourcegroup $resourcegroup

#Get BGP Information
$vnet1gw = Get-AzureRmVirtualNetworkGateway -Name $gatewayname -ResourceGroupName $resourcegroup

Good Luck

Restore Azure ARM Virtual Machine with Special Configuration

Written by Luke Smith. Posted in Microsoft

Below is a handy script for restoring a VM with Special Configuration

Please Note: this will only work where the VM still exists in the Azure. this process would be used to recover the VM from a previous day or if became corrupt. If the VM completely disappeared then additional steps will be required to manually recreate Availability Sets and NICs.

This script focus on restore NIC, ILB, Availability Sets , OMS, Diagnostic Settings and Antimalware

# Login to Azure PowerShell
$YourSubscriptionName= ''
Get-AzureRmSubscription –SubscriptionName $YourSubscriptionName | Select-AzureRmSubscription
Get-AzureSubscription –SubscriptionName $YourSubscriptionName | Select-AzureRmSubscription

#Set the restore date
$startDate = Get-Date -Date '21 December 2016 00:00:00'
$endDate = Get-Date -Date '21 December 2016 23:59:59'

#Global Settings
$loc = 'North Europe'
$rgname = ''
$VMName = ''
$RestoreVMName = $VMName #Only Change if you want to give the VM a New Name (for Testing)
$VaultName = ''
$StorageAccount = ''
$workspaceName = "" #The OMS Name

#XML Download name and location
$diagnosticsconfig_path = 'DiagnosticsPubConfig.xml'
$VMNameConfig_path = 'VMConfig.json'
$RestoreVMNameConfig_path = 'RestoreVMConfig.json'

#Backup Diagnostic Settings
$publicsettings = (Get-AzureRmVMDiagnosticsExtension -ResourceGroupName $rgname -VMName $vmname).PublicSettings
$encodedconfig = (ConvertFrom-Json -InputObject $publicsettings).xmlCfg
$xmlconfig = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encodedconfig))
$xmlconfig | Export-Clixml -Path $diagnosticsconfig_path

#Backup VM Settings
$VmObject = Get-AzureRmVM -ResourceGroupName $rgname -Name $Vmname
ConvertTo-Json -InputObject $VmObject | Out-File -FilePath $VMNameConfig_path
$destination_path = $VMNameConfig_path
$oldconfobj = ((Get-Content -Path $destination_path -Encoding Unicode)).TrimEnd([char]0x00) | ConvertFrom-Json

#Remember to remove the remark to remove the VM
#Remove-AzureRmVM -ResourceGroupName $rgname -Name $VMName

$vault = Get-AzureRmRecoveryServicesVault -Name $VaultName -ResourceGroupName $rgname
Set-AzureRmRecoveryServicesVaultContext -Vault $vault

$namedContainer = Get-AzureRmRecoveryServicesBackupContainer -ContainerType AzureVM –Status Registered -FriendlyName $RestoreVMName
$backupitem = Get-AzureRmRecoveryServicesBackupItem –Container $namedContainer –WorkloadType "AzureVM"

#Select the backup Set
$rp = Get-AzureRmRecoveryServicesBackupRecoveryPoint -Item $backupitem -StartDate $startdate.ToUniversalTime() -EndDate $enddate.ToUniversalTime()

#Start the Restore Process
$restorejob = Restore-AzureRmRecoveryServicesBackupItem -RecoveryPoint $rp[0] -StorageAccountName $StorageAccount -StorageAccountResourceGroupName $rgname

#Wait for Restore to complete
$restorejob = Get-AzureRmRecoveryServicesBackupJob -Job $restorejob
$details = Get-AzureRmRecoveryServicesBackupJobDetails -Job $restorejob

#Get Details from Backup Configuration Properties

$properties = $
$storageAccountName = $properties["Target Storage Account Name"]
$containerName = $properties["Config Blob Container Name"]
$blobName = $properties["Config Blob Name"]

Set-AzureRmCurrentStorageAccount -Name $storageaccountname -ResourceGroupName $rgname
$Restoredestination_path = $RestoreVMNameConfig_path
Get-AzureStorageBlobContent -Container $containerName -Blob $blobName -Destination $Restoredestination_path
$obj = ((Get-Content -Path $Restoredestination_path -Encoding Unicode)).TrimEnd([char]0x00) | ConvertFrom-Json
$vm = New-AzureRmVMConfig -VMSize $obj.HardwareProfile.VirtualMachineSize -VMName $VMName -AvailabilitySetId $ #$AvailabilitySet.Id

Set-AzureRmVMOSDisk -VM $vm -Name "osdisk" -VhdUri $obj.StorageProfile.OSDisk.VirtualHardDisk.Uri -CreateOption “Attach”
$vm.StorageProfile.OsDisk.OsType = $obj.StorageProfile.OSDisk.OperatingSystemType foreach($dd in $obj.StorageProfile.DataDisks)
$vm = Add-AzureRmVMDataDisk -VM $vm -Name "datadisk1" -VhdUri $dd.VirtualHardDisk.Uri -DiskSizeInGB 127 -Lun $dd.Lun -CreateOption Attach

#Connect existing NIC
$vm=Add-AzureRmVMNetworkInterface -VM $vm -Id $oldconfobj.NetworkInterfaceIDs[0]

$vm.StorageProfile.OsDisk.OsType = $obj.StorageProfile.OSDisk.OperatingSystemType
New-AzureRmVM -ResourceGroupName $rgname -Location $loc -VM $vm

#Attach Antimalware Extension
$RegularServer = @'
"AntimalwareEnabled": true,
"RealtimeProtectionEnabled": true,
"ScheduledScanSettings": {
"isEnabled": false,
"day": 1,
"time": 10,
"scanType": "Full"
"Exclusions": {
"Extensions": ".MDF;.LDF;.NDF",
"Paths": "%systemroot%:\\inetpub\\temp\\IIS",
"Processes": ""
$TypeHandlerVersion = ((Get-AzureRmVMExtensionImage -Location 'North Europe' -PublisherName 'Microsoft.Azure.Security' -Type 'IaaSAntimalware').Version[-1][0..2] -join '')
Set-AzureRmVMExtension -ResourceGroupName $rgname -VMName $vmname -Name 'IaaSAntimalware' -Publisher 'Microsoft.Azure.Security' -ExtensionType 'IaaSAntimalware' -SettingString $RegularServer -Location $loc -TypeHandlerVersion $TypeHandlerVersion

#Enable Diagnostic Logging
Set-AzureRmVMDiagnosticsExtension -ResourceGroupName $rgname -VMName $vmname -DiagnosticsConfigurationPath $diagnosticsconfig_path

#Attach OMS Resource
$workspace = (Get-AzureRmOperationalInsightsWorkspace).Where({$_.Name -eq $workspaceName})
if ($workspace.Name -ne $workspaceName)
Write-Error "Unable to find OMS Workspace $workspaceName. Do you need to run Select-AzureRMSubscription?"
$workspaceId = $workspace.CustomerId
$workspaceKey = (Get-AzureRmOperationalInsightsWorkspaceSharedKeys -ResourceGroupName $workspace.ReourceGroupName -Name $workspace.Name).PrimarySharedKey
Set-AzureRmVMExtension -ResourceGroupName $rgname -VMName $VMName -Name 'MicrosoftMonitoringAgent' -Publisher 'Microsoft.EnterpriseCloud.Monitoring' -ExtensionType 'MicrosoftMonitoringAgent' -TypeHandlerVersion '1.0' -Location $loc -SettingString "{'workspaceId': '$workspaceId'}" -ProtectedSettingString "{'workspaceKey': '$workspaceKey'}"