4

I've received the complaint...

Help! My I drive filled up on EC2-Server-1! Please give moar space!

However, when I remote on the the server before extending the volume, I find I cannot easily figure out which EBS volume I will need to extend.

When I run aws ec2 describe-instances --filters "Name=tag:Name,Values=EC2-Server-1", the relevant info found in $.Reservations.Instances.BlockDeviceMappings shows...

DeviceName Ebs
---------- ---
/dev/sda1  @{VolumeId=vol-0123;...}
xvdf       @{VolumeId=vol-0456;...}
xvdj       @{VolumeId=vol-0789;...}
xvdg       @{VolumeId=vol-0abc;...}
...

Following this guidance, I can see in Disk Management under Properties > General for Disk 2 (Drive Letter I) the Location value is Bus Number 0, Target Id 6, LUN 0. Looking this value up on the windows volume mapping table from the same page, we see the corresponding DeviceName is xvdg, which maps to vol-0abc.

So... great... now I just need to click through about 5 dialogue boxes every time I need to do this (or just fuzzy match on size from the AWS Console and Windows Explorer).

Is there terminal command (or series of commands) I can execute to retrieve this mapping quickly & reliably?

I'm currently rubber ducking my way through various wmic iterations, but... any chance this is a solved problem?

2 Answers 2

2

Yes, there is. PowerShell (with WMI) to the rescue:

Get-WmiObject Win32_DiskDrive | select-object DeviceID,size,scsiport,scsibus,scsitargetid,scsilogicalunit

This will leave you with:

DeviceID        : \\.\PHYSICALDRIVE9
size            : 234362882560
scsiport        : 3
scsibus         : 0
scsitargetid    : 2
scsilogicalunit : 4
1
  • 1
    Thanks! This is super helpful, but still seems to be missing a key bit needed to map Win32_DiskDrive (AWS info) to Win32_Volume (Drive Letter & Name). Feb 20, 2019 at 12:00
1

The below function returns BlockDeviceName and EBS VolumeID for a given drive letter when executed within the context of an EC2 host. It handles for drives that span multiple disks, but not for disks spanning multiple EBS volumes.

function Get-EbsDeets {
    [cmdletbinding()]Param(
        [string[]]$DriveLetter
    )

    # $wmiVol = Get-WmiObject Win32_Volume      | Where DriveLetter -eq "$DriveLetter`:"
    $wmiLd = Get-WmiObject Win32_LogicalDisk | Where {($_.DeviceID).Trim(':') -in $DriveLetter}

    $wmiLd | ForEach-Object {
        $Letter =  $_.DeviceID

        $wmiLd2p = Get-WmiObject Win32_LogicalDiskToPartition | Where Dependent -in $_.__PATH

        $wmiDd2p = Get-WmiObject Win32_DiskDriveToDiskPartition | Where Dependent -in $wmiLd2p.Antecedent

        $wmiDsk = Get-WmiObject Win32_DiskDrive | Where __PATH -in $wmiDd2p.Antecedent 

        $wmiDsk | ForEach-Object {
            $EstimatedVolumeId = $_.SerialNumber.Insert(3,'-')
            $DeviceName = (ec2WinVolMap $_.SCSIBus -target $_.SCSITargetId -lun $_.SCSILogicalUnit).DeviceName
            $VolumeType = (ec2WinVolMap $_.SCSIBus -target $_.SCSITargetId -lun $_.SCSILogicalUnit).VolumeType
            $SizeGb = [Math]::Round(($_.Size / 1gb),2)

            [PSCustomObject]@{
                DriveLetter = $Letter 
                DiskNumber  = $_.DeviceId
                DeviceName  = $DeviceName
                VolumeType  = $VolumeType
                VolumeId    = $EstimatedVolumeId
                SizeGb      = $SizeGb
            }
        }
    }
}

Function ec2WinVolMap {
    [cmdletBinding()]Param(
         $bus
        ,$target
        ,$lun
    )
# https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-volumes.html#windows-volume-mapping
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html
    $Lookup = @"
Bus,Target,LUN,DeviceName,VolumeType
0,0,0,/dev/sda1,ebs
0,1,0,xvdb, ebs
0,2,0,xvdc, ebs
0,3,0,xvdd, ebs
0,4,0,xvde, ebs
0,5,0,xvdf, ebs
0,6,0,xvdg, ebs
0,7,0,xvdh, ebs
0,8,0,xvdi, ebs
0,9,0,xvdj, ebs
0,10,0,xvdk,ebs
0,11,0,xvdl,ebs
0,12,0,xvdm,ebs
0,13,0,xvdn,ebs
0,14,0,xvdo,ebs
0,15,0,xvdp,ebs
0,16,0,xvdq,ebs
0,17,0,xvdr,ebs
0,18,0,xvds,ebs
0,19,0,xvdt,ebs
0,20,0,xvdu,ebs
0,21,0,xvdv,ebs
0,22,0,xvdw,ebs
0,23,0,xvdx,ebs
0,24,0,xvdy,ebs
0,25,0,xvdz,ebs
0,78,0,xvdca,instance-store
0,79,0,xvdcb,instance-store
0,80,0,xvdcc,instance-store
0,81,0,xvdcd,instance-store
0,82,0,xvdce,instance-store
0,83,0,xvdcf,instance-store
0,84,0,xvdcg,instance-store
0,85,0,xvdch,instance-store
0,86,0,xvdci,instance-store
0,87,0,xvdcj,instance-store
0,88,0,xvdck,instance-store
0,89,0,xvdcl,instance-store
"@ | ConvertFrom-Csv

    $DeviceName = ($Lookup | Where-Object {
        $_.Bus    -eq $bus    -and `
        $_.Target -eq $target -and `
        $_.LUN    -eq $lun
    }).DeviceName

    $VolumeType = ($Lookup | Where-Object {
        $_.Bus    -eq $bus    -and `
        $_.Target -eq $target -and `
        $_.LUN    -eq $lun
    }).VolumeType

    [PSCustomObject]@{
        DeviceName = $DeviceName
        VolumeType = $VolumeType
    }
}

Explanation

Given the above limitation, you can estimate the EBS VolumeID for (the first volume in) a given disk by inspecting the SerialNumber attribute on Win32_DiskDrive. As noted in @bjoster's answer, you can also retrieve the bus, target, and lun values necessary to look up the BlockDeviceName based on the table in the previously linked AWS documentation.

Frustratingly though, this doesn't easily map back to the actual drive letter or name which you're likely to receive in an actual user complaint. To associate these attributes (found on the Win32_LogicalDisk collection in my case), you can daisy chain back through the antecedent/dependent mappings on the Win32_LogicalDiskToPartition and Win32_DiskDriveToDiskPartition collections.

When cobbling this together, I noted that on my installation Win32_DiskDriveToDiskPartition maps 1:1 for disks. While Win32_LogicalDiskToPartition does match the number of EBS volumes (in the case of multiple volumes per disk), I haven't bothered just yet to figure out how to associate the bus, target, and lun needed to get the BlockDeviceName for the non-primary underlying volume(s) when they exist. If these are retrieved but for some reason the EBS VolumeID isn't immediately known for the non-primary volumes, there may be some thought of calling the AWSPowerShell function in the following way

$bdn = 'xvdg'

# assuming you've tagged your instance with the hostname
$ec2 = Get-EC2Instance -Filter @{Name='tag:Name';Values='EC2-Server-1'}

($ec2.Instances.BlockDeviceMappings | Where DeviceName -eq $bdn).Ebs

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .