Abstract
Azure automation has changed a lot since I wrote last
blog about AutoShutdown of Azure VMs using Azure Automation. Looking at the
phenomenal rate of Azure platform evolution it makes perfect sense to revisit
same services and write a new blog with absolutely new feature and tasks.
This article highlights step by step guide to make an
Azure VM domain joined automatically using Automation DSC feature. This guide does
not cover
-
Step by step flow on creating Azure
Automation account in Azure Portal.
-
Azure VM provisioning
-
Domain configurations on domain controller
What is DSC?
DSC stands for Desired
State Configuration. It’s a configuration management tool. There are many
configuration tools available in the market. Few popular names are Chef and
Puppet. DSC is also configuration management tool from Microsoft. Basically, it
helps to automate tasks which would be very boring to do manually otherwise.
Example of such a boring task is, domain join the Azure VM
when it is provisioned. I am working with one of the customer where almost
every month they provision 100+ VMs on Azure and remove them. To satisfy the
organization compliance and security policies all VMs should domain joined.
Poor IT team had to do this domain joining repetitive task almost every day
manually. There was a dedicated team member for this. He was about to go under
psychiatric treatment. Thanks to Azure Automation DSC, he is back to normal
now.
If interested more in knowing about DSC then link is
here - https://msdn.microsoft.com/en-us/powershell/dsc/overview.
Note
-
As of today Azure supports Classic(ASM) and ARM (Azure Resource Manager) type of deployments of
resources. ARM is the future and this articles talks about ARM based resources
only. Provisionof Azure ARM VM and configuring domain controller is out of
scope of this article. Refer article - http://www.dotnetcurry.com/windows-azure/1145/active-directory-adfs-azure-virtual-machine-authentication-aspnet-mvc to
understand quick steps about domain controller provisioning. The article talks
about classic VM provisioning, which you can ignore and directly follow steps
from section “Configure Active Directory” to promote the
VM as domain controller.
Provision Azure Automation Account
Below link specifies the steps to provision Azure
Automation account – CreateAzure Automation account. I am using below values for the same –
In above screenshot, subscription name is blurred;
because your subscription name will be different from me and I want to keep it
secret for security purpose. sssssshhhh…
New automation account will look as below -
To know about meaning of various options in Automation
account like Runbooks, Assets, Hybrid Worker Groups and all refer - https://mva.microsoft.com/en-US/training-courses/automating-the-cloud-with-azure-automation-8323?l=C6mIpCay_4804984382.
And learning path is present here - https://azure.microsoft.com/en-us/documentation/learning-paths/automation/.
As our focus is specifically on writing DSC script to
make VMs auto domain join I will not spend time on various concepts and
information related to Azure Automation.
With this let’s move forward to actual implementation.
Import xDSCDomainJoin module
xComputerManagement is the DSC module which can be used
to make a computer domain joined. xDSCDomainjoin is stripped version of the
same. This module is available on PowerShell Gallery. The central repository of
PowerShell is known as PowerShell gallery. To know more refer - https://www.powershellgallery.com/.
So this PowerShell gallery has xDSCDomainjoin module and
we must first import in our automation account before we use it in our script.
The best way to import a module in Automation Account is from Azure Portal.
On the Azure Portal, select your Automation account. The
click Assets -> Modules. All existing modules will be shown as below –
Click on “Browse Gallery” option. Search xDSCDomainjoin
in the search box and it will be appear as shown below. The click on “Import”
and then click Ok to complete importing procedure of module in the automation
account. –
A message will appear as “Activities being extracted”.
Let this procedure continue. After successful import the assets count will
increase by 1 on the main page of Automation account.
Installing Azure PowerShell on local machine
On your local machine/ laptop open PowerShell ISE. You
need all Azure PowerShell commands available on your local machine. Working on
Azure without PowerShell is like Superman without Powers (or underwear…). Therefore,
first install Azure PowerShell as per the guide given here - https://docs.microsoft.com/en-us/powershell/azureps-cmdlets-docs/#install-and-configure.
Writing DSC script for domain join
Now after installation first we must provide
authentication information of Azure account to current open PowerShell ISE window.
For this run the command –
Add-AzureRmAccount
This will prompt for login. Go ahead and login to
complete the authentication.
Create new file in PowerShell ISE and save it as
DomainJoinConfiguration.ps1. Write below PowerShell in the same file –
#first import below configuration in Azure automation account
xDSCDomainjoin
Configuration DomainJoinConfiguration
{
Import-DscResource
-ModuleName 'xDSCDomainjoin'
#domain
credentials to be given here
$secdomainpasswd
= ConvertTo-SecureString
"YourDomainPassword" -AsPlainText -Force
$mydomaincreds
= New-Object
System.Management.Automation.PSCredential ("UserName@Domain", $secdomainpasswd)
node $AllNodes.NodeName
{
xDSCDomainjoin JoinDomain
{
Domain
= 'YourDomain'
Credential
= $mydomaincreds
}
}
}
In above script replace YourDomainPassword, UserName@Domain, 'YourDomain'
values by your own values. This is your final script to make an Azure VM domain
joined. Now we must upload this file on Azure automation account. Therefore,
click on DSC Configuration -> Add Configuration as shown below –
On the next window upload the file we created in above
step and then click on Ok to complete the configuration of domain join DSC. And
yes, please provide some meaningful description as shown below -
Why password in plain text?
In above script, you must have observed below line -
$secdomainpasswd = ConvertTo-SecureString
"YourDomainPassword" -AsPlainText -Force
This forces to keep the password as plain text. As you
have guessed this is not good practice. But I am not going to leave it here. Please
read out next sections to understand why we are keeping the password in plain
text. So, hold on your emotions.
Adding Configuration Data to DSC script of Domain Join
Configuration data allows you to separate structural
configuration from any environment specific configuration while using
PowerShell DSC.
This way, we want to separate “WHAT” from “WHERE”. DSC
script we have written above specifies the structural configuration (what).
This is where we define “What is needed” and does not change based on
environment. Irrespective of environment; whether development or production, we
want VMs to be Domain Joined. Environmental configuration specifies the
environment in which the configuration is deployed (where). For example, we
need common settings for all nodes and specific settings for specific nodes.
To specify environment configuration, we use “Config
Data” and then we compile entire DSC script using config data. This should
contain a key “All Nodes” where you specify all common configurations for all
nodes that wishes to get domain joined automatically and then it can contain
other node specific keys. By the way, Azure VMs we add to DSC configuration are
termed as “Nodes”.
For all nodes, I want to allow “Plain Text Password” and
“domain user credentials” and specific nodes I want domain joined. Therefore,
we will write config data as –
$ConfigData = @{
AllNodes =
@(
@{
NodeName =
"*"
PSDscAllowPlainTextPassword = $True
PSDscAllowDomainUser = $true
}
@{
NodeName =
"DomainJoined"
}
)
}
This configuration data I will need use to compile my
DSC script.
Compile the DSC configuration
The domain join DSC script has been added to Azure
automation account and now it is time to compile it so that .MOF file will be generated
on Azure Pull Server. Once .MOF is generated all DSC nodes added to automation
account receives configuration from the same .MOF file. If you open the DSC
configuration, you will observe that “Compile” button is available at top in
the portal itself.
However as of today, if you have DSC script and you wish
to get compiled using Configuration data then PowerShell is only option. If you
compile DSC script with config data using portal, you will receive errors. So,
we will write compilation script and pass above mentioned configuration data, to
compile DSC script present in Azure Automation, from local machine.
To compile DSC script present in Azure Automation
account from your laptop, you will need credentials. This is where Service
Principal helps. When we create Azure Automation account, an Azure Active
Directory service principal automatically gets added to your Azure AD tenant
under which current subscription is present. To verify, just go to Azure AD on
Azure Portal and then select “App Registrations”. You will see the automation
account added as web app.
Every app registered in Azure AD has application Id –
this is your username.
Every app registered in Azure Ad has secret key – this is
your password.
Specify duration as per your choice and give logical
name to key as “KeyForDSC” and then click Save. This will automatically
generate key. Secret key is visible only once, after which it won’t be visible
on the portal. So make sure you get it stored in nice place instead of desktop
for future use.
Azure AD tenant has unique id – this is your tenant id.
We need use Login-AzureRmAccount command and use above
credentials to start a compilation job for DSC script in Azure Automation
account from local machine. The complete script of compilation job with config
data and service principal credentials is as below –
$ConfigData = @{
AllNodes =
@(
@{
NodeName =
"*"
PSDscAllowPlainTextPassword = $True
PSDscAllowDomainUser = $true
}
@{
NodeName =
"DomainJoined"
}
)
}
$secpasswd = ConvertTo-SecureString
"YourSecretKey" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential
("YourApplicationId", $secpasswd)
Login-AzureRmAccount -ServicePrincipal -Tenant
"YourADTenantId" -Credential $mycreds
$compilationJob = Start-AzureRmAutomationDscCompilationJob
-ResourceGroupName 'YourResourceGroupName'
-AutomationAccountName 'YourAutomationAccountName'
-ConfigurationName 'DomainJoinConfiguration'
-ConfigurationData $ConfigData
$compilationJob
Run above command and compilation job will start. Once
completed, you can view the job status as below –
This completes the configuration DSC domain join in
Azure Automation account.
Password in Plain Text
In both, DSC and compilation script above we used
password in plain text.
The best way to protect the password is to use
certificate based encryption. If you need details around the same then refer - https://blogs.technet.microsoft.com/ashleymcglone/2015/12/18/using-credentials-with-psdscallowplaintextpassword-and-psdscallowdomainuser-in-powershell-dsc-configuration-data/.
However, even if you keep the password in simple text in
script it is fine. Because, the .MOF file generated from compilation of DSC
script in Azure is always encrypted. But Automation doesn’t know that Azure is
going to keep the entire .MOF file encrypted and it throws error. Therefore, we
must explicitly specify the force keyword in PowerShell script. So, if you are
sure that no untrusted admin will access automation account from azure portal
then you can always keep the credentials in plain text. Choice is yours!
Add DSC node to make domain join – finally!
On the Azure portal, under automation account click on DSC Nodes -> Add Azure VM -> Virtual
Machines. This will list all VMs present in the azure subscription. Select
the VMs of your choice to get them domain joined.
Under Registration
tab, Select Node configuration name as “DomainJoinConfiguration.DomainJoined”
and provide other information as shown below.
After a while, selected node will display the
information as Compliant and VM will show as domain joined.
Bonus Tip - To join VM to specific OU
This is simple. In the main DSC script you will need to
provide your OU information if you want all VMs to be joined to specific OU.
Example below -
xDSCDomainjoin JoinDomain
{
Domain
= $Domain
Credential
= $Credential
# Credential to join to domain
JoinOU
= "CN=Computers,DC=someplace,DC=kunal,DC=gov,DC=au"
}
Sometimes you may
face errors related to domain credentials in log generated out of DSC job. In
such case instead of specifying user@domain
you can also specify domain\user
format for credentials in DSC script.
Conclusion
I hope this post have helped you to save you from very
repetitive tasks of domain joining a machine.
Please provide your valuable comments. Good news is its
free!!
Keep Automating!!
Top PLC SCADA Industrial Automation Training Institute in Delhi
ReplyDeleteOur image gallery is a wonderful section. View the gallery to see lab, seminar, workshop, projects and instruments, infrastructure, student photos etc. Call for more updates 9310096831.
This comment has been removed by the author.
ReplyDeleteI managed to get this working.
ReplyDeleteBut I am on something new and looking for any help.
I have this domain join working and now I want to automate the timezone setting in azure VM's set to my default rather than UTC.
and I want to achieve this using DSC and want to modify my domain Join configuration itself in a way that post domain join it will also set timezone to my default.
Any help please.
Incredible articles and awesome design. Your blog entry merits the greater part of the positive input it"s been getting. the best vpn
ReplyDeleteIt is the best portal to pay bills online within minutes without any complications. It avails maximum possible flexibility to users to complete their tasks in real quick time. Apart from bill payments it also avails most popular and reputed brands products to customers in affordable prices. PayTM came into existence in 2010. gizlilikveguvenlik
ReplyDeleteSuch a very useful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. privacy en bescherming
ReplyDeleteAbsolutely stunning, best guide on Azure I could find!
ReplyDeletewhy not use the credentials in DSC instead of plain text password
ReplyDelete