Configuring Azure ExpressRoute using PowerShell

Microsoft Azure ExpressRoute is a private connection from on-premises networks to the Microsoft cloud over a private peering facilitated by a network service provider. With ExpressRoute, you can establish a faster, low latencies and reliable connection to Microsoft cloud services, such as Microsoft Azure, Office 365, and Dynamics 365. ExpressRoute is available to all continent and in all geopolitical boundaries.

ExpressRoute Circuit Connectivity Model

  • Co-located at a cloud exchange- The on-premises infrastructure is co-located in a facility with Microsoft Azure Cloud, you can order virtual cross-connections to the Microsoft cloud through the co-location provider’s Ethernet exchange. Data center providers can offer either Layer 2 cross-connections, or managed Layer 3 cross-connections between your infrastructure in the colocation facility and the Microsoft cloud.
  • Point-to-point Ethernet connections- You can connect your on-premises infrastructure to the Microsoft cloud through point-to-point Ethernet links. Point-to-point Ethernet providers can offer Layer 2 connections, or managed Layer 3 connections between your site and the Microsoft cloud.
  • Any-to-any (IPVPN) networks- You can integrate company WAN with the Microsoft cloud. IPVPN providers are typically MPLS connection between your branch offices and data centers. The Microsoft cloud can be interconnected to company WAN to make it look just like another branch office.

Key Features:

  • Layer 3 connectivity between your on-premises network and the Microsoft Cloud through a connectivity provider.
  • Connectivity to Microsoft cloud services across all regions in the geopolitical region.
  • Global connectivity to Microsoft services across all regions with an ExpressRoute premium add-on.
  • Dynamic routing between your network and Microsoft over industry standard protocols (BGP).
  • Built-in redundancy in every peering location for higher reliability.
  • QoS support for Skype for Business.
  • Bandwidth starting from 50Mbps to 10Gbps

Subscription requirements:

  • A valid and active Microsoft Azure account or an active Office 365 subscription. This account is required to set up the ExpressRoute circuit. ExpressRoute circuits are resources within Azure subscriptions.

Partners Requirements:

Network requirements:

  • Redundant connectivity-Microsoft requires redundant BGP sessions to be set up between Microsoft’s routers and the peering routers, even when you have just one physical connection to a cloud exchange.
  • Routing-ExpressRoute provider needs to set up and manage the BGP sessions for routing domains. Some Ethernet connectivity provider or cloud exchange provider may offer BGP management as a value-add service.
  • NAT-Microsoft only accepts public IP addresses through Microsoft peering. If you are using private IP addresses in your on-premises network, you or your provider need to translate the private IP addresses to the public IP addresses using the NAT.
  • QoS-Skype for Business has various services (for example; voice, video, text) that require differentiated QoS treatment. You and your provider should follow the QoS requirements.
  • Network Security- consider network security when connecting to the Microsoft Cloud via ExpressRoute.

ExpressRoute Peering

  • Private peering- The private peering domain is considered to be a trusted extension of on-premises core network into Microsoft Azure. You can set up bi-directional connectivity between your core network and Azure virtual networks.
  • Public peering- In a simple terminology, the public peering is a network peering between public domain to on-premises DMZ and connect to all Azure services on their public IP addresses from company WAN without having to connect to the internet.
  • Microsoft peering- ExpressRoute provides private network connectivity to Microsoft cloud services. Infrastructure and platform services running in Azure often benefit by addressing network architecture and performance considerations. Therefore, we recommend enterprises use ExpressRoute for Azure.
  • Microsoft peering is used specifically for SaaS like Office 365 and Dynamics 365, were created to be accessed securely and reliably via the Internet. Therefore, we only recommend ExpressRoute for these applications in specific scenarios.

 Provisioning an ExpressRoute

Step1: Login and Select the subscription



Copy the name of the subscription to be used for next command.

Select-AzureRmSubscription -SubscriptionId “Company Default”

Step2: Copy the name of the ExpressRoute Provider information to be used for next command.

Name, PeeringLocations, BandwidthsOffered, Sku


Step3: Create new ExpressRoute

