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