Weekend Learning: Day 2 – Resume Windows Server Configuration after Restart using userdata in AWS using PowerShell

In my previous blog post we saw how to deploy a EC2 Instance, stop, start and finally terminate it using PowerShell. Here is the link to it just in-case you missed it : Weekend Learning: Day 1 – Deploy in AWS using PowerShell
When deploying AWS EC2 Instance for an organization it is always good to have it configured almost similar to your server in your own datacenter. Like have your organizations hostname schema, install any standard configuration management agents (HPE Server Automation agent or SCCM agent or Puppet agent etc.) that your organization is using etc. (Note you need to take care of the communication between the respective agent and there server. That is out of scope for this post.)
To perform such customization when you launch an instance in Amazon EC2, you have the option of passing user data to the instance that can be used to perform common automated configuration tasks and even run scripts after the instance starts for the first time.
By default user data is only triggered the first time the instance starts. But some tasks require a restart before the rest of the customization can be performed, like once the server hostname has been changed the server needs to be restart.
In today’s blog post we will take a look at how we can trigger configuration of the server using user data and continue from where it left off before the restart and yes using PowerShell !!
We will see how to do this on a Windows Server and here is the user data.
$UserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(
@'
<powershell>
$path= 'HKLM:\Software\UserData'

if(!(Get-Item $Path -ErrorAction SilentlyContinue)) {
New-Item $Path
New-ItemProperty -Path $Path -Name RunCount -Value 0 -PropertyType dword
}

$runCount = Get-ItemProperty -Path $path -Name Runcount -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty RunCount

if($runCount -ge 0) {
switch($runCount) {
0 {
#Increment the RunCount
Set-ItemProperty -Path $Path -Name RunCount -Value 1

#Enable user data
$EC2SettingsFile = "$env:ProgramFiles\Amazon\Ec2ConfigService\Settings\Config.xml"
$xml = [xml](Get-Content $EC2SettingsFile)
$xmlElement = $xml.get_DocumentElement()
$xmlElementToModify = $xmlElement.Plugins

foreach ($element in $xmlElementToModify.Plugin)
{
if ($element.name -eq "Ec2HandleUserData")
{
$element.State="Enabled"
}
}
$xml.Save($EC2SettingsFile)

#Rename Server and Restart
Rename-Computer -NewName DMTEST -Restart
}
1 {
#Increment the RunCount
Set-ItemProperty -Path $Path -Name RunCount -Value 2

#Enable user data
$EC2SettingsFile = "$env:ProgramFiles\Amazon\Ec2ConfigService\Settings\Config.xml"
$xml = [xml](Get-Content $EC2SettingsFile)
$xmlElement = $xml.get_DocumentElement()
$xmlElementToModify = $xmlElement.Plugins

foreach ($element in $xmlElementToModify.Plugin)
{
if ($element.name -eq "Ec2HandleUserData")
{
$element.State="Enabled"
}
}
$xml.Save($EC2SettingsFile)

#Change the local admin password
([adsi]("WinNT://$env:COMPUTERNAME/administrator, user")).psbase.invoke('SetPassword', 'DMAWSP@ssw0rd')

#Restart
Restart-Computer
}
2 {
#Install Windows Feature
Install-WindowsFeature -Name NET-Framework-Core
}
}
}
</powershell>
'@
))
I am using a variable called UserData and putting the complete code into it so that I can pass this as a parameter into -Userdata parameter in New-EC2Instance command-let.
Now let me explain the code inside the Userdata Variable, I am using the registry path ‘HKLM:\Software\UserData’ to add a key called RunCount with value 0 to start of with. This key will be used to keep track of current section of the script.
Each time the script runs I look up for the value in RunCount and pass it to switch case and based on value it will run the specific section. In each section I update the run count to the next section.
Next I read the config.xml file for EC2ConfigService available in “%ProgramFiles%\Amazon\Ec2ConfigService\Settings” folder and set the Ec2HandleUserData to Enabled. What this does is it ensures that user data is run again after the server restarts.
Then I run the command for example here Rename-Computer and then restart it. When the server restarts, user data we passed initially will run again which will look into the RunCount registry key and then go to the specific switch case and run. This way you can add enough reboots and continue from the next section.
One thing you  will notice is that in the last switch case section I do not update the RunCount Registry and the Config.xml file for EC2ConfigService and that is how I exit out of the user data execution.
That brings us to the end of today’s blog Post. In the upcoming blog post we will do more automation tasks in AWS using PowerShell..

!! Preenesh

Advertisements
This entry was posted in Powershell and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s