New-AzureRmExpressRouteCircuit -Name “On-premtoAzureCloud” -ResourceGroupName “ExpressRouteRG” -Location “Australia East” -SkuTier Standard -SkuFamily MeteredData -ServiceProviderName “Equinix” -PeeringLocation “Sydney” -BandwidthInMbps 200

Once you have created new ExpressRoute, you will see the below status of ExpressRoute.

NotProvisioned & Enabled, Provisioning & Enabled, Provisioned & Enabled

Step4: Record Subscription ID, service Key, Location and send this information to your ExpressRoute circuit provider to provision and activate services.

get-help New-AzureRmExpressRouteCircuit –detailed

Step5: List of All ExpressRoute and record the information for next command

Get-AzureRmExpressRouteCircuit -Name “ExpressRouteARMCircuit” -ResourceGroupName “ExpressRouteResourceGroup”

Step5: Connect a virtual network in the same subscription to a circuit

$circuit = Get-AzureRmExpressRouteCircuit -Name “MyCircuit” -ResourceGroupName “MyRG”

$gw = Get-AzureRmVirtualNetworkGateway -Name “ExpressRouteGw” -ResourceGroupName “MyRG”

$connection = New-AzureRmVirtualNetworkGatewayConnection -Name “ERConnection” -ResourceGroupName “MyRG” -Location “East US” -VirtualNetworkGateway1 $gw -PeerId $circuit.Id -ConnectionType ExpressRoute

Step6: Create Azure private peering for Azure Services

Make sure that you have the following items before you proceed with the next steps:

  • A /30 subnet for the primary and secondary link. This must not be part of any address space reserved for virtual networks.
  • A valid VLAN ID to establish this peering on. Ensure that no other peering in the circuit uses the same VLAN ID.
  • AS number for peering. You can use both 2-byte and 4-byte AS numbers. You can use a private AS number for this peering. Ensure that you are not using 65515.

$ckt = Get-AzureRmExpressRouteCircuit -Name “ExpressRouteARMCircuit” -ResourceGroupName “ExpressRouteResourceGroup”

Add-AzureRmExpressRouteCircuitPeeringConfig -Name “AzurePrivatePeering” -ExpressRouteCircuit $ckt -PeeringType AzurePrivatePeering -PeerASN 100 -PrimaryPeerAddressPrefix “” -SecondaryPeerAddressPrefix “” -VlanId 200

Set-AzureRmExpressRouteCircuit -ExpressRouteCircuit $ckt

Get-AzureRmExpressRouteCircuitPeeringConfig -Name “AzurePrivatePeering” -Circuit $ckt

Step7: Configure Azure public peering for the circuit if you require a public peering refer to the explanation section.

  • Make sure that you have the following information before you proceed further:
  • A /30 subnet for the primary and secondary link. This must be a valid public IPv4 prefix.
  • A valid VLAN ID to establish this peering on. Ensure that no other peering in the circuit uses the same VLAN ID.
  • AS number for peering. You can use both 2-byte and 4-byte AS numbers.

Add-AzureRmExpressRouteCircuitPeeringConfig -Name “AzurePublicPeering” -ExpressRouteCircuit $ckt -PeeringType AzurePublicPeering -PeerASN 100 -PrimaryPeerAddressPrefix “” -SecondaryPeerAddressPrefix “” -VlanId 100

Set-AzureRmExpressRouteCircuit -ExpressRouteCircuit $ckt

Step8: Configure Microsoft peering for the circuit if you require a public peering refer to the explanation section.

  • Make sure that you have the following information before you proceed:
  • A /30 subnet for the primary and secondaary link. This must be a valid public IPv4 prefix owned by you and registered in an RIR / IRR.
  • A valid VLAN ID to establish this peering on. Ensure that no other peering in the circuit uses the same VLAN ID.
  • AS number for peering. You can use both 2-byte and 4-byte AS numbers.
  • Advertised prefixes: You must provide a list of all prefixes you plan to advertise over the BGP session. Only public IP address prefixes are accepted. You can send a comma separated list if you plan to send a set of prefixes. These prefixes must be registered to you in an RIR / IRR.
  • Customer ASN: If you are advertising prefixes that are not registered to the peering AS number, you can specify the AS number to which they are registered. This is optional.
  • Routing Registry Name: You can specify the RIR / IRR against which the AS number and prefixes are registered.

