- Using AWS Lambda functions with Docker containers - Fri, May 12 2023
- A Go AWS SDK example - Fri, Nov 11 2022
- Getting started with Jenkins - Tue, Aug 16 2022
My PowerShell class (AwsInstance) requires the AWS Tools for Windows PowerShell. The AWS Tools documentation is very clear with good examples. The cmdlets themselves for controlling the state of an EC2 instance are good, but I wanted an all-in-one tool with some extra features. The AWS module uses PowerShell Core 6 and its very rich in its content. You can install the module from the PowerShell Gallery:
Install-Module -Name AWSPowerShell
The AwsInstance class allows you to stop, start, and restart the machine, while also providing a check status. With the cmdlets, you must pass in the instance ID, which is not that easy to find. So adding the option to control the machine by the tag name became useful.
The AwsInstance class
First, we declare the class by using the keyword class:
Class AwsInstance {}
After declaring the class, we define a field using the properties required to get and set the values. I have four properties, with one set to hidden.
[String] $TagName [String] $InstanceId [String] $Status Hidden [Object] $EC2Instance
We'll use the hidden property to find the EC2 instance in AWS, which we'll then use in the methods. The value passed to the class either populates or finds the TagName or InstanceId. This occurs as part of the constructor:
AwsInstance([String]$name) { if ($name -match '^i-[a-f0-9]+$') { $this.InstanceId = $name $this.EC2Instance = $this.getInstanceFromInstanceId($name) $this.TagName = ($this.EC2Instance.RunningInstance.Tag).Where({ $_.key -eq 'Name' }).Value } else { $this.EC2Instance = $this.getInstanceFromTagName($name) $this.TagName = $name $this.InstanceId = $this.EC2Instance.RunningInstance.InstanceId } $this.GetStatus() }
The constructor takes either an InstanceId or TagName and evaluates via the regular expression in the if block. The GetStatus() method at the end displays these details.
Now we come to the methods.
[Amazon.EC2.Model.Reservation] getInstanceFromTagName([String]$name) { $Filter1 = [Amazon.EC2.Model.Filter]::new("key", ('Name', 'name')) $Filter2 = [Amazon.EC2.Model.Filter]::new('value', $name) $ResourceId = (Get-EC2Tag -Filter @($filter1, $filter2)).Where({$_.ResourceType -eq 'instance'}) return Get-EC2Instance -InstanceId $ResourceId.ResourceId } [Amazon.EC2.Model.Reservation] getInstanceFromInstanceId([String]$name) { return Get-EC2Instance -InstanceId $name } [Void] Start() { try { $this.EC2Instance | Start-EC2Instance $this.GetStatus() } catch { $this.Status = $_.Exception.Message } } [Void] Restart() { try { $this.EC2Instance | Restart-EC2Instance $this.GetStatus() } catch { $this.Status = $_.Exception.Message } } [Void] Stop() { try { $this.EC2Instance | Stop-EC2Instance $this.GetStatus() } catch { $this.Status = $_.Exception.Message } } [Void] GetStatus() { try { $this.Status = ($this.EC2Instance | Get-EC2InstanceStatus).InstanceState.Name.Value } catch { $this.Status = $_.Exception.Message } } Hidden [Void] getInstance() { $this.EC2Instance = Get-EC2Instance -InstanceId $this.InstanceId }
The first two methods relate to the constructor to get either the InstanceId or TagName. The code within the methods uses the cmdlets and classes from the AWS module. The getInstanceFromTagName method uses the filter class Amazon.EC2.Model.Reservation to create two filters. The first one is the key value, which in this case is a tag called either Name or name. The second filter sets the value to the TagName. The code passes the filters to the Get-EC2Tag cmdlet to obtain the ResourceId, which it then passes to the Get-EC2Instance cmdlet to return the EC2 instance.
The getInstanceFromInstanceID method simply passes the InstanceId to the Get-EC2Instance cmdlet to return.
Once our hidden object $EC2Instance has the machine information collected from the two methods just described, we can now it use to control the state of our machine.
For the Start(), Stop(), Restart(), and GetStatus() methods, we pipe the instance information collected in the $EC2Instance variable to the respected cmdlets. To return the status information, we call the GetStatus() method in each of the Start(), Stop(), and Restart() methods.
The final part of the class is to carry out the task itself. I chose to use static methods to do this.
static [String] Start([String]$name) { $instance = [AwsInstance]::new($name) $instance.Start() return "Status: " + $instance.Status } static [String] Stop([String]$name) { $instance = [AwsInstance]::new($name) $instance.Stop() return "Status: " + $(if (-not $instance.Status) { "Stopped" }) } static [String] Restart([String]$name) { $instance = [AwsInstance]::new($name) $instance.Restart() return "Status: " + $instance.Status } static [AwsInstance] GetStatus([String]$name) { $instance = [AwsInstance]::new($name) $instance.GetStatus() return $instance } } Each static method creates an instance of the class: $instance = [AwsInstance]::new($name)
Each static method creates an instance of the class:
$instance = [AwsInstance]::new($name)
Once the static method has created an instance of the machine, it can call methods to change the running state. If I wanted to get the status of a machine, I can do this:
[AwsInstance]::GetStatus('Server2016Test')
This returns the following:
To start, stop, or restart the instance, change the static method to reflect this like so:
Subscribe to 4sysops newsletter!
AwsInstance]::Start(‘Server2016Test’) [AwsInstance]::Stop(‘Server2016Test’) [AwsInstance]::Restart(‘Server2016Test’)
I find myself using this class a lot, as it's quick and easy. The added feature of being able to pass in the tag name is extremely useful. I'm really enjoying PowerShell classes and think it's a great feature. I hope this article has given you something to think about and shown how you can use classes. I've posted the full code here on my git page.