Within the EC2 service, the Systems Manager Services includes the Run Command. The Run Command allows the remote execution of different Command Documents. While there are a variety of applications, the focus of this article will be the execution of PowerShell commands on Windows EC2 instances.
This guide includes portions from the AWS Docs site.
Create an IAM Role and attach the AmazonEC2RoleforSSM AWS managed policy.
Use the following JSON document to populate the Trust Relationship of the newly created role.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "ssm.amazonaws.com", "ec2.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ]}Attach the role to the EC2 instance.
In the EC2 service, locate the Run Command under the heading of Systems Manager Services.
Then, click on Run a command.
Locate the AWS-RunPowerShellScript document.
Next to Select Targets by, choose Manually Selecting Instances.
Mark the test Windows instances.
Below is the code to populate in the Commands section. This will produce a text file on the root of the C: drive named Diag-[year month day].txt. This file will contain various information about the instance and some event log capturing. (All of this information can be obtained in more efficient and effective ways leveraging CloudWatch, but this is for the sake of demonstration.)
$date = get-date -format "yyyy MM d" #Defines date for filename output$path = "C:\Diag-$date.txt" #Defines path for output file$hostname = $env:computername$IP = ((ipconfig | findstr [0-9].\.)[0]).Split()[-1] #Formats the IP as simple text string$SN = (Get-WMIObject -Class WIN32_SystemEnclosure -ComputerName $env:ComputerName).SerialNumber$disk = Get-WmiObject Win32_logicaldisk | where {$_.DeviceID -eq “C:”} | Select-Object FreeSpace,Size$diskfree = [math]::truncate($disk.FreeSpace / 1GB)$disksize = [math]::truncate($disk.Size / 1GB)$updates = Get-HotFix | sort installedon -desc | select HotFixID,InstalledOn$BIOS = gwmi win32_bios | Select –ExpandProperty SMBIOSBIOSVersion$eventlogerrors = Get-Eventlog -Logname system | Where {$_.entryType -Match "Error"} | select-object -last 25 | Sort-Object TimeWritten $RAM = Get-WMIObject -class Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | % {[Math]::Round(($_.sum / 1GB),2)}"Computername:`t$hostname" | Set-Content $path"IPv4 Address:`t$IP" | Add-Content $path"SerialNumber:`t$SN" | Add-Content $path"BIOS Version:`t$BIOS" | Add-Content $path"Disk Size:`t$disksize GB" | Add-Content $path"Free Disk:`t$diskfree GB" | Add-Content $path"Memory:`t`t$RAM GB" | Add-Content $path"`r`nMost Recent Errors (25):" | Add-Content $path"EventID`tSource`tTime`t`t`tMessage" | Add-Content $path"=======`t======`t====`t`t`t=======" | Add-Content $pathforeach ($eventlogerror in $eventlogerrors) { ($eventlogerror.EventID.ToString() + "`t" + $eventlogerror.Source + "`t" + $eventlogerror.TimeWritten + "`t" + $eventlogerror.Message) | Add-Content $path} "`r`nUpdates:" | Add-Content $path"HotfixID`tInstalledOn" | Add-Content $path"========`t===========" | Add-Content $pathforeach ($update in $updates) { ($update.hotfixid + "`t" + $update.installedon) | Add-Content $path} Click Run.
Remote into the server and look for a file like C:\Diag-[date].txt.
Returning to the Run Command, the status of the script can be monitored and inspected further in the list of logged commands.
In the instance that a script contains an output (write-host, etc.), the output of the command can be located on the Output tab in this log view.
While the specific use case described above is only to show some of the capabilities of the Run Command, further comment on the script may be interesting to some. In that case...
Note that there is a field for serial number and BIOS Version. While this may seem odd for an EC2 instance, this script and the Run Command can be used for on prem servers as well. So in the instance that there is a hybrid environment, the EC2 console interface can be used as a unified management console for both. (See more about the various use cases in the AWS Docs.)