Search code examples
powershellamazon-web-servicesamazon-ec2amazon-ebs

Getting Drive letter from volume id on windows 2016 EC2 -Powershell


Is it any simple way to get the EBS volume id for particular drive letter/label?

I am doing this which is just giving the volume IDs but not able to figure out how to get drive letters.

# Get Instance ID from the EC2 metadata web service
$instanceID = (New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")
# Get a collection of all volumes attached to the instance
$volumes = @(get-ec2volume) | ? { $_.Attachments.InstanceId -eq $instanceID}


# Get a collection of each volume's ID property
$volumeNames = $volumes | %{$_.attachment.device}
$volumeNames

Actually, I wanted to tag the ebs volume with particular ec2 instance name: and drive letter.


Solution

  • Finally figured out. This script will iterate over all the EBS volumes and add a tag to EBS according to its Disk label. You can modify it, as per your need (refer bottom if-else blocks). The EC2 needs to have proper IAM role to call the New-Ec2 tag API.

    Start-Transcript -Path C:\cfn\log\Tag-EBS-Volumes.ps1.txt -Append
            # Create a hash table that maps each device to a SCSI target
            $Map = @{"0" = '/dev/sda1'}
            for($x = 1; $x -le 25; $x++) {$Map.add($x.ToString(), [String]::Format("/dev/xvd{0}",[char](97 + $x)))}
            for($x = 78; $x -le 102; $x++) {$Map.add($x.ToString(), [String]::Format("/dev/xvdc{0}",[char](19 + $x)))}
    
        Try {
            # Use the metadata service to discover which instance the script is running on
            $InstanceId = (Invoke-WebRequest '169.254.169.254/latest/meta-data/instance-id').Content
            $AvailabilityZone = (Invoke-WebRequest '169.254.169.254/latest/meta-data/placement/availability-zone').Content
            $Region = $AvailabilityZone.Substring(0, $AvailabilityZone.Length -1)
    
            # Get the list of volumes attached to this instance
            $BlockDeviceMappings = (Get-EC2Instance -Region $Region -Instance $InstanceId).Instances.BlockDeviceMappings
        }
        Catch
        {
            Write-Host "Could not access the AWS API, are your credentials loaded?"  -ForegroundColor Yellow
        }
    
        Get-WmiObject -Class Win32_DiskDrive | %{
            $Drive = $_
            # Find the partitions for this drive
            Get-WmiObject -Class Win32_DiskDriveToDiskPartition |  Where-Object {$_.Antecedent -eq $Drive.Path.Path} | %{
                $D2P = $_
                # Get details about each partition
                $Partition = Get-WmiObject -Class Win32_DiskPartition |  Where-Object {$_.Path.Path -eq $D2P.Dependent}
                # Find the drive that this partition is linked to
                $Disk = Get-WmiObject -Class Win32_LogicalDiskToPartition | Where-Object {$_.Antecedent -in $D2P.Dependent} | %{
                    $L2P = $_
                    # Get the drive letter for this partition, if there is one
                    Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.Path.Path -in $L2P.Dependent}
                }
    
                $BlockDeviceMapping = $BlockDeviceMappings | Where-Object { $_.DeviceName -eq $Map[$Drive.SCSITargetId.ToString()] }
    
                 If( $Disk.VolumeName -eq "") {
                    $tagvalue= "$env:COMPUTERNAME-Root"
                 }  ElseIf ($Disk.VolumeName -eq "ABC" )
                 {
                    $tagvalue= "$env:COMPUTERNAME-ABC"
                 }ElseIf ($Disk.VolumeName -eq "DEF" )
                 {
                    $tagvalue= "$env:COMPUTERNAME-DEF"
                 }Else
                 {
                    $tagvalue= ""
                 }
    
                 New-EC2Tag -Resources $BlockDeviceMapping.Ebs.VolumeId -Tags @{ Key = "Name"; Value = $tagvalue } # Add volume name tag that matches VolumeId
            }
        }