Skip to content

Instantly share code, notes, and snippets.

@mikedixson
Created June 17, 2026 09:15
Show Gist options
  • Select an option

  • Save mikedixson/50322267a295f9d7b684c533bd4b8e8d to your computer and use it in GitHub Desktop.

Select an option

Save mikedixson/50322267a295f9d7b684c533bd4b8e8d to your computer and use it in GitHub Desktop.
PowerShell AWS EC2 lookup & connect toolkit — quickly find instances by name and connect via SSH, RDP or SSM across multiple accounts and regions
# ================================
# AWS EC2 Lookup + Connectivity Toolkit
# ================================
# Purpose:
# Quickly find EC2 instances by Name tag and connect via:
# - SSH
# - RDP
# - SSM (Session Manager)
#
# Features:
# - Multi-region lookup (default: eu-west-2, eu-west-1)
# - Optional multi-account search
# - Automatic AWS SSO authentication
# - Result caching for performance
# - Interactive selection if multiple matches
# - SSH auto-fallback to SSM
#
# To use add to your PowerShell Profile
# ================================
# Examples:
#
# Lookup instances:
# ec2 ukienat
# ec2 uk -AllAccounts
# ec2 uk -Profile DevAccount
#
# SSH:
# ssh2 ukienat
# ssh2 ukienat -User ubuntu
#
# SSM:
# ssm2 ukienat
# ssm2 uk -Profile AdminAccount
# ssm2 uk -Region eu-west-1
#
# RDP:
# rdp2 winserver01
#
# Force fresh lookup (skip cache):
# ec2 ukienat -NoCache
#
# Notes:
# - Partial name matching is supported (*uk* matches multiple hosts)
# - If multiple matches are found, a selection prompt is shown
# - SSH automatically falls back to SSM if connection fails
# ================================
# In-memory cache (per PowerShell session)
$Global:EC2LookupCache = @{}
function Get-EC2Instance {
[CmdletBinding()]
param(
# Name (or partial name) of EC2 instance (matches Name tag)
[Parameter(Mandatory = $true)]
[string]$Name,
# Default AWS profile
[string]$Profile = "ReadOnlyAccess-1234567890",
# Regions to search (extendable)
[string[]]$Regions = @("eu-west-2", "eu-west-1"),
# Search all configured AWS CLI profiles
[switch]$AllAccounts,
# Bypass cache
[switch]$NoCache
)
# Проверка валидности AWS профиля (silent)
function Test-AwsProfile {
param($Profile)
aws sts get-caller-identity --profile $Profile 1>$null 2>$null
return ($LASTEXITCODE -eq 0)
}
# Ensure SSO login is active (auto-login if needed)
function Ensure-AwsLogin {
param($Profile)
if (-not (Test-AwsProfile $Profile)) {
Write-Host "SSO login required for '$Profile'..." -ForegroundColor Yellow
aws sso login --profile $Profile
# Re-check after login
if (-not (Test-AwsProfile $Profile)) {
Write-Warning "Login failed or still invalid for '$Profile'"
return $false
}
}
return $true
}
# Resolve target profiles
if ($AllAccounts) {
$profiles = aws configure list-profiles
} else {
$profiles = @($Profile)
}
$results = @()
foreach ($p in $profiles) {
# Skip profiles that fail auth
if (-not (Ensure-AwsLogin $p)) { continue }
foreach ($region in $Regions) {
$cacheKey = "$p|$Name|$region"
# Return cached result if available
if (-not $NoCache -and $Global:EC2LookupCache.ContainsKey($cacheKey)) {
$results += $Global:EC2LookupCache[$cacheKey]
continue
}
try {
# Query EC2 instances filtered by Name tag
$data = aws ec2 describe-instances `
--profile $p `
--region $region `
--filters "Name=tag:Name,Values=*${Name}*" `
--query "Reservations[].Instances[].{
InstanceId:InstanceId,
Name:Tags[?Key=='Name']|[0].Value,
State:State.Name,
PrivateIP:PrivateIpAddress,
PublicIP:PublicIpAddress,
AZ:Placement.AvailabilityZone
}" `
--output json | ConvertFrom-Json
if ($data) {
foreach ($i in $data) {
$obj = [PSCustomObject]@{
Name = $i.Name
InstanceId = $i.InstanceId
State = $i.State
PrivateIP = $i.PrivateIP
PublicIP = $i.PublicIP
AZ = $i.AZ
Region = $region
Profile = $p
}
$results += $obj
# Cache per profile/region/search
if (-not $NoCache) {
$Global:EC2LookupCache[$cacheKey] = $obj
}
}
}
} catch {
Write-Warning "Failed $p / $region"
}
}
}
if (-not $results) {
Write-Warning "No instances found matching '$Name'"
}
return $results
}
function Select-EC2Instance {
param($instances)
# No results
if (-not $instances) { return $null }
# Single result → return immediately
if ($instances.Count -eq 1) {
return $instances
}
# Prefer GUI picker if available (Out-GridView)
if (Get-Command Out-GridView -ErrorAction SilentlyContinue) {
return $instances | Out-GridView -Title "Select EC2 instance" -PassThru
}
# Fallback to CLI selection menu
Write-Host "Multiple instances found:" -ForegroundColor Yellow
for ($i = 0; $i -lt $instances.Count; $i++) {
$inst = $instances[$i]
Write-Host "[$i] $($inst.Name) $($inst.InstanceId) $($inst.Region) $($inst.State)"
}
$choice = Read-Host "Select index"
return $instances[$choice]
}
function ec2ssm {
param(
# Instance name lookup
[Parameter(Mandatory = $true)]
[string]$Name,
# AWS profile
[string]$Profile = "ReadOnlyAccess-442285748543",
# Override region (optional)
[string]$Region
)
$instances = Get-EC2Instance -Name $Name -Profile $Profile
$instance = Select-EC2Instance $instances
if (-not $instance) { return }
# Use explicit region if provided
$targetRegion = if ($Region) { $Region } else { $instance.Region }
Write-Host "SSM → $($instance.InstanceId) [$targetRegion/$($instance.Profile)]" -ForegroundColor Cyan
# Start SSM session
aws ssm start-session `
--target $($instance.InstanceId) `
--profile $($instance.Profile) `
--region $targetRegion
}
function ec2ssh {
param(
# Instance name lookup
[Parameter(Mandatory = $true)]
[string]$Name,
# SSH username (default Linux AMIs)
[string]$User = "ec2-user",
# AWS profile
[string]$Profile = "ReadOnlyAccess-442285748543"
)
$instances = Get-EC2Instance -Name $Name -Profile $Profile
$instance = Select-EC2Instance $instances
if (-not $instance) { return }
# Prefer public IP, fallback to private
$ip = $instance.PublicIP
if (-not $ip) { $ip = $instance.PrivateIP }
Write-Host "SSH → $User@$ip ($($instance.InstanceId))" -ForegroundColor Green
# Attempt SSH connection
ssh "$User@$ip"
# If SSH fails → fallback to SSM
if ($LASTEXITCODE -ne 0) {
Write-Warning "SSH failed, falling back to SSM..."
ec2ssm -Name $instance.Name -Profile $instance.Profile -Region $instance.Region
}
}
function ec2rdp {
param(
# Instance name lookup
[Parameter(Mandatory = $true)]
[string]$Name
)
$instances = Get-EC2Instance -Name $Name
$instance = Select-EC2Instance $instances
if (-not $instance) { return }
# Prefer public IP, fallback to private
$ip = $instance.PublicIP
if (-not $ip) { $ip = $instance.PrivateIP }
Write-Host "RDP → $ip ($($instance.InstanceId))"
# Launch Remote Desktop
mstsc /v:$ip
}
# ================================
# Aliases (short commands)
# ================================
Set-Alias ec2 Get-EC2Instance
Set-Alias ssh2 ec2ssh
Set-Alias rdp2 ec2rdp
Set-Alias ssm2 ec2ssm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment