Skip to content

Instantly share code, notes, and snippets.

@nanoDBA
Created June 29, 2024 11:54
Show Gist options
  • Save nanoDBA/eab51fb30d58995e029a113d06d05fdb to your computer and use it in GitHub Desktop.
Save nanoDBA/eab51fb30d58995e029a113d06d05fdb to your computer and use it in GitHub Desktop.
This function retrieves the volumes attached to the specified EC2 instances in the specified region. It returns a list of volume details including the instance ID, instance name, instance type, volume ID, device name, state, availability zone, volume type, IOPS, throughput, and size.
# 2023-06-29 version originally by nanoDBA, greatly enhanced by OpenAI's ChatGPT model
<#
.SYNOPSIS
Get the volumes attached to the EC2 instances.
.DESCRIPTION
This function retrieves the volumes attached to the specified EC2 instances in the specified region.
It returns a list of volume details including the instance ID, instance name, instance type, volume ID, device name, state, availability zone, volume type, IOPS, throughput, and size.
.PARAMETER InstanceNames
Specifies the names of the EC2 instances to retrieve the attached volumes for. Accepts multiple instance names if passed as an array.
.PARAMETER InstanceId
Specifies the ID of the EC2 instance to retrieve the attached volumes for.
.PARAMETER Region
Specifies the AWS region where the EC2 instances are located.
.EXAMPLE
Get-EC2VolumesAttached -InstanceNames Instance1 -Region us-west-2
Retrieves the volumes attached to the EC2 instance named "Instance1" in the "us-west-2" region.
.EXAMPLE
Get-EC2VolumesAttached -InstanceNames Instance1, Instance2 -Region us-east-1
Retrieves the volumes attached to the EC2 instances named "Instance1" and "Instance2" in the "us-east-1" region.
.EXAMPLE
Get-EC2VolumesAttached -InstanceId i-1234567890abcdef0 -Region us-west-2
Retrieves the volumes attached to the EC2 instance with the specified Instance ID in the "us-west-2" region.
#>
function Get-EC2VolumesAttached {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, ParameterSetName='ByName')]
[string[]]$InstanceNames, # accept multiple instance names if passed
[Parameter(Mandatory=$true, ParameterSetName='ById')]
[string]$InstanceId,
[Parameter(Mandatory=$true)]
[string]$Region
)
# Clear any previous state
$allVolumes = @() # Initialize an array to store volume details from all instances
$volumeKeys = [ordered]@{} # Initialize an ordered hash table to track unique volume keys (VolumeId + InstanceId)
if ($PSCmdlet.ParameterSetName -eq 'ByName') {
foreach ($InstanceName in $InstanceNames) {
Write-Verbose "Checking instance with name: $InstanceName in region: $Region"
$instProps = Get-EC2Instance -Filter @{name='tag:Name'; values=@($InstanceName)}, @{name='instance-state-name'; values='running'} -Region $Region |
Select-Object -ExpandProperty Instances |
Select-Object @{N='InstanceName'; E={$InstanceName}}, InstanceId, InstanceType
if (-not $instProps) {
Write-Verbose "Instance with name $InstanceName not found or not running in region $Region"
continue
}
$allVolumes += Get-VolumesForInstances -Instances $instProps -Region $Region -VolumeKeys $volumeKeys
}
}
elseif ($PSCmdlet.ParameterSetName -eq 'ById') {
Write-Verbose "Checking instance with ID: $InstanceId in region: $Region"
$instProps = Get-EC2Instance -InstanceIds $InstanceId -Region $Region |
Select-Object -ExpandProperty Instances |
Select-Object @{N='InstanceName'; E={(Get-EC2Tag -ResourceId $_.InstanceId -Region $Region | Where-Object { $_.Key -eq 'Name' }).Value}}, InstanceId, InstanceType
if ($instProps) {
$allVolumes += Get-VolumesForInstances -Instances $instProps -Region $Region -VolumeKeys $volumeKeys
} else {
Write-Verbose "Instance with ID $InstanceId not found in region $Region"
}
}
# Remove any potential duplicates from $allVolumes
$allVolumes = $allVolumes | Sort-Object -Property InstanceId, VolumeId -Unique
# Return the complete list of volumes for all specified instances
return $allVolumes
}
function Get-VolumesForInstances {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[array]$Instances,
[Parameter(Mandatory=$true)]
[string]$Region,
[Parameter(Mandatory=$true)]
$VolumeKeys
)
$volumes = @()
foreach ($inst in $Instances) {
Write-Verbose "Retrieving volumes for instance ID: $($inst.InstanceId) in region: $Region"
$Volumes = Get-EC2Volume -Filter @{ Name = "attachment.instance-id"; Values = $inst.InstanceId } -Region $Region |
Sort-Object {$_.Attachments.Device} |
Select-Object -Property VolumeId, AvailabilityZone, VolumeType, Iops, Throughput, Size,
@{N='Device'; E={$_.Attachments.Device}},
@{N='State'; E={$_.Attachments.State}},
@{N='InstanceId'; E={$_.Attachments.InstanceId}} |
ForEach-Object {
[PSCustomObject]@{
InstanceId = $inst.InstanceId
InstanceName = $inst.InstanceName
InstanceType = $inst.InstanceType
VolumeId = $_.VolumeId
Device = $_.Device
State = $_.State
AvailabilityZone = $_.AvailabilityZone
VolumeType = $_.VolumeType
Iops = $_.Iops
Throughput = $_.Throughput
Size = $_.Size
}
}
# Accumulate unique volumes from all instances
foreach ($vol in $Volumes) {
$key = "$($vol.VolumeId)-$($vol.InstanceId)"
Write-Verbose "Processing volume with key: $key"
if (-not $VolumeKeys.Contains($key)) {
$VolumeKeys[$key] = $true
Write-Verbose "Adding volume: $($vol.VolumeId) for instance: $($vol.InstanceId)"
Write-Verbose "Volume details: $($vol | Out-String)"
$volumes += $vol
} else {
Write-Verbose "Skipping duplicate volume: $($vol.VolumeId) for instance: $($vol.InstanceId)"
Write-Verbose "Duplicate volume details: $($vol | Out-String)"
}
}
}
Write-Verbose "Final volume keys: $($VolumeKeys.Keys -join ', ')"
return $volumes
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment