vNet Peering PowerShell

We have a hub and spoke design in Azure for our vNets and needed to peer the vNets together.

This can be done in an ARM template and we could have deployed all three networks in one go and peered them as part of the ARM template deployment.  For various reasons that approach didn’t really work for us, 1 reason was the customer is very sensitive to change control and having all 3 vNets being controlled by one ARM deployment didn’t sit very well with them and made them nervous.

So PowerShell was the obvious answer, and it’s very simple in PowerShell anyway.  So we deploy all 3 vNets using separate ARM templates and then peer them together with powershell.  Code also over on github

#Peering for hub and spoke network design
#Variables Section
$hubVnetResourceGroup = "RG_hubVnet"
$hubVnetName = "hubprodVnet"
$spoke1VnetResourceGroup = "RG_spoke1vnet"
$spoke2VnetResourceGroup = "RG_spoke2Vnet"
$spoke1VnetName = "spoke1prodVnet"
$spoke2VnetName = "spoke2prodVnet"
$hubVnet = Get-AzureRmVirtualNetwork -Name $hubVnetName -ResourceGroupName $hubVnetResourceGroup 
$spoke1Vnet = Get-AzureRmVirtualNetwork -Name $spoke1VnetName -ResourceGroupName $spoke1VnetResourceGroup
$spoke2Vnet = Get-AzureRmVirtualNetwork -Name $spoke2VnetName -ResourceGroupName $spoke2VnetResourceGroup
#End Variables

#Add Hub to spoke1 peer and allow gateway transit through hub1
Add-AzureRmVirtualNetworkPeering -Name 'hubtospoke1peer' -VirtualNetwork $hubvnet -RemoteVirtualNetworkId $ -AllowForwardedTraffic  -AllowGatewayTransit 

#Add spoke 1 to hub and use hub 1 gateways
Add-AzureRmVirtualNetworkPeering -Name 'spoke1tohubpeer' -VirtualNetwork $spoke1vnet -RemoteVirtualNetworkId $ -AllowForwardedTraffic  -UseRemoteGateways 

#Add hub to spoke2 peer and allow gateway transit through hub
Add-AzureRmVirtualNetworkPeering -Name 'hubtospoke2peer' -VirtualNetwork $hubvnet -RemoteVirtualNetworkId $ -AllowForwardedTraffic  -AllowGatewayTransit

#Add spoke 2 to hub and use hub 1 gateways
Add-AzureRmVirtualNetworkPeering -Name 'spoke2tohubpeer' -VirtualNetwork $spoke2vnet -RemoteVirtualNetworkId $ -AllowForwardedTraffic  -UseRemoteGateways 

Querying IIS SMTP Smarthost Settings

Had a request to throw something together to query multiple machines and find the smarthost server that IIS was configured to use.  All I had time for was ‘quick and dirty’ so this is what I came up with;


get-adcomputer -filter * | Select-Object dnshostname >c:\servers.txt
Get-WmiObject -Namespace “root\MicrosoftIISv2” -Class “IISSMTPServerSetting” -Filter “Name =’SmtpSvc/1′” -comp (Get-Content c:\servers.txt) | Select-Object smarthost,defaultdomain | export-csv c:\servers.csv -NoTypeInformation

Obvious problem with the above is there is no connectivity check in place so any servers not being enabled for PS Remoting or firewalls in the way will just generate an error




New Child Domain – Server Core and PowerShell

All of my domain controllers are now server core unless someone can give me a very good reason to install Windows with a GUI, so far no one has given me a good enough reason.

When deploying a new child domain this means we can now use some PowerShell goodness to create our new child domain.


Windows 2012R2 Server Core installed

IP address set on the box and preferred DNS server set to the IP address of a domain controller in the parent domain

Install-Windowsfeature AD-Domain-Services

Install-ADDSDomain -DomainType child -NewDomainName ‘childdomname’ -ParentDomainName ‘’ -InstallDns -CreateDnsDelegation -NewDomainNetBiosName ‘childdomname’ -DomainMode win2012r2 -Credential (get-credential)


You will be prompted for the admin credentials of your parent domain and then for the safemodepassword that you want to set on this DC.

Restore Computer Object with AD Recycle Bin

Over the Xmas period it would seem that someone deleted a computer account from AD.  This meant that the user of that PC could not log in using that PC.  This is a Windows 2008R2 forest so to restore the computer object;


Get-Adobject -filter {samaccountname -eq “pcname$”} -IncludeDeletedObjects | Restore-Adobject


