Read the Azure Storage Analytics Metrics Table with PowerShell
Another script I recently needed to read Azure Storage Analytics Metrics.
Here is the table schema if you need additional or different information.
https://msdn.microsoft.com/en-us/library/azure/hh343264.aspx
Please note that metrics are calculated when an aggregation period ends and are not available immediately. If you run my script as-is, it will attempt to get blob metrics from the previous hour. If you run it "early" in the hour, the data from the previous hour may not yet be ready. You can comment out my filter line to get all data.
Please note that you are on your own to turn storage metrics on. My script will not enable storage metrics for you.
##########################################################################
# Hard-coded Parameters
# Set $proxyAddr = '' if you don't need a proxy server
# Change $BlobOrQueueOrTable to 'Queue' or 'Table' if you like.
##########################################################################
$mgmtUri = 'https://management.core.windows.net'
$subId = '12345678-1234-1234-1234-123456789ABC'
$msApiVer = '2012-08-01'
$servName = 'asdfgh'
$tableEP = 'https://asdfgh.table.core.windows.net/'
$certPW = '<PFX Password>'
$certPath = 'C:\myCert.pfx'
$proxyAddr = 'https://proxy:80'
$HourOrMinute = 'Hour'
$PrimaryOrSecondary = 'Primary'
$BlobOrQueueOrTable = 'Blob'
##########################################################################
# Create a X509 Certificate from the byte array
##########################################################################
$flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"MachineKeySet"
$clientCert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $certPath, $certPW, $flags
##########################################################################
# Call the management service to get the storage keys
##########################################################################
$keysUri = $mgmtUri + '/' + $subId + '/services/storageservices/' + $servName + '/keys'
$mgmtWebRequest = [System.Net.HttpWebRequest]::Create($keysUri)
$mgmtWebRequest.Timeout = 15000
$mgmtWebRequest.ClientCertificates.Add($clientCert)
$mgmtWebRequest.Method = "GET"
$mgmtWebRequest.Headers.Add("x-ms-version", $msApiVer)
If ($proxyAddr -eq '')
{
$mgmtWebRequest.Proxy = $null
}
Else
{
$myWebProxy = New-Object System.Net.WebProxy($proxyAddr)
$mgmtWebRequest.Proxy = $myWebProxy
}
##########################################################################
# Get the storage service keys from the response
##########################################################################
$response = $mgmtWebRequest.GetResponse()
$responseReader = New-Object System.IO.StreamReader($response.GetResponseStream())
[xml]$xmlResponseBody = $responseReader.ReadToEnd()
$responseReader.Close()
$primaryKey = $xmlResponseBody.StorageService.StorageServiceKeys.Primary
##########################################################################
# Create a hasher and seed it with the storage key
##########################################################################
$sharedKey = [System.Convert]::FromBase64String($primaryKey)
$myHasher = New-Object System.Security.Cryptography.HMACSHA256
$myHasher.Key = $sharedKey
##########################################################################
# Construct the Storage Analytics Metrics Table and URI
##########################################################################
$myInvariantCulture = New-Object System.Globalization.CultureInfo("")
$strTable = '$Metrics' + $HourOrMinute + $PrimaryOrSecondary + 'Transactions' + $BlobOrQueueOrTable
$strTableUri = $tableEP + $strTable
##########################################################################
# Get the current date/time and format it properly
# The culture "" is the invariant culture
##########################################################################
$myDateObj = Get-Date
$strDate = $myDateObj.ToUniversalTime().ToString("R", $myInvariantCulture)
##########################################################################
# This will get only the metrics from the previous hour. Metrics are not
# available immediately when an hour ends. If you want to change this
# try either subtracting more than 1 hour from the current time or
# removing the filter from the URI. You can comment out the next two
# lines if you like.
##########################################################################
$strPartition = $myDateObj.AddHours(-1).ToUniversalTime().ToString("yyyyMMddTHH00")
$strTableUri = $strTableUri + '?$filter=PartitionKey%20eq%20''' + $strPartition + ''''
##########################################################################
# Preare the HttpWebRequest
##########################################################################
$tableWebRequest = [System.Net.HttpWebRequest]::Create($strTableUri)
$tableWebRequest.Timeout = 15000
$tableWebRequest.ContentType = "application/xml"
$tableWebRequest.Method = "GET"
$tableWebRequest.Headers.Add("x-ms-date", $strDate)
If ($proxyAddr -eq '')
{
$tableWebRequest.Proxy = $null
}
Else
{
$tableWebProxy = New-Object System.Net.WebProxy($proxyAddr)
$tableWebRequest.Proxy = $tableWebProxy
}
##########################################################################
# Create the Authorization header
##########################################################################
$strToSign = $tableWebRequest.Method + "`n" `
+ $tableWebRequest.Headers.Get("Content-MD5") + "`n" `
+ $tableWebRequest.Headers.Get("Content-Type") + "`n" `
+ $tableWebRequest.Headers.Get("x-ms-date") + "`n" `
+ '/' + $servName + '/' + $strTable
$bytesToSign = [System.Text.Encoding]::UTF8.GetBytes($strToSign)
$strSignedStr = [System.Convert]::ToBase64String($myHasher.ComputeHash($bytesToSign))
$strAuthHeader = "SharedKey " + $servName + ":" + $strSignedStr
$tableWebRequest.Headers.Add("Authorization", $strAuthHeader)
##########################################################################
# Read the results
##########################################################################
$tableResponse = $tableWebRequest.GetResponse()
$tableResponseReader = New-Object System.IO.StreamReader($tableResponse.GetResponseStream())
[xml]$xmlMetricsData = $tableResponseReader.ReadToEnd()
$entries = $xmlMetricsData.feed.entry
Foreach ($entry in $entries)
{
Write-Host 'Row Key:' $entry.content.properties.RowKey
Write-Host 'Partition Key:' $entry.content.properties.PartitionKey
Write-Host 'Total Requests:' $entry.content.properties.TotalRequests.innertext
Write-Host 'Total Ingress:' $entry.content.properties.TotalIngress.innertext
Write-Host 'Total Egress:' $entry.content.properties.TotalEgress.innertext
Write-Host '---------------------'
}
$tableResponseReader.Close()
Comments
- Anonymous
January 09, 2015
Nice job Micheal. Work perfectly for me. Took me a minute to figure out that $servName was the StorageAccountName. Thanks for your help. - Anonymous
November 19, 2015
Hi..
I am trying to use above script ..
can you please provide details about -
$certPW = ''
$certPath = 'C:myCert.pfx'
which certificate is needed and how I can create the same?