Does anyone have a PowerShell script that starts and stops aws ec2 instances - amazon-web-services

Does anyone have a PowerShell script that starts and stops aws ec2 instances?
param
(
[string] $Filter = "xxxxx*"
)
$CurrentDate = (Get-Date -Format "yyyyMMdd.0.0")
$instances = Get-EC2Instance -Filter #(#{name = 'tag:Name'; values = "xxxx"}) Start-EC2Instance $_.instances.instanceid

Check out this cmdlet by AWS: "Start-EC2Instance Cmdlet", https://docs.aws.amazon.com/powershell/latest/reference/items/Start-EC2Instance.html
And in extension, have a look at the PowerShell Gallery to understand the AWS tools for PowerShell: https://www.powershellgallery.com/packages/AWSPowerShell.NetCore/4.1.11.0

Related

Powershell - Find instances without a tag associated

I have spent a long time on this getting nowhere and cannot find an answer on the web.
I am looking for a PowerShell script that will return EC2 Instances without tag called 'backup' associated with it.
Each Backup tag has a value but right now I am just looking for instances which do not have the tag. Any help would be greatly appreciated.
Thanks
This returns the EC2 Instance objects without a tag named Backup in a specific region:
Import-Module AWSPowershell
$instances = (Get-EC2Instance -Region $region -Credential $cred).Instances
$EC2Tags = Get-EC2Tag -Region $region -Credential $cred |
Where {$_.Key -eq 'Backup' -and $_.ResourceType -EQ 'Instance'}
$instances | Where {$_.InstanceID -NotIn $EC2Tags.ResourceID}

Scheduling a Powershell script to run weekly in AWS

So, I've got the following powershell script to find inactive AD users and disable their accounts, creating a log file containing a list of what accounts have been disabled:
Import-Module ActiveDirectory
# Set the number of days since last logon
$DaysInactive = 60
$InactiveDate = (Get-Date).Adddays(-($DaysInactive))
# Get AD Users that haven't logged on in xx days
$Users = Get-ADUser -Filter { LastLogonDate -lt $InactiveDate -and Enabled -eq $true } -
Properties LastLogonDate | Select-Object #{ Name="Username"; Expression=.
{$_.SamAccountName} }, Name, LastLogonDate, DistinguishedName
# Export results to CSV
$Users | Export-Csv C:\Temp\InactiveUsers.csv -NoTypeInformation
# Disable Inactive Users
ForEach ($Item in $Users){
$DistName = $Item.DistinguishedName
Disable-ADAccount -Identity $DistName
Get-ADUser -Filter { DistinguishedName -eq $DistName } | Select-Object #{ Name="Username"; Expression={$_.SamAccountName} }, Name, Enabled
}
The script works and is doing everything it should. What I am trying to figure out is how to automate this in an AWS environment.
I'm guessing I need to use a Lambda function in AWS to trigger this script to run on a schedule but don't know where to start.
Any help greatly appreciated.
I recomment to create a Lambda function with dotnet environment: https://docs.aws.amazon.com/lambda/latest/dg/lambda-powershell.html
Use a CloudWatch Event on a Scheduled basis to trigger the function:
https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/RunLambdaSchedule.html
An alternative, if you like to to have a more pipeline style execution you could use CodePipeline and CodeBuild to run the script. Use again CloudWatch to trigger the CodePipeline on a scheduled basis!

Send multiple lines of script to EC2 instance from PowerShell SSM cmdlets

I have this example from AWS sites:
Send-SSMCommand -DocumentName "AWS-RunPowerShellScript" -Parameter #{commands = "echo helloWorld"} -Target #{Key="instanceids";Values=#("i-0cb2b964d3e14fd9f")}
in which one line of PowerShell script (echo helloworld) is being sent.
What if I have to send multiple line of PowerShell script through SSM.
How to do that?
There are multiple ways you can achieve this.
You can provide a script to run, which resides inside the instance. or you can create an array of commands - like this:
$commands = #("ipconfig","hostname","write-output 'nothing new here'","get-service")
Send-SSMCommand -InstanceId $instance -Parameter #{commands = $commands} -DocumentName "AWS-RunPowerShellScript"
You can simply run multiple commands with ';' separator - like this:
Send-SSMCommand -InstanceId $instance -Parameter #{commands = "ipconfig;hostname"} -DocumentName "AWS-RunPowerShellScript"
Here is an example - you could run the script directly - which can have multiple lines:
Send-SSMCommand -InstanceId $instance -Parameter #{commands = "c:\programdata\get-param.ps1"} -DocumentName "AWS-RunPowerShellScript"
You could also run the remote script with a custom document, which is either in s3 or github - find examples here: https://docs.aws.amazon.com/systems-manager/latest/userguide/integration-remote-scripts.html
I hope this helps.

create a Powershell code that works with AWS: to list EC2 Key Pairs that are not in use by instances