The $ on the pcname is important – computer objects in AD always have $ at the end of the name as part of the samaccountname attribute.

AdminSDHolder and admincount=1 attribute

Certain groups within Active Directory are considered protected groups and are protected by AdminSDHolder.  When a user becomes a member of a protected group it will no longer inherit permissions from its parent object in AD (usually an OU).  This can mess up any carefully laid permission delegations you may have configured.  Much more on AdminSDHolder here

As an AD admin you may find that if you have been delegated permissions to , say, reset passwords of all users in OU you could come across a user who’s password you can’t reset.  You’ll basically be told you do not have permissions on that object.  If that user account was once in a protected group they will not be inheriting the permissions from the parent OU.

To identify users that have the attribute admincount set to 1

$count = Get-Aduser -searchbase “OU=ExampleOU,DC=Example,DC-Com” -Properties adminCount -Filter * | where {admincount -gt 0}

To then set that attribute back to 0

$count | Select SamAccountName,distinguishedName,adminCount | ForEach-Object {Set-Aduser -Identity $_.SamAccountName -Replace @{adminCount=0}}


Once that is done then inheritance needs to be re-enabled on the object; the below code from here


$users = Get-ADUser -ldapfilter “(objectclass=user)” -searchbase “OU=companyusers,dc=enterpriseit,dc=co”
ForEach($user in $users)
# Binding the users to DS
$ou = [ADSI](“LDAP://” + $user)
$sec = $ou.psbase.objectSecurity

if ($sec.get_AreAccessRulesProtected())
$isProtected = $false ## allows inheritance
$preserveInheritance = $true ## preserver inhreited rules
$sec.SetAccessRuleProtection($isProtected, $preserveInheritance)
Write-Host “$user is now inherting permissions”;
Write-Host “$User Inheritable Permission already set”


Move users to OU based on description

Trying to keep up with job changes and ensuring users accounts are in the correct OU in AD can be problematic.  In the environment I work in each team has their own OU (I’m not sure why it is like this,  I suspect it’s a case of ‘that’s the way we’ve always done it’).

Anyway mine is not to reason why.  So the good thing is that the descriptions for users are fairly well defined, for example someone in the 2nd line team the description is ‘Second Line Support Team’.   Using this description users can be moved to the correct OU using Powershell

First I create variables for the OUs

$secondlineou = “OU=SecondLineOU,DC=Example,DC=Com”

then I can use Get-Aduser and filter on the description

Get-Aduser -Filter “Description -eq ‘Second Line Support Team'”

This gives me all users in AD with a description of ‘Second Line Support Team’

I then pipe that information to the Move-Adobject cmdlet and specify the variable as the target

Move-Adobject -TargetPath $secondlineou

Putting this all together gives

$secondlineOU = “OU=SecondLineOU,DC=Example,DC=Com”

Get-Aduser -Filter “Description -eq ‘Second Line Support Team'”| Move-Adobject -TargetPath $secondlineou


I have this running as a scheduled task.  This has made things easier on the service desk team.  All they now need to do is updated a users description and the automation will ensure the account gets placed into the correct OU

Mailbox Enable all users in an OU

As well as having to Skype enable all users recently (see previous post) I also had to mailbox enable the users.  With Exchange 2010 you can’t just import the powershell module.  Using this article as a base I came up with this;

$Session = New-Pssession -COnfigurationName Microsoft.Exchange -ConnectionUri http://exchangeservername/powershell

Import-Pssession $Session

Get-User -OrganizationalUnit “OU=ExampleOU,DC=Example,DC=Com” | Enable-Mailbox -database “your mailbox database”


Skype/Lync Enable all users in an OU

I recently had to enable all users in a specific OU for Skype for Business 2015.  Easily done with Powershell;

Either import the skypeforbusiness module into a normal Powershell window or run the Skype for Business Server Management Shell

import-module skypeforbusiness

Get-CsAduser -OU “OU=ExampleOU,DC=example,DC=com” | Enable CSuser -RegistrarPool “your pool name” -SipAddressType emailaddress

Set IP Address and DNS settings with PowerShell – Windows 2012 and newer


Name                      InterfaceDescription                    ifIndex Status
—-                      ——————–                    ——- ——       ———-
Ethernet                  vmxnet3 Ethernet Adapter                     12 Up

Name is the interfacealias.

New-Netipaddress -interfacealias “ethernet” -ipaddress -prefixlength 24 -defaultgateway

Could also use

new-netipaddress -interfaceIndex 12


set-dnsclientserveraddress -interfacealias “ethernet” -serveraddresses”,″