VMware Cloud Community
Sirry
Enthusiast
Enthusiast

Accessing vCloud REST API with Powershell

Hello,

     I have come to the conclusion that the new vCLoud cmdlets are not enough for what I plan on doing, and I plan to extend upon the cmdlets by using the API via REST. I have been fiddling with Invoke-RestMethod a bit, but I cannot seem to get the syntax to work despite reading the pdf regarding vCloud API Programming. Can anyone give me a generic start into this? Thanks!

0 Kudos
4 Replies
LucD
Leadership
Leadership

Thread moved to vCD PowerCLI community


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
admin
Immortal
Immortal

Hi Sirry,

The PowerCLI cmdlets indeed do not cover the entire vCloud functionality. However we do expose the entire vCloud API through PowerCLI - through the Get-CIView cmdlet (and the ExtensionData properties of the objects returned from the other cmdlets). This works in the same way as for vSphere - if you are familiar with that. So instead of using directly the REST API, I suggest you use Get-CIView, it is much more convenient.

To get you started have a look at the Get-CIView help. You can also find articles on how to use Get-CIView in our blog, like this one for example: http://blogs.vmware.com/vipowershell/2012/03/automating-creation-of-vcd-organizations-users-and-org-...

I hope this helps you. If you have more specific questions on this I might be able to assist.

Regards,

Dimitar

DougBaer
Commander
Commander

Sorry for the late reply, but I found this thread when I started looking into doing this myself. I finally pieced some things together and figured this would be a good place to share. While I am no expert, I think this information may help someone get started.

Note that the Invoke-RestMethod cmdlet debuted in Powershell 3.0. This code works with Powershell 4.0, but I don't know why it would not work in 3.0.

The first hurdle is understanding that you need to format the credential a specific way in order for vCD to accept it. This is a little different than the expected "username:password" configuration:

###Configure REST authentication

$vcdHost = 'vcd01.mylab.local'

#vCloud API version

$apiver = "5.1"

# Username and password

$username = 'administrator'

$password = 'VMware1!'

$vcdOrg = 'my-org'

# For a system admin, you can use

# $vcdOrg = 'system'

# Here is where I think a lot of people might run into issues

$auth = $username + '@' + $vcdOrg + ':' + $password

# Encode basic authorization for the header

$Encoded = [System.Text.Encoding]::UTF8.GetBytes($auth)

$EncodedPassword = [System.Convert]::ToBase64String($Encoded)

#define a standard header

$headers = @{"Accept"="application/*+xml;version=$apiver"}

With that part out of the way, let's issue a request. vCD will allow an unauthenticated GET to the https://VCDSERVER/api/versions URL. We'll do that:

$baseurl = "https://$vcdHost/api"

# Create full address of resource to be retrieved

$resource = '/versions'

$url = $baseurl + $resource

# Unauthenticated GET: request and display API versions supported

$versions = Invoke-RestMethod -Uri $url -Headers $headers -Method Get

ForEach ($ver in $versions.SupportedVersions.VersionInfo) { Write $ver.Version}

That seems simple enough, right? Next, let's try authenticating. This requires 1) getting the service URL and 2) POSTing to that URL with our encoded authentication headers AND capturing the authentication token. Note that the argument to the -Session parameter is a string which will become the name of the PS variable. This will contain, among other things, the authentication token we need in a cookie.

# 1) need to get the login URL

$versions = Invoke-RestMethod -Uri $url -Headers $headers -Method GET

ForEach ($ver in $versions.SupportedVersions.VersionInfo) {

  if ($ver.Version -eq $apiver) { $loginUrl = $ver.LoginUrl }

}

if($loginUrl -ne $null) {

# do a POST with our headers to the service/login URL, capture the auth token in a session object

  $headers += @{"Authorization"="Basic $($EncodedPassword)"}

  $response = Invoke-RestMethod -Uri $loginurl -Headers $headers -Method POST -Session MYSESSION

}

We can test the login by getting a simple list of Orgs available. Note that we pass the "MYSESSION" parameter as a PS variable now.

$resource = "/org"

$url = $baseurl + $resource

$response = Invoke-RestMethod -Uri $url -Headers $headers -Method GET -WebSession $MYSESSION

ForEach ( $org in $response.OrgList.org ) { Write $org.name }

Finally, log out properly


$sessionURL = $baseurl + '/session'

Invoke-RestMethod -Uri $sessionurl -Headers $headers -Method DELETE -WebSession $MYSESSION

I hope someone finds this helpful,

Doug

Doug Baer, Solution Architect, Advanced Services, Broadcom | VCDX #019, vExpert 2012-23
snoopj
Enthusiast
Enthusiast

DougBaer,

There was a bug identified with the Invoke-RestMethod cmdlet in regards to using Accept headers.  That's why there was such a problem with vCloud authentication in PS 3.0.  PS 4.0's implementation handles the Accept header much better (as you've already found out).

https://connect.microsoft.com/PowerShell/feedback/details/757249/invoke-restmethod-accept-header

0 Kudos