Add-AzureRmExpressRouteCircuitPeeringConfig -Name “MicrosoftPeering” -ExpressRouteCircuit $ckt -PeeringType MicrosoftPeering -PeerASN 100 -PrimaryPeerAddressPrefix “” -SecondaryPeerAddressPrefix “” -VlanId 300 -MicrosoftConfigAdvertisedPublicPrefixes “” -MicrosoftConfigCustomerAsn 23 -MicrosoftConfigRoutingRegistryName “ARIN”

Set-AzureRmExpressRouteCircuit -ExpressRouteCircuit $ckt

To Upgrade the SKU from metered to unlimited. Implement the below command to upgrade ExpressRoute SKU

$ckt = Get-AzureRmExpressRouteCircuit -Name “ExpressRouteARMCircuit” -ResourceGroupName “ExpressRouteResourceGroup”

$ckt.Sku.Family = “UnlimitedData”

$ckt.sku.Name = “Premium_UnlimitedData”

Set-AzureRmExpressRouteCircuit -ExpressRouteCircuit $ckt

Login to Exchange Online PowerShell using MFA

Once you enable MFA on Admin account, you will be denied access to EXO using PowerShell until you update Azure PowerShell version to latest.

Download and install Microsoft Online Services Sign-In Assistant and Azure Active Directory Connection preview

Use Connect-MsOlService Cmdlets, you will prompted to signin in a browser with MFA. Once correct MFA is provided, you are signed into Office 365.

Create Azure Internal Load Balancer using PowerShell

Input Parameters:

Subnets: Subnet_10.x.x.x
Resource Groups (Service Name): ServerGroup1
VMs: Server1, Server2
InternalLoadBalancerName: InternalLB1
Port: 443

Find the Subnets where you would like to create a internal load balancer.


Find the VMs which you would like to add to this internal load balancer

Get-AzureVM -ServiceName ServerGroup1

Create a Internal Network

Add-AzureInternalLoadBalancer -ServiceName ServerGroup1 -InternalLoadBalancerName InternalLB1 -SubnetName “Subnet_10.x.x.x” -StaticVNetIPAddress 10.x.x.x

Add VM to this network

Get-AzureVM -ServiceName ServerGroup1 -Name Server1 | Add-AzureEndpoint -LBSetName “InternalLB1” -Name “InternalLB1” -DefaultProbe -InternalLoadBalancerName “InternalLB1” -Protocol tcp -PublicPort 443 -LocalPort 443 -LoadBalancerDistribution sourceIP | Update-AzureVM

Add second VM to this network

Get-AzureVM -ServiceName ServerGroup1 -Name Server2 | Add-AzureEndpoint -LBSetName “InternalLB1” -Name “InternalLB1” -DefaultProbe -InternalLoadBalancerName “InternalLB1” -Protocol tcp -PublicPort 443 -LocalPort 443 -LoadBalancerDistribution sourceIP | Update-AzureVM

Add multiple users to Office 365 security groups using PowerShell Scripts

Step1:  Connect MSOL Services


Step2: Find out ObjectID of the Security Group you would like add members to

Get-MsolGroup –Maxresults 100000 | Where-Object {$_.DisplayName -eq “Test Security Group”}

Get-MsolGroup –ObjectId “af407072-7ae1-4b07-a0ca-6634b7396054”


Sign-in to Portal.Azure.Com and Select Azure Active Directory>Security Groups>Search the Group>Go to properties of the group and copy the ObjectID

Step3: Create a CSV file with a header UserPrincipalName and list all email addresses in one column of CSV file e.g.


Step4: Execute the PowerShell Script to add users into the Security group

Copy the script and paste it in a notepad. Rename the notepad to Add-MsolGroupMembers.PS1

