The Imperfect Lab: Azure Networking – Two Ways

Around this time last year, I kicked off my “Imperfect Lab” and used it as a story to play around in Azure and get more comfortable with PowerShell. And then I got busy with some other work priorities (as we all do) and I shut down those VMs, with the hopes of dusting them off in the future to continue with more learning.

At any rate, with all the changes to Azure in the last year, it’s really time to reboot the Imperfect Lab and give it a new shine, using some of the fresh new tools – particularly the *new” Portal, Azure Resource Manager (ARM), Azure PowerShell 1.0 and Templates.

Let’s recap what I have to start with (all in “classic” Azure Service Manager)

  • A cloud service and related virtual network
  • Two domain controllers (one using the minimal interface and one running core)
  • One member server that runs the AD Sync service
  • Traditional AD synced to Azure AD

So now where to begin?

When using ARM, it’s no longer possible for the creation of a VM resource without a virtual network, so it seemed fitting for me to start with the network.  It’s also not possible to mix ASM and ARM resources, I’ll be using this network to deploy all the lab VMs I’ll be using in ARM going forward. For those of you who aren’t familiar with old-school Azure, the classic mode (aka Azure Service Manager or ASM) made it possible to create resources in a cloud service without an user-manageable virtual network.

One of the other tasks that was difficult using ASM was programmatically creating and updating networking. It required downloading and editing an XML file and I found that generally distasteful. With ARM, you’ve got two options – straight up PowerShell or an ARM Template.

If you don’t know where to begin with an ARM Template, you can check out this repository of Azure Quickstart Templates. To create a basic network with two subnets, I used this one – https://azure.microsoft.com/en-us/documentation/templates/101-two-subnets/

You can deploy this template using the Azure portal (which will allow you to adjust the parameters to your liking) or you can edit the template to your meet your needs or you can deploy it as is via PowerShell. If you want more details on the ways you can deploy templates, I recommend reading this – https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-deploy/

The other option is use just vanilla PowerShell from the command line or via ISE. I used the following, which is using PowerShell 1.0:

