Ok, after that last example I ended up pulling what hair I had left in my head out trying to parse the XML that got returned. I have come across this problem before but my memory being what it is I had totally forgotten about it so have written this blog post to help remind myself next time this happens.
I couldn’t seem to be able to get at the elements in the data. I was doing this:
' Parse the web response
responseStream = httpResponse.GetResponseStream
reader = New StreamReader(responseStream)
Dim rawOutput As String = reader.ReadToEnd
Dim xdoc As XDocument = XDocument.Parse(rawOutput)
Dim serviceOperations = From s In xdoc.Descendants("SubscriptionOperation")
Select s
For Each s In serviceOperations
Dim email = s.Descendants("UserEmailAddress").Value
Dim operation = s.Descendants("OperationName").Value
Dim opDate = s.Descendants("OperationStartedTime").Value
Console.WriteLine(String.Format("User: {0} Did: {1} On: {2}", email, operation, opDate))
Next
And stepping through the code I found that ServiceOperations resolved to nothing. After a couple of hours of poking and prodding and then searching the internet I came across the solution in this post: Fetching Hosting Services Name Using Windows Azure Management API
Namespaces! Memory starts ticking over and I remember hitting this before. So here is the revised code (In full) which will get Subscription details (Basically audit information) from the Management API
Imports System.Net
Imports System.Security.Cryptography.X509Certificates
Imports System.IO
Imports System.Text
Module Module1
Sub Main()
' X.509 certificate variables
Dim certStore As X509Store
Dim certCollection As X509Certificate2Collection
Dim certificate As X509Certificate2
' Request and response variables
Dim httpRequest As HttpWebRequest
Dim httpResponse As HttpWebResponse
' Stream variables
Dim responseStream As Stream
Dim reader As StreamReader
' URI variable
Dim requestURI As Uri
Try
' specify time range
Dim startTime As String = "2012-11-11"
Dim endTime As String = "2012-11-13"
' The ID for the Windows Azure subscription.
Dim subscriptionId As String = "{Your Subscription}"
' The thumbprint for the certificate. This certificate would have been
' previously added as a management certificate within the Windows
' Azure management portal.
Dim thumbPrint As String = "{Your Thumbprint}"
' Open the certificate store for the current user.
certStore = New X509Store(StoreName.My, StoreLocation.CurrentUser)
certStore.Open(OpenFlags.ReadOnly)
' Find the certificate with the specified thumbprint
certCollection = certStore.Certificates.Find(
X509FindType.FindByThumbprint,
thumbPrint,
False)
' close the certificate store
certStore.Close()
' Check to see if mat
If certCollection.Count = 0 Then
Throw New Exception("No certificate found containing thumbprint " & thumbPrint)
End If
' A matching certificate was found.
certificate = certCollection(0)
Console.WriteLine("Using certificate with thumbprint: " & thumbPrint)
' create new request
requestURI = New Uri(
String.Format("https://management.core.windows.net/{0}/operations?StartTime={1}&EndTime={2}",
subscriptionId, startTime, endTime)
)
httpRequest = HttpWebRequest.Create(requestURI)
' add certificate to requrest
httpRequest.ClientCertificates.Add(certificate)
' Specify the version information in the header
httpRequest.Headers.Add("x-ms-version", "2012-03-01")
httpRequest.ContentType = "application/xml"
' Make the call using the web request
httpResponse = httpRequest.GetResponse
' Display the response status code
Console.WriteLine("Response status code: " _
& httpResponse.StatusCode)
' Display thr request ID returned by windows azure
If httpResponse.Headers IsNot Nothing Then
Console.WriteLine("x-ms-request-id: " & httpResponse.Headers("x-ms-request-id"))
End If
' Parse the web response
responseStream = httpResponse.GetResponseStream
reader = New StreamReader(responseStream)
Dim rawOutput As String = reader.ReadToEnd
Dim ns As XNamespace = "http://schemas.microsoft.com/windowsazure"
Dim xdoc As XDocument = XDocument.Parse(rawOutput)
Dim serviceOperations = From s In xdoc.Descendants(ns + "SubscriptionOperation")
Select s
For Each s In serviceOperations
Dim email = s.Descendants(ns + "UserEmailAddress").Value
Dim operation = s.Descendants(ns + "OperationName").Value
Dim opDate = s.Descendants(ns + "OperationStartedTime").Value
Console.WriteLine(String.Format("User: {0} Did: {1} On: {2}", email, operation, opDate))
Next
httpResponse.Close()
responseStream.Close()
reader.Close()
Console.ReadKey()
Catch ex As Exception
Console.WriteLine("Error encountered: " & ex.Message)
Console.ReadKey()
System.Environment.Exit(1)
Finally
System.Environment.Exit(0)
End Try
End Sub
End Module
This can be used as an example to pull audit information from Azure. I hope this helps others not make my silly mistake 😉
P.s. I hope you like the new theme. Thanks to the above blog post (Debugmode.net) for showing it to me. It makes reading source code much better on wider monitors.