Import-CSv -Path “c:\Temp\testscript.CSV” | ForEach {


$Users=Get-MsolUser -UserPrincipalName $UPN

$Groupid = Get-MsolGroup -ObjectId “0c3c9f82-2392-43cc-bc00-b0d7b5734ac4”

$Users | ForEach {Add-MsolGroupMember -GroupObjectId $GroupID.ObjectID -GroupMemberObjectId $Users.ObjectID -GroupMemberType User}


Run the scripts

On-prem to Office 365 Migration: PowerShell Script Collection

Connect to Azure Active Directory PowerShell without Password Prompt

#Use Case: Log on to Office 365 tenant without typing credentials.


$Password=ConvertTo-SecureString -String “MyPassword” -AsPlainText -Force

$O365CREDS= New-Object –TypeName “System.Management.Automation.PSCredential” –ArgumentList $User, $Password

#$O365CREDS = Get-Credential -Username Raihan@tenant.OnMicrosoft.Com

$SESSION = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $O365CREDS -Authentication Basic -AllowRedirection

Import-PSSession $SESSION

Connect-MsolService -Credential $O365CREDS

Create New UPN Suffix

#Use Case: Create New UPN Suffix in Active Directory to match email domain.

Get-ADForest | Set-ADForest -UPNSuffixes @{add=””}

 Changing  UPN Suffix from CSV Input


#Use Case: Changing .local domain to email domain before the Office 365 migration.

#CSV header of input file is Loginid and each row containing one samaccountname.

 $oldSuffix = ‘’

$newSuffix = ‘’

Import-CSV userlist.csv | ForEach-Object {

$usr = get-aduser $_.loginid |Select userprincipalname, samaccountname

$newUpn = $usr.UserPrincipalName.Replace($oldSuffix,$newSuffix)

Set-ADUser -identity $usr.samaccountname -UserPrincipalName $newUpn -Verbose


 Changing UPN Suffix to Match Email Address

#Use Case: To match UPN suffix with primary email address on the general properties of Active Directory users.

Step 1: Export all UserPrincipalNames and Email Addresses from the AD to a CSV File.

Get-AdUser -Filter * -Properties UserPrincipalName, Name, EmailAddress | Select-Object UserPrincipalName, Name, EmailAddress | Export-CSV -Path C:\MyADUsers.csv -NoTypeInformation

Step 2: Use that CSV file to bulk change the UserPrincipalNames to match those Email Addresses.

CSV Headers are UserPrincipalName and EmailAddress

#Script to Change the UPN on the Active Directory#

#This script should run from an Active Directory Module for Windows PowerShell#

$UserCount = 0

Import-Csv -Path C:\MyADUsers.csv | ForEach-Object {

$UPN = $_.UserPrincipalName

Write-Host “Working on user:” $UPN

Get-ADUser -Filter {UserPrincipalName -Eq $UPN} | Set-AdUser -userprincipalname $_.EmailAddress

$usercount = $usercount +1


Write-Host “Number of users on your CSV: $UserCount”

Write-Host “UPN’s Changed”

 Changing UPN to Match SMTP

  #Use Case: Select all users in a domain and assign new UPN in bulk

Get-ADUser -Filter {mail -like “*”} -Properties Mail | Foreach { Set-ADUser $_ -UserPrincipalName $_.mail }

Above command will copy primary SMTP of each user and make that SMTP to match UPN suffix. To complete this task, you must pre-populate primary SMTP before you run this command.

 Changing UserName to FirstName.LastName

#Use Case: If you have a scenario where username is but your username should match the SMTP which is . In this scenario you can extract all username from Active Directory, create a CSV or txt file with one column with just username and no then the below script will modify username from FirstName to

Get-Content .\users.csv | foreach { .\Update-Username.ps1 –Username $_ –UPNSuffix -LogFile .\changes.txt -WhatIf }


Add Alias and Set as Primary SMTP


#Use case: You have synchronized all users from on-prem Active Directory to Azure Active Directory but users email address is showing default domain e.g. Now you want to add a alias and set that alias as primary SMTP to match email domain. 

 Import-Csv c:\data.csv | Foreach{

$maileg = Get-Mailbox -Identity $_.Name

$maileg.EmailAddresses += $_.emailaddress

$maileg | Set-Mailbox -EmailAddresses $maileg.EmailAddresses -PrimarySmtpAddress $_.emailaddress


 Assign Office 365 licenses from CSV File Input

#Use Case: Assign licenses in bulk. 

Step1: Find Current Sku

Get-MsolAccountSkuId to find out current Sku

Step2: Create a CSV file with UserPrincipalName as header e.g.

Step3: Run the command.

$path= Import-Csv -Path “C:\CSV\E1Licenses.csv”

foreach ($item in $path){

$MSOLUserName= $item.UserPrincipalName

$AccountSkuId = “tenant:STANDARDPACK”

$UsageLocation = “AU”

$LicenseOptions = New-MsolLicenseOptions -AccountSkuId $AccountSkuId

Set-MsolUser -UserPrincipalName $MSOLUserName -UsageLocation $UsageLocation

Set-MsolUserLicense -UserPrincipalName $MSOLUserName -AddLicenses $AccountSkuId  -LicenseOptions $LicenseOptions



  • For E1 license is StandardPack and for E3 license is EnterprisePack
  • For Country Code, use ISO 3166 two-letter country-code standard e.g. Australia is AU

 Reclaim Office 365 Licenses

Step1: Export Last Logon to Office 365 in a SSO environment

Follow the URL to Extract last log on report to make sure user did not log on recently and active.

Step2: Create a CSV file with a header UserPrincipalName

Step3: Remove Office 365 Licenses from CSV File Input

$path= Import-Csv -Path “C:\CSV\E1NA.csv”

foreach ($item in $path){

$MSOLUserName= $item.UserPrincipalName

$AccountSkuId = “Tenant:ENTERPRISEPACK”

Set-MsolUserLicense -UserPrincipalName $MSOLUserName -RemoveLicenses $AccountSkuId


 Import Contact from On-prem to Office 365 via CSV File

#Use Case: This script is to import all the contact from on-premises Exchange to Office 365 from a CSV input.

Step1: Run Export all mail contact Get-MailContact | Export-Csv c:\CSV\MailContact.CSV 

Step2: Create a CSV file with CSV headers are Name,DisplayName,ExternalEmailAddress,FirstName,LastName

 Step3: Import Mail Contact  

Import-Csv | ForEach {New-MailContact -Name $_.Name -DisplayName $_.Name -ExternalEmailAddress $_.ExternalEmailAddress -FirstName $_.FirstName -LastName $_.LastName}

 Import Room Mailboxes from On-prem to Office 365 via CSV input

 Step1: Export Room Mailboxes  Get-Mailbox -RecipientTypeDetails RoomMailbox | Export-Csv c:\CSv\RoomMailboxes.csv Get-Mailbox -RecipientTypeDetails EquipmentMailbox | Export-Csv c:\CSv\EquipmentMailboxes.csv

 Step2: Create CSV file with header Name,Alias,PrimarySMTPAddress

Step3: Run the following command to import Room Mailbox

Import-Csv “C:\Scripts\RoomMailboxes.csv” | foreach-object { New-Mailbox -Name $_.Name -Alias $_.Alias -PrimarySmtpAddress $_.Address -Room }

 Assign Shared Mailboxes Permission to Match on-prem Shared Mailboxes

Step1: Export Shared Mailbox Full Access Permision

Get-Mailbox -RecipientTypeDetails SharedMailbox | Get-MailboxPermission | where { ($_.AccessRights -eq “FullAccess”) -and ($_.IsInherited -eq $false) -and -not ($_.User -like “NT AUTHORITY\SELF”) }

Step2: Export Shared Mailbox SendAs Permision

Get-Mailbox -RecipientTypeDetails SharedMailbox | Get-ADPermission | Where {$_.ExtendedRights -like “Send-As” -and $_.User -notlike “NT AUTHORIT\SELF” -and $_.Deny -eq $false} | ft Identity,User,IsInherited -AutoSize

Step3: Prepare two CSV file with header like Name,User where name is the username and user primary SMTP of shared Mailbox.

Step4: Assign SendAs Permission to Shared Mailboxes

$Mailboxes = import-csv C:\CSV\Mailboxes1.csv

Foreach ($Mailbox in $Mailboxes) {Add-RecipientPermission -Identity $Mailbox.Name -Trustee $Mailbox.User -AccessRights “SendAs”}

Step5: Assign Full Access Permission to Shared Mailboxes

$Mailboxes = import-csv C:\CSV\Mailboxes1.csv

Foreach ($Mailbox in $Mailboxes) {Add-MailboxPermission -Identity $Mailbox.Name -user $Mailbox.User -AccessRights ‘FullAccess’ -InheritanceType All}

 Import DL from on-prem to office 365 including Memberships

Download and install PowerShell module from this URL

Step1: Extract list of AD Groups

Get-ADGroupMember -Id “Group Name” | Export-CSV c:\temp\GroupOutput.CSV –NoTypeInformation

Step2: Extract AD Group’s memberships

$groups = Get-Content c:\temp\ADGroupsAdmin.csv           

foreach($Group in $Groups) {                    

Get-ADGroupMember -Id $Group | select  @{Expression={$Group};Label=”Group Name”},* | Export-CSV c:\temp\GroupsInfo.CSV -NoTypeInformation -Append           


Step3: Export ManagedBy Properties of DL

$DL = ‘OU=example,DC=Domain,DC=com’

$DL | ForEach {Get-ADGroup -Filter * -Properties ManagedBy -SearchBase $_ } |

 Select Name, ManagedBy | Sort -Property Name | Out-File C:\ManagedBy.csv

Step4: Create Distribution Group in Bulk

CSV Headers are Name,DisplayName,Alias,Address,Type

Import-CSV “C:\CSG\distributiongroup.csv” | foreach {New-DistributionGroup -Name $ -DisplayName $_.DisplayName -Alias $_.Alias -PrimarySmtpAddress $_.Address -Type $_.Type}

Step5: Add Members to Distribution Group in Bulk

CSV headers are Indentity,Members

Import-Csv “C:\CSG\addmem1.csv” | foreach{Add-DistributionGroupMember -Identity $_.identity -Member $_.members}

Step6: Add ManagedBy properties of Distribution Groups

CSV Headers are GroupName,ManagedBy,User

$list=import-csv C:\AddDistributionGroupOwnerList.csv

Foreach ($i in $list) {

 $grp=get-distributiongroup $i.groupname


 $newuser=get-user $i.user


 Set-distributiongroup $grp -managedby $newmanage -bypasssecuritygroupmanagercheck


 Enable remote Mailboxes in Bulk

This script is useful in hybrid environment when you don’t want to create a mailbox on the on-prem server and then migrate to Office 365. Instead you enable remote mailbox and assign Office 365 licenses to user and create the mailboxes in the Office 365 tenant.  

$Users = Import-csv C:\CSv\EnableRemoteMailbox.csv$Users | ForEach-Object {Enable-RemoteMailbox -identity $_.userprincipalname -RemoteRoutingAddress ($_.samaccountname+’’)} 

Add Proxy Address to the On-prem Mailboxes

This script is very handy if you would like to add alias to all mailboxes in bulk. Alias or proxy address can be used for various reason including mailflow co-existence between disparate mail systems to Office 365 address during IMAP migration.

CSV Headers are Name,ProxyAddresses

 Import-Csv C:\AddressList.csv | ForEach-Object {

  $name = $_.Name

  $proxy = $_.ProxyAddresses -split ‘;’

  Set-Mailbox -Identity $name -EmailAddresses @{add= $proxy}


 Setup Forwarding Address on the On-prem Server

This script is to create forwarding address or target address in bulk. Target address is used to configure mailflow co-existence between disparate mail systems to Office 365 address during IMAP migration.

CSV Headers are Mailbox,ForwardTo

Import-CSV “C:\CSV\Users.csv” | ForEach {Set-Mailbox -Identity $_.mailbox -ForwardingAddress $_.forwardto}

Terms & Conditions:

Before you run any script from any internet source, make sure you understand the risks associated with the script. Understand what has been written on the script, test and validate the script then you run the script. These script does not come with at-fault warranty. These scripts come with As is. Use one or all the scripts when necessary and if the my scenario matches yours. Good luck!