$vnetName = "ImperfectRMNet"
$RGroup = "ImperfectRG"
$Location = "West US"
New-AzureRmResourceGroup -Name $RGroup -Location $Location
$subnet1 = New-AzureRmVirtualNetworkSubnetConfig -Name SubNet6 -AddressPrefix "192.168.6.0/24"
$subnet2 = New-AzureRmVirtualNetworkSubnetConfig -Name SubNet7 -AddressPrefix "192.168.7.0/24"
New-AzureRmVirtualNetwork `
 -Name $vnetName `
 -ResourceGroupName $RGroup `
 -Location $Location `
 -AddressPrefix "192.168.6.0/23" `
 -Subnet $subnet1, $subnet2

Take note that with PowerShell 1.0, there is no “Switch-AzureMode” cmdlet and all of the “New” commands include “RM” in the cmdlet somewhere to differentiate between creating classic Azure resources.  There is nothing else to this basic network, no external IP address or load balancer that would normally come default with a cloud service in ASM.

The Imperfect Lab: Check out the Microsoft Test Lab Guides

If you’ve been reading along for a while now, you know I’ve been having a blast building and expanding my Imperfect Lab. But I admit, if you are looking for a full step-by-step guide to what to actually put in you lab, I’ve haven’t given you all that.  But I do know somewhere you can look!
Available right inside the official Azure documentation is the details (including PowerShell) for setting up a hybrid cloud environment for testing.  Now, this first guide requires you to have a physical data center lab to connect to using RRAS, but you can easily rework it for a VNET-to-VNET if that’s what you desire, by following these instructions instead.
Once you have the basics in place, you can do things like build a full SharePoint Farm (on my short list), set up a Web-based LOB application or set up DirSync. Or do all of them!

The Imperfect Lab: Letting Additional Administrators Remotely Connect to Servers

An age-old server administration best practice is to make sure that everyone who is administering servers on your network are doing it with their own “admin” credentials.

Up until this point, I’ve done all my remote Azure sessions (PS-Session) with the built-in administrator account.  This works fine if you are only person connecting remotely to a server. But what if you want to grant others administrative rights to your machine and they would also like to connect remotely?

Your first step would likely be to add them to the local administrators group. Since you’ve already turned on the “remote management” feature for yourself, you might expect this to work out of the box.

But you probably overlooked this little note in the “Configure Remote Management” box when you enabled remote management – “Local Administrator accounts other than the built-in admin may not have rights to manage this computer remotely, even if remote management is enabled.”

That would be your hint that some other force might be at work here.  Turns out that UAC is configured to filter out everyone except the built-in administrator for remote tasks.

A review of this TechNet information gives a little more detail:

“Local administrator accounts other than the built-in Administrator account may not have rights to manage a server remotely, even if remote management is enabled. The Remote User Account Control (UAC) LocalAccountTokenFilterPolicy registry setting must be configured to allow local accounts of the Administrators group other than the built-in administrator account to remotely manage the server.”

To open up UAC to include everyone in your local Admins group for remote access, you’ll need to make some registry changes.

Follow these steps to manually edit the registry:

  1. Click Start, type regedit in the Start Search box, and then click regedit.exe in the Programs list.
  2. Locate and then click the following registry subkey:
  3. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system
  4. On the Edit menu, point to New, and then click DWORD Value.
  5. Type LocalAccountTokenFilterPolicy for the name of the DWORD, and then press ENTER.
  6. Right-click LocalAccountTokenFilterPolicy, and then click Modify.
  7. In the Value data box, type 1, and then click OK.
  8. Exit Registry Editor.

Now you will be able to remotely connect and administer your server using PowerShell with any account you’ve give Admin rights too for that particular server.  This would hold true for servers in Azure, as well as servers on your local network.

Special shout out to Bret Stateham for bringing this “remote admin road-bump” to my attention. Sometimes what looks like an “Azure” problem, is really a “Server” feature. 🙂

The Imperfect Lab: Not So SharePointed

On my list of thing to try with the Imperfect Lab was deploying a SharePoint Farm from the new portal since there is this nifty wizard that just does all the work of building the servers for you.  Just a few clicks and boom, SharePoint!
But alas, it was not quite to be. While the portal does do what it claims, produces a test/dev scenario of SharePoint, it’s completely isolated.  And completely isolated isn’t exactly what I wanted. When you use the portal configuration “wizard” you are prompted for several bits of information that you can’t get around.
  1. You are prompted to give a domain name for a new FOREST domain.
  2. You must create a NEW virtual network.

Because I wanted to create a little Imperfect Lab “team site” and experiment a bit with SharePoint 2013, I wanted to use my existing domain and my existing network.  But that isn’t an option allowed via the portal “journey”, to get what I want, I’ll have to build it out the old-fashioned way, one server at a time.
Had I know this before I started this project, I might have considered creating the SharePoint farm first, then using that domain and network as the basis for the rest of my lab projects.  Oh well, that’s why we experiment in the first place right?  Live and learn. I guess I’ll swing back around to this SharePoint project a bit later.
Meanwhile, if a completely isolated SharePoint playground is something you need, by all means check out the new Azure portal and give it go.  And if you need more than what the test environment provides, you might find the complete Planning for SharePoint 2013 on Azure Infrastructure Services guide useful.

The Imperfect Lab: Syncing AD to Azure AD

Today I decided to ease myself into my next steps and build out a member server to sync AD to.  I reused some previous PowerShell to deploy a member server and join it to my domain.  It is possible to run the sync services on an existing domain controller, but as a best practice I don’t like to install one-off applications on my domain controllers.  I like to keep them identical, thus the need for different member server to perform the sync role.

I had previously uploaded the Microsoft Azure AD Sync Services (aka AADSync) application to my Azure file share, but you can find it at http://aka.ms/azureadsync.  You will want to install and run the Microsoft Azure AD Connection Tool.  Please note that Microsoft Azure AD Sync Services is DIFFERENT from Windows Azure Active Directory Sync (aka DirSync)

Once the Sync Server is built, you will want to kick off the installation of the application, but not before you’d made some adjustments to your Azure Directory.  In the Portal, I went to my directory and created a new user account to be my Azure AD Administrator (newuser@imperfectlab.com) and made it a Global Administrator.  You will also need to go through the sign-in process to set a non-temporary password.

Once you have this account, you simply need to throw the switch under “Directory Integration -> Directory Sync” from Inactive to Active.  Once the setting is saved, the “Last Sync” field will say “never synced”.  Now go over to your sync server and run that connection tool.

You’ll need the account and credentials you created for the new Azure AD Admin and some information about your domain.  For the addition of the forest, you’ll need your domain name and the username and password of a enterprise domain admin from your local domain.  This will be different than the account your created directly in Azure AD.

Leave the User Matching page at the defaults but select “Password Synchronization” from the Optional Features. Finally, review your configuration screen and verify that “Synchronize Now” is checked and click finish.  At this point, your users should sync into Azure AD and after a few minutes you’ll see a list of them in the portal.

If you want to make any changes to the settings of your AD Sync, like adding in a feature, simply rerun the tool after disabling the Azure AD Sync Task in Task Scheduler.  The task will be re-enabled automatically when you finish the wizard again.

If you want to force a sync for Azure AD Sync Services for any reason, the default location of the command line tool is:

c:\program files\microsoft azure ad sync\bin\directorysyncclientcmd [initial|delta]

Happy Syncing!

The Imperfect Lab: Adding A Custom Domain

This will be a super short post, because this task is super easy!
My lab in Azure wouldn’t be complete without its own custom domain. Honestly, this is one of those “just pop over to the Portal” tasks because it only takes a few clicks, particularly if you are only doing it once.  But you won’t be able to complete in a hurry, because your registrar will update the public DNS entries on their own sweet time and that update is needed to complete the process.
By the way, if you really want to do this without the Portal, you can find information on installing the right PowerShell modules and the commands here. (http://msdn.microsoft.com/en-us/library/azure/jj151815.aspx)  If you are going to managing multiple tenants over time, PowerShell will likely be the best way to go.
Anyway, when you are in the Portal, click “Active Directory” in the navigation.  Select the domain directory you want to add a custom domain to.  In this case, I wanted to create a new Azure Directory for the Imperfect Lab, so I clicked “New” and then went to APP SERVICES -> ACTIVE DIRECTORY -> DIRECTORY -> CUSTOM CREATE.
I named my directory “ImperfectLab” and picked my region.  The domain name for the directory is now “Imperfectlab.onmicrosoft.com”.  Since I don’t want to be using the “onmicrosoft.com” moniker for very long, I need to add my recently purchased domain.  You actually have to a own (or at least control) the domain you want to add because it’s requirement to add a TXT or MX record to your public DNS.
Click into the directory you want to use and go to the “Domains” section. On the bottom action bar, click “Add”. Then type in the FQDN for your “real” domain, in my case “imperfectlab.com”.  You be given the information to create either at TXT or MX record that needs to be added to your DNS records managed by your registrar.
My registrar doesn’t accept the @ symbol for the parent zone, but leaving that field blank worked fine.  You have to add the record, wait for the external DNS to update and then return to the portal to verify it.

Once verified, you can create (or sync) users into your Azure Active Directory using either your “user@domain.onmicrosoft.com” UPN or your “user@domain.com” UPN.

The Imperfect Lab: Fleshing Out Active Directory

Having a domain with no users isn’t any fun.  So my next task for the Imperfect Lab was to create a few accounts to act as my users for provisioning access and eventually syncing with Azure Active Directory.
You can do a lot with some basic PowerShell to create OUs and User Accounts.  Here are a few basic lines that would create something in my lab domain:
New-ADOrganizationalUnit –Name “DOGS” –Path “DC=imperfectlab, DC=Com”
New-ADUser -Name “Lizbeth Tiburon” -Path “OU=DOGS,dc=imperfectlab,dc=com” -AccountPassword $newPassword -Department “Career Changed” -SamAccountName “LTibu” -Surname “Tiburon” -GivenName “Lizbeth” -DisplayName “Lizbeth Tiburon”
Those lines would create a OU and then a user account in the new OU.  But what if you wanted to create more users at once?  I could simply duplicate the 2nd line, but figured there had to a relatively easy way to get data straight from a CSV file.
I did some looking around online and since no good Internet search goes unpunished, I found this: https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Create-Active-7e6a3978#contentby @mwashamtx.  Honestly, this a great script that I couldn’t have written by myself at this point, but I was able to tweak it enough to do my bidding. 

I changed the paths (to reflect the drive letter and file location I set up using Azure Files), removed a lot of the fields the script used to populate account attributes and edited the CSV file to match.  I uploaded my CSV file to my Azure file share. I left the script writer’s five character SAM account name creation as is and ran it remotely via PS-Session on my domain controller.  The DC tapped the CSV file in my Azure File share and wrote the log to that same location.  The script does some great error handling, which was really helpful for troubleshooting.  Mission accomplished!
And for those of you who are curious about the user created in that line above, Lizbeth is a dog who didn’t complete the training to become a guide dog

The Imperfect Lab: Azure Files as a Repository

Oh, the chicken before the egg… or the horse before the cart!  I have this laundry list of things I want to do in the lab, but realized that I would likely need to store some files for my Azure VMs to access.  I will admit that the enhancements with RDP, particularly being about to copy and paste files from a local Explorer window to a remote one are super handy, but I wanted to avoid relying on connecting to the GUI as much as possible.  Plus I wanted to create a centralized location for these files, so I wouldn’t need to ensure that file services was always accessible from a particular VM.
Enter Azure Files.
Azure Files allows you to create a SMB share in Azure Storage that is then accessible from machines in the same region. For the Imperfect Lab, my first goal with this is create a location where I can put some files for use later when connect to my Imperfect Lab domain controllers.  You can find a basic, step-by-step for getting Azure Files going  in the Azure documentation, but this is what I did for my lab.
Also for those of you want a neater way to copy my lines of code, you can find the code from this post here. (It’s not embedded because the Blogger platform is a PITA, but I digress.)
Created a new storage account:
New-AzureStorageAccount -StorageAccountName -Location ‘West US’

Captured the Access Key as a variable:
$storageAccessKey = (Get-AzureStorageKey –StorageAccountName ).Primary
You can also get the full key from the Azure Portal. Just click “Manage Access Keys” from the black tool bar at the bottom of the page for the storage account.
Created a security context with the access key:
$storageContext = New-AzureStorageContext $storageAccessKey
Created a new share:
$share = New-AzureStorageShare -Context $storageContext
Created a directory in the share. I called mine “powershell” in this example:
New-AzureStorageDirectory -Share $share -Path powershell
I wanted to upload a file to my new directory, so I used:
Set-AzureStorageFileContent -Share $share -Source “localfilepath” -Path powershell
To check that it made it, I used: Get-AzureStorageFile -Share $share -Path powershell
Okay, now that I have my Azure Files going, I need to be able to access it from my VM in Azure.  You can do this simply by RDPing to your client, passing it your storage credentials and then mounting the share.  You’ll need that key from the portal to do this since your VM likely won’t be connect to your Azure subscription to capture it as a variable like I did in the previous code.
If you don’t want to RDP to the machine, you can do this from the command line of your remote machine by opening a PS-Session, just note that the credentials won’t be persistent that way and your mapping won’t be retained after a reboot.
cmdkey /add:.file.core.windows.net /user: /pass:
Alternatively, if you don’t have persistent credentials, you can just pass them along right with the net use command:
net use z: \\imperfectfiles.file.core.windows.net\imperfectshare/p:no /u:imperfectfiles $storageAccessKey
Once I have that drive mapped, I can use PS-Session commands remotely, yet access files that are stored locally on the VM, like CSV files or to write logs.  And if you want to delete files, use REMOVE instead of SET, or GET if you want to download them.  For example:
Remove-AzureStorageFile –Share $share –Path [foldername]/[filename]

 As an added note, Azure Files differ from Blob storage because they are accessible via SMB and allows you to build a traditional folder hierarchy if you need one.  However only VMs in the same region can access it.  Regular blob storage has the ability to be accessed globally and by the “public” without an access key.  Azure Files are accessible via both REST and SMB, where Blob storage is only accessible via REST. 

The Imperfect Lab: Creating Client Machines

Playing with domain controllers is all well and good, but I also needed some client machines in my lab.  My goal for the exercise was to be able to create a couple new VMs in the proper subnet and have them automatically join to my domain.
I debated making having each VM in its own cloud service or sharing one cloud services for all my client VMs.  I went with the latter just to keep things neater.  I don’t think there is a right or wrong pick on that one – my client VMs will simply all share the same external *.cloudapp.net DNS name.
For networking, the recommended guidance is to not mix machines with static/reserved DHCP addresses (like my DCs) with machines that are going to use the standard DHCP.  Thus my client machines will go into the alternate subnet I have in my ImperfectNet.
  • ImperfectNet
    • FirstSubnet (192.168.1.0/24)
    • HalfSubnet (192.168.2.0/25) <- right in here!
    • Gateway (192.168.3.200/29)
Since I would be creating a new cloud service name, there are few requirements to keep in mind.  Cloud service names need to meet DNS standards, so they have to start with a letter, end with a letter or number, can only include letters, numbers and hyphens and must be between 3-15 characters.
Because they must also be unique to the “cloudapp.net” domain, you might want to check that your name is available before incorporating it into your script.
Test-Azurename -service “CloudServiceName”
The results of this command will be either “True” or “False”.  You might think this means:
  • True = name already used
  • False = name not used, thus available

 But this thinking will lead you astray.  A “TRUE” response can mean that the name is already in use, but it can also mean that it did not meet the DNS standards.  The line below will return “TRUE” because its longer than 15 characters and includes an underscore.
Test-Azurename -service “imperfectlab_clientmachine1”
Anyway, once you’ve got a good cloud service name sorted out, you’ll want to deploy a VM or two into it.  For my lab, I went with two VMs one running Windows 8 and one with the Windows 10 TP.  (If you are playing along at home don’t have an MSDN subscription that gives you the option to use the Clients OS choices from the gallery, feel free to use another copy of server.)
I set up all my necessary variables, including two different ones for the OS images.  You may want to have different usernames and passwords for the domain vs. the local admin on the clients, but for my ease of not forgetting things in the lab, I’ve been making all mine the same for now.
$image = “03f55de797f546a1b29d1b8d66be687a__Windows-8.1-Enterprise-x64-en.us-201410.01”
$image10 = “03f55de797f546a1b29d1b8d66be687a__Windows-10-Technical-Preivew-Enterprise-x64-en.us-201411.01”
$pwd = “password”
$un = “username”
$subnet = “halfsubnet”
$instancesize = “Small”
$domainjoin = “imperfectlab.com” #this is the domain FQDN
$domain = “imperfectlab” #this is the domain name
$VnetName = “imperfectnet”
Because the variable are preset, I can reuse the same line of code almost exactly, with only a couple of tweaks.
$newVM1 = New-AzureVMConfig -Name “Imperfect-Win8” -InstanceSize $instanceSize -ImageName $image |
    Add-AzureProvisioningConfig -WindowsDomain -JoinDomain $domainjoin -Domain $domain -DomainPassword $pwd -Password $pwd -AdminUsername $un -DomainUserName $un | 
    Set-AzureSubnet -SubnetNames $subnet 
$newVM2 = New-AzureVMConfig -Name “Imperfect-Win10” -InstanceSize $instanceSize -ImageName $image10 |
    Add-AzureProvisioningConfig -WindowsDomain -JoinDomain $domainjoin -Domain $domain -DomainPassword $pwd -Password $pwd -AdminUsername $un -DomainUserName $un | 
    Set-AzureSubnet -SubnetNames $subnet
New-AzureVM -ServiceName “ImperfectClients” -VMs $newVM1 -Location “West US” -VNetName $vnetName
New-AzureVM -ServiceName “ImperfectClients” -VMs $newVM2
For the 2nd VM, I didn’t need to include the “Location” and “VNetName” switches because the cloud service would have already existed due to the creation of the first VM. 
The beauty of this was once I had worked out what I wanted, I kicked off the script and walked out to get coffee.  When I came back, everything was up, running and domain joined.  Look Ma! No portal needed!

The Imperfect Lab: A Few VM Manageability Tweaks

Today in the Imperfect Lab I’m going to work on some clean up to improve the manageability of my new domain controllers. Since I have two of them, I want to take advantage of the Azure’s service level agreement.  The only way to ensure that Azure keeps at least one DC running at all times is to create an availability set, which will distribute the VMs within a set across different update and fault domains.

Some notes about Availability Sets – VMs must be in the same cloud service and you can have a maximum of 50 in each set. You will find that your machines are spread across 2 fault domains and upwards of 5 update domains.  Also, avoid creating a set with just one machine it, because once you create a set you won’t get notifications about maintenance regarding those update/fault areas. 

Since my machines have already been created I use the following PowerShell to update them with a set named “ADDC”.
Get-AzureVM -ServiceName “imperfectcore” -Name “dc-cloud1” |
    Set-AzureAvailabilitySet -AvailabilitySetName “ADDC” |
    Update-AzureVM
Get-AzureVM -ServiceName “imperfectcore” -Name “dc-cloud3” |
    Set-AzureAvailabilitySet -AvailabilitySetName “ADDC” |
    Update-AzureVM
If you want a quick gander at all the availability sets that exist in your subscription, run this:
(Get-AzureService).servicename | foreach {Get-AzureVM -ServiceName $_ } | select name,AvailabilitySetName
Since the GUI does hold a fond place in my heart, I do want the dashboard of Server Manager on one of the VMs to show the status of all the servers in the domain.  You’ll notice that if you log into the desktop of one of these newly created servers the “Remote Management” will be disabled.  This needs to be enabled to allow management from other services, so run “winrm quickconfig -q”against each server to turn that on.  You will have to start a PS-Session for each server for that.
Finally, since I expect to reduce the amount of times I’m logging into a machine directly, I’m going to take switch one of the DCs to Server Core and the other to the MinShell format.  These commands do take a while to complete and require a restart to complete the configuration, so don’t panic if you can’t connect to what looks like “running” VMs in Azure for a few minutes after reboot.
For Server Core (from a Machine running the Full GUI):
Remove-WindowsFeature -name User-Interfaces-Infra
Restart-Computer -Force
For MinShell (from a Machine running the Full GUI):
Remove-WindowsFeature -name Server-GUI-Shell
Restart-Computer -Force
With the MinShell installation I will still have access to the nice Server Manager dashboard when I want it and will be able to remotely manage the 2nd domain controller from it.  The list below will show the differences between each of the versions. (Click to make it bigger!)