81 lines
3.1 KiB
PowerShell
81 lines
3.1 KiB
PowerShell
|
function Get-InstanceMetadata {
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
This function wraps the web-request to get the Instance Metadata (IMDS) from an EC2 instance.
|
||
|
|
||
|
.DESCRIPTION
|
||
|
Defaults to using V2 of the service, which requires a token. This function takes care of the token
|
||
|
generation and use.
|
||
|
|
||
|
There's also the option to use V1 of the service with the switch $UseImdsV1, which requires no token.
|
||
|
|
||
|
.PARAMETER Endpoint
|
||
|
The endpoint in the IMDS servicec to fetch. Ex. '/meta-data/hostname'
|
||
|
|
||
|
.PARAMETER UseImdsV1
|
||
|
Switch to change to the IMDS V1 request instead of V2.
|
||
|
|
||
|
.EXAMPLE
|
||
|
$result = Get-InstanceMetadata -Endpoint "/meta-data/hostname"
|
||
|
$result = Get-InstanceMetadata -Endpoint "/meta-data/hostname" -UseImdsV1
|
||
|
|
||
|
.NOTES
|
||
|
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
|
||
|
#>
|
||
|
[CmdletBinding()]
|
||
|
[OutputType([System.String])]
|
||
|
Param (
|
||
|
[Parameter(Mandatory = $true)]
|
||
|
[string]$Endpoint,
|
||
|
|
||
|
[Parameter(Mandatory = $false)]
|
||
|
[switch]$UseImdsV1
|
||
|
)
|
||
|
$logLead = (Get-LogLeadName)
|
||
|
|
||
|
# Script block to be used when Imds V2 is selected. This is default unless switch $UseImdsV1 is specified.
|
||
|
$V2Script = {
|
||
|
param ($sbImdsUri, $sbEndpoint, $sbImdsV2Token)
|
||
|
|
||
|
$endpoint = ("{0}/{1}" -f $sbImdsUri, $sbEndpoint)
|
||
|
|
||
|
try {
|
||
|
$metadata = (Invoke-WebRequest -Headers @{"X-aws-ec2-metadata-token" = $sbImdsV2Token} -Method GET -UseBasicParsing -TimeoutSec 5 -Uri $endpoint)
|
||
|
} catch [System.Net.WebException] {
|
||
|
# Only on 401
|
||
|
$unauthorizedStatusCode = [System.Net.HttpStatusCode]::Unauthorized
|
||
|
$response = $_.Exception.Response
|
||
|
|
||
|
if($response.StatusCode -eq $unauthorizedStatusCode) {
|
||
|
Write-Verbose "401 Unauthorized caught. Trying again with new token."
|
||
|
$newToken = Get-ImdsV2Token -InvalidateCache
|
||
|
$metadata = (Invoke-WebRequest -Headers @{"X-aws-ec2-metadata-token" = $newToken} -Method GET -UseBasicParsing -TimeoutSec 5 -Uri $endpoint)
|
||
|
}
|
||
|
}
|
||
|
return $metadata
|
||
|
}
|
||
|
|
||
|
# Script block to be used when ImdsV1 is specified.
|
||
|
$V1Script = {
|
||
|
param($sbImdsUri, $sbEndpoint)
|
||
|
|
||
|
$endpoint = ("{0}/{1}" -f $sbImdsUri, $sbEndpoint)
|
||
|
$metadata = (Invoke-WebRequest -Method GET -UseBasicParsing -TimeoutSec 5 -Uri $endpoint)
|
||
|
return $metadata
|
||
|
}
|
||
|
|
||
|
# Set up variables to be passed into the script blocks.
|
||
|
$imdsUri = Get-ImdsBaseUri
|
||
|
|
||
|
# Switch between the two commands based on the $UseImdsV1 switch param.
|
||
|
if($UseImdsV1) {
|
||
|
Write-Verbose "$logLead Imds V1 specified, trying command with V1 URI."
|
||
|
$result = (Invoke-CommandWithRetry -Arguments ($imdsUri, $Endpoint) -MaxRetries 3 -Exponential -ScriptBlock $V1Script)
|
||
|
} else {
|
||
|
Write-Verbose "$logLead Imds V2 specified, trying command with V2 URI."
|
||
|
$token = Get-ImdsV2Token
|
||
|
$result = (Invoke-CommandWithRetry -Arguments ($imdsUri, $Endpoint, $token) -MaxRetries 3 -Exponential -ScriptBlock $V2Script)
|
||
|
}
|
||
|
|
||
|
return $result
|
||
|
}
|