I am looking to create a Powershell code that works with AWS: to list EC2 Key Pairs that are not in use by instances.
aws ec2 --profile default describe-key-pairs --query
KeyPairs[].[KeyName] --output text |xargs -I {} aws ec2 --profile
default describe-instances --filters Name=key-name,Values={} --query
Reservations[].Instances[].[KeyName,InstanceId] --output text| uniq
this code dosent work for powershell
You need to work with AWS Powershell Module.
The trick here is work with 2 cmdlet function - Get-EC2instance and Get-EC2KeyPair. First of all, you need to get all the keys that in use right now.
Later, you need to get all key pairs and filter them by basic for each and if statement.
Take a look at the following code snippet :
Import-Module AWSPowerShell
$keysInUse = #()
$keysNotInUse = #()
#Set AWS Credential
Set-AWSCredential -AccessKey "AccessKey" -SecretKey "SecretKey"
#Get ec2 key name from each instance
$allInstancesKeys = (Get-EC2instance -Region "YourRegion").Instances.KeyName
#Get all key based on region and check if there's an instance who use this key
Get-EC2KeyPair -Region "YourRegion" | % {
if($_.KeyName -notin $allInstancesKeys)
{
$keysNotInUse += $_.KeyName
}
else
{
$keysInUse += $_.KeyName
}
}
Write-Output "Keys not in use: $($keysNotInUse -join ',')\n
Keys in use: $($keysInUse -join ',')"
The instances i own and key name :
Output :
How to create new AccessKey and SecretKey - Managing Access Keys for Your AWS Account.
AWSPowerShell Module installation.
More about Get-EC2KeyPair Cmdlet.
From the docs :
Describes the specified key pairs or all of your key pairs.
More about Get-EC2instance
Returns information about instances that you own.

Query AWS CLI to populate Jenkins "Active Choices Reactive Parameter" (Linux)

I have a Jenkins 2.0 job where I require the user to select the list of servers to execute the job against via a Jenkins "Active Choices Reactive Parameter". These servers which the job will execute against are AWS EC2 instances. Instead of hard-coding the available servers in the "Active Choices Reactive Parameter", I'd like to query the AWS CLI to get a list of servers.
A few notes:
I've assigned the Jenkins 2.0 EC2 an IAM role which has sufficient privileges to query AWS via the CLI.
The AWS CLI is installed on the Jenkins EC2.
The "Active Choices Reactive Parameter" will return a list of checkboxes if I hardcode values in a Groovy script, such as:
return ["10.1.1.1", "10.1.1.2", 10.1.1.3"]
I know my awk commands can be improved, I'm not yet sure how, but my primary goal is to get the list of servers dynamically loaded in Jenkins.
I can run the following command directly on the EC2 instance which is hosting Jenkins:
aws ec2 describe-instances --region us-east-2 --filters
"Name=tag:Env,Values=qa" --query
"Reservations[*].Instances[*].PrivateIpAddress" | grep -o
'\"[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\"' | awk
{'printf $0 ", "'} | awk {'print "[" $0'} | awk {'gsub(/^[ \t]+|[
\t]+$/, ""); print'} | awk {'print substr ($0, 1, length($0)-1)'} |
awk {'print $0 "]"'}
This will return the following, which is in the format expected by the "Active Choices Reactive Parameter":
["10.1.1.1", "10.1.1.2", 10.1.1.3"]
So, in the "Script" textarea of the "Active Choices Reactive Parameter", I have the following script. The problem is that my server list is never populated. I've tried numerous variations of this script without luck. Can someone please tell me where I've went wrong and what I can do to correct this script so that my list of server IP addresses is dynamically loaded into a Jenkins job?
def standardOut = new StringBuffer(), standardErr = new StringBuffer()
def command = $/
aws ec2 describe-instances --region us-east-2 --filters "Name=tag:Env,Values=qaint" --query "Reservations[*].Instances[*].PrivateIpAddress" |
grep -o '\"[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\"' |
awk {'printf $0 ", "'} |
awk {'print "[" $0'} |
awk {'gsub(/^[ \t]+|[ \t]+$/, ""); print'} |
awk {'print substr ($0, 1, length($0)-1)'} |
awk {'print $0 "]"'}
/$
def proc = command.execute()
proc.consumeProcessOutput(standardOut, standardErr)
proc.waitForOrKill(1000)
return standardOut
I tried to execute your script and the standardErr had some errors, Looks like groovy didn't like the double quotes in the AWS CLI. Here is a cleaner way to do without using awk
def command = 'aws ec2 describe-instances \
--filters Name=tag:Name,Values=Test \
--query Reservations[*].Instances[*].PrivateIpAddress \
--output text'
def proc = command.execute()
proc.waitFor()
def output = proc.in.text
def exitcode= proc.exitValue()
def error = proc.err.text
if (error) {
println "Std Err: ${error}"
println "Process exit code: ${exitcode}"
return exitcode
}
//println output.split()
return output.split()
This script works with Jenkins Active Choices Parameter, and returns the list of IP addresses:
def aws_cmd = 'aws ec2 describe-instances \
--filters Name=instance-state-name,Values=running \
Name=tag:env,Values=dev \
--query Reservations[].Instances[].PrivateIpAddress[] \
--region us-east-2 \
--output text'
def aws_cmd_output = aws_cmd.execute()
// probably is required if execution takes long
//aws_cmd_output.waitFor()
def ip_list = aws_cmd_output.text.tokenize()
return ip_list