Workplace vNext :: Part 5 :: Add Second Server Automatically Into Active Directory

This blog post shows you how to create a new VM and make sure it automatically joins the Active Directory domain. It acts as a part in a bigger series about ‘Workplace vNext’ using Configuration Manager 2012 R2, Intune, ADFS and Azure Multifactor Authentication to provide the next generations Workplace. You can find the introduction post here with the complete index of all posts.

Automatically Join the Domain During Provisioning

During ‘normal OSD’ it is common to join the domain during installation so that we don’t have to logon to the machine just to join the domain, then reboot and back onto the machine with domain credentials. This is possible as well for Windows Azure. The first thing is to make sure that the newly created VM will have the Domain Controller as it’s primary DNS server. And since we’ve already done that in a previous post we can go ahead and provisioning av VM. Yey for us!

As with previous posts I’ve created a script that will do all of these steps that we are going to do. I haven’t found a way to do this using the Web GUI for Windows Azure so this time it is time to buckle up and put on those driving gloves because we’ll make friends with PowerShell :)

The script can be downloaded here.

It uses the PowerShell Module for Windows Azure as described in this post.

The magic is really done using the “Add-AzureProvisioningConfig” function in PowerShell where we can specify the -WindowsDomain switch along with -Domain, -DomainUserName, -DomainPassword and -JoinDomain. All of these parameters together tells Windows Azure to join the machine to a domain.

In the script below it is on line 59, however in the script that you download you’ll find it on line number 76. The script starts by asking you to authenticate to Windows Azure and then a couple of questions, such as what you would like to name your VM as well as the Cloud Service.

Clear
[System.Datetime]$start = [System.Datetime]::Now
$VerbosePreference = "SilentlyContinue"

try {
 Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"
}
catch {
 Write-Error "Unable to find the Azure PowerShell Module." -ErrorAction Stop
}
try
{
 Add-AzureAccount
}
catch
{
 Write-Error "Unable to authenticate against Windows Azure." -ErrorAction Stop
}
if ((Get-AzureStorageAccount).Count -eq 1)
{
 $StorageAccountName = ((Get-AzureStorageAccount).StorageAccountName)
}
else
{
 $StorageAccountName = Read-Host "What is the name of the Storage Account you would like to use?"
}

Set-AzureSubscription -SubscriptionName (Get-AzureSubscription).SubscriptionName -CurrentStorageAccountName (Get-AzureStorageAccount -StorageAccountName $StorageAccountName).StorageAccountName -Verbose

$VMName = Read-Host "What would you like to name your VM?"
$image = (Get-AzureVMImage | Where Label -Like "Windows Server 2012 R2*")[-1].ImageName
Remove-Variable ServiceName -ErrorAction SilentlyContinue
$ServiceName = "infoworks"
While (Test-AzureName -Service $ServiceName)
{
 $ServiceName = Read-Host "What Cloud Service name would you like to use (must be uniqe within Windows Azure)?"
}

$VMNet = Read-Host "What is the name of the Virtual Network?"
$AffinityGroup = (Get-AzureVNetSite -VNetName $VMNet).AffinityGroup
$LocalAdminUsername = Read-Host "What would you like to name your local administrator account (must not be admin, administrator or the same as your VM name)?"
$LocalAdminPassword = Read-Host "What password would you like to use for your local administrator account (sorry, need it in plain text during the script! But this is demo/test only so why worried hehe)?"
$DomainNetBIOS = Read-Host "What is the NetBIOS name of your domain?"
$DomainFQDN = Read-Host "What is the FQDN name of your domain?"
$LocalAdminPassword_Secure = ConvertTo-SecureString -String $LocalAdminPassword -AsPlainText -Force
$DomainAdminUsername = Read-Host "What is the name of the Domain Administrator Account?"
$DomainAdminUsernameAndDomain = "$($DomainNetBIOS)\$($DomainAdminUsername)"
$DomainAdminPassword = Read-Host "What is the Domain Administrators Password (sorry, need it in plain text during the script! But this is demo/test only so why worried hehe)clear?"
$DomainAdminPassword_Secure = ConvertTo-SecureString -String $DomainAdminPassword -AsPlainText -Force
if ((Get-AzureVNetSite -VNetName $VMNet).Subnets.Count -eq 1)
{
 $SubnetName = (Get-AzureVNetSite -VNetName $VMNet).Subnets.Name
}
else
{
 $SubnetName = Read-Host "What is the name of the subnet that you would like the VM to be attached to?"
}

$VM = New-AzureVMConfig -Name $VMName -InstanceSize Small -ImageName $image -Verbose | Add-AzureProvisioningConfig -WindowsDomain -AdminUsername $LocalAdminUsername -Password $LocalAdminPassword -Domain $DomainNetBIOS -DomainUserName $DomainAdminUsername -DomainPassword $DomainAdminPassword -JoinDomain $DomainFQDN -Verbose | Set-AzureSubnet -SubnetNames $SubnetName -Verbose

if (!(Test-AzureName -Service $ServiceName)) { New-AzureVM -ServiceName $ServiceName -AffinityGroup $AffinityGroup -VNetName $VMNet -VMs $VM -Verbose } else { Write-Output "Unable to create a new Cloud Service, a service with that name already exists." }

$Service = (Get-azureVM -ServiceName $ServiceName)

if ($Service -ne $null)
{
 $RemotePS = Get-AzureEndpoint -VM $Service | Where Name -eq "WinRmHTTPs"

 if ($RemotePS -ne $null)
 {

 $credentials = New-Object System.Management.Automation.PSCredential($DomainAdminUsernameAndDomain, $DomainAdminPassword_Secure)

 while ((Get-AzureVM -Name $VMName).Status -ne "ReadyRole")
 {
 Start-Sleep -Seconds 10
 Write-Verbose "Waiting For Server To Become Ready"
 }

 $PSR = New-PSSession -ComputerName $RemotePS.Vip -Port $RemotePS.Port -UseSSL:$true -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck) -Credential $credentials -Name "PSR"

 Invoke-Command -Session $PSR -ScriptBlock {
 Install-WindowsFeature -Name ADFS-Federation -IncludeManagementTools -Verbose
 } -Verbose
 Disconnect-PSSession -Session $PSR > $null
 }
}

Write-Verbose "ADFS still needs to be configured. At this moment, it has only been installed. Please configure it manually."

While running the script it looks like this

01-Running_The_Script

and as you can see there is a slight problem that you actually has to write the password in clear text. I know of both Get-Credentials as well as -AsSecuryString for Read-Host however we need the password in clear text later on in the script so we need to capture it in that form. Sadly. And no, I do not use that password :)

This script will install ADFS as well since this machine will be used to that purpose, if you would like a clean VM, simply remove everything from and including line 63 above (you’ll have to recalculate for the downloaded script). It’s the line that reads “$Service = (Get-azureVM -ServiceName $ServiceName)“.

If you would like to read more about how to do this, you can check this guide at Microsoft. It does how ever include errors at this point in time (3rd of January 2014).

Next post in this series will be to install SCCM, however later on in this series we’ll take a look at how we’ll configure ADFS as well. This script will only install ADFS, the post configuration will be done later on.

 <<< Previous Post | Next Post >>>

/Tim

About The Author

Tim Nilimaa is a consultant with Lumagate in Sweden. He has been working with Configuration Manager for 8 years. His knowledge has been selected as a speaker at many events among them Microsoft Management Summit.

No Comments

Leave A Reply