update 06/03/2018: Check out this great example of it’s usage with Veeam!
Original Post: got milk? ehhh I mean metadata?
So this next post is about importing metadata as properties for use in reports, views, dashboards, custom groups etc…
I am going to import the sample meta data below as new vMAN|* properties
Below is a screenshot of the suite-api properties query for one of my VM’s before I ran the script.
Now I run my script and the new VMAN properties have been applied to all VM’s in my list.
So what can i do with these properties now??
Let’s create a custom group!
Lets find the new properties
and now define the filter
So I now have a new group which will automatically update with new members that are “MISSION CRITICAL”
The properties can also be used in lists on dashboards, this can be useful to quickly identify the culprit application causing load / issues on the infrastructure without having to go off to a CMDB.
So… to the script!
Update the script with your own vRops server IP or FQDN.
$vRopsAddress = 'vrops.vMan.ch'
So that I don’t keep being prompted for credentials I save the service account user and password with the powershell Get-Credential command.
$cred = Get-Credential $cred | Export-Clixml -Path "d:\vRops\home.xml"
Now update the XML to reflect the file generated above…
$cred = Import-Clixml -Path "$ScriptPath\HOME.xml"
and don’t forget to supply the metadata.csv and update the XML structure to match what you need.
$MetaImport = "$ScriptPath\metadata.csv"
good luck! if you found the post helpful… please consider supporting my hosting by checking out one of the sponsored links.
#Vars $vRopsAddress = 'vrops.vMan.ch' $ScriptPath = (Get-Item -Path ".\" -Verbose).FullName [DateTime]$NowDate = (Get-date) [int64]$NowDateEpoc = Get-Date -Date $NowDate.ToUniversalTime() -UFormat %s $NowDateEpoc = $NowDateEpoc*1000 $MetaImport = "$ScriptPath\metadata.csv" $cred = Import-Clixml -Path "$ScriptPath\HOME.xml" $vRopsUser = $cred.GetNetworkCredential().Username $vRopsPassword = $cred.GetNetworkCredential().Password #Take all certs. add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy #Functions #Lookup Function to get resourceId from VM Name Function GetObject([String]$vRopsObjName, [String]$vRopsServer, $User, $Password){ $wc = new-object system.net.WebClient $wc.Credentials = new-object System.Net.NetworkCredential($User, $Password) [xml]$Checker = $wc.DownloadString("https://$vRopsServer/suite-api/api/resources?name=$vRopsObjName") # Check if we get more than 1 result and apply some logic If ([Int]$Checker.resources.pageInfo.totalCount -gt '1') { $DataReceivingCount = $Checker.resources.resource.resourceStatusStates.resourceStatusState.resourceStatus -eq 'DATA_RECEIVING' If ($DataReceivingCount.count -gt 1){ $CheckerOutput = '' return $CheckerOutput } } $CheckerOutput = New-Object PsObject -Property @{Name=$vRopsObjName; resourceId=$Checker.resources.resource.identifier; resourceKindKey=$Checker.resources.resource.resourceKey.resourceKindKey} return $CheckerOutput } #Import Metadata into a PSObject / table $AttributeImport = Import-csv $MetaImport #Create XML, lookup resourceId and push Data to vRops ForEach($VM in $AttributeImport){ #Create XML Structure and populate variables from the Metadata file $XMLFile = @('<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ops:property-contents xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ops="http://webservice.vmware.com/vRealizeOpsMgr/1.0/"> <ops:property-content statKey="VMAN|FUNCTION"> <ops:timestamps>{0}</ops:timestamps> <ops:values>{1}</ops:values> </ops:property-content> <ops:property-content statKey="VMAN|COSTCODE"> <ops:timestamps>{0}</ops:timestamps> <ops:values>{2}</ops:values> </ops:property-content> <ops:property-content statKey="VMAN|CRITICALITY"> <ops:timestamps>{0}</ops:timestamps> <ops:values>{3}</ops:values> </ops:property-content> </ops:property-contents>' -f $NowDateEpoc, $VM.FUNCTION, $VM.COSTCODE, $VM.CRITICALITY ) [xml]$xmlSend = $XMLFile #Run the function to get the resourceId from the VM Name $resourceLookup = GetObject $VM.NAME $vRopsAddress $vRopsUser $vRopsPassword #Create URL string for Invoke-RestMethod $urlsend = 'https://' + $vRopsAddress + '/suite-api/api/resources/'+ $resourceLookup.resourceId + '/properties' ## Debug echo $urlsend #Send Attribute data to vRops. $ContentType = "application/xml;charset=utf-8" Invoke-RestMethod -Method POST -uri $urlsend -Body $xmlSend -Credential $cred -ContentType $ContentType #CleanUp Variables to make sure we dont update the next object with the same data as the previous one. Remove-Variable urlsend -ErrorAction SilentlyContinue Remove-Variable xmlSend -ErrorAction SilentlyContinue Remove-Variable XMLFile -ErrorAction SilentlyContinue }
#Lookup Function to get resourceId from VM Name
That will be handy, thanks for sharing!
thanks 🙂 you should checkout the new report on steroids
I was stumped I added the properties, and they showed up in the REST properties call… But I could not see them when trying to make a report.
Now I understand, these properties are to a member not the base, so the menu wont update them. You could add a step above the “Lets find the new properties” selection to say hit “Select Object” icon. Then filter/select a host that you’ve added the property to, then you will see the properties.
I did all kinds of crazy things trying to see this.
Ahh good point, I guess I can do a separate post on this.
When trying to use the properties in the GUI to build custom groups / add properties to view’s… etc
Basically the reason the properties dont show up in the GUI when you create them (on larger environments) is that the property needs to be associated with a certain number / % of objects in the environment before it ends up displayed… it also requires some kind of job or task wish runs to scan them in. I remember losing many hours on v6.0 with this issue… I then spoke to the head of vRops engineering and then he explained that there were not enough objects with the property so it wouldn’t show up in the GUI straight away or at all sometimes..
Just another item on this I am struggling with. How do I “reverse” this? Ie remove the Properties I just added? I like to document changes with a rollback (to be able to return the system back to its previous state)..
I cant seem to find a method to delete a single named property.. or worst case a “remove-VIProperty” equivalent…
Hey Jason
Currently there is nothing in the GUI or in the suite-api that can remove Properties (confirmed by VMware), I raised a requirement with them to implement this in a future release of the product and hopefully it makes it in at some point…
But I did come up with a solution… you can check it out Here, its the only thing I could come up with… use it at your own risk but it works for me.
Cheers
vMan
Thanks – I have multiple resources with the same name although they have different resourceKindKey’s. Is there a way to filter for a specific resourceKindKey as well as a VM Name in the lookup so that I get the right ID?
I don’t have access to my vRops lab at the moment so I cant test it but i think you can do the following replacements on my script to solve your problem….. See the lines below.
Function GetObject([String]$vRopsObjName, [String]$vRopsServer, $User, $Password){
replace it with
Function GetObject([String]$vRopsObjName, [String]$vRopsServer, [String]$ResKind, $User, $Password){
then
[xml]$Checker = $wc.DownloadString(“https://$vRopsServer/suite-api/api/resources?name=$vRopsObjName”)
with
[xml]$Checker = $wc.DownloadString(“https://$vRopsServer/suite-api/api/resources?name=$vRopsObjName&resourceKind=$ResKind”)
and the last replacement…
$resourceLookup = GetObject $VM.NAME $vRopsAddress $vRopsUser $vRopsPassword
with
$resourceLookup = GetObject $VM.NAME $vRopsAddress ‘VirtualMachine’ $vRopsUser $vRopsPassword
I used ‘VirtualMachine’ as an example but you can replace this with the resourceKindKey you require.
Let me know how you go.
Thanks for your reply. I went down that path originally but can’t seem to get any download string to filter out only the Virtual Machines that match my criteria by & in the url. It still returns all results with the same Virtual Machine Name. I have also tried adding a Foreach statement after the If ([Int]… statement, but everything I tried still returns all the results which of course, causes the post to vROps to fail with a (400) Bad request because it has multiple identifiers in the string.
Is the email you posted this comment with valid?
If so I will send you an email, if you can send me some screenshots of the issue / results I will try to help further.
Cheers
vMan
Hi, yes it is valid. I will wait for your email.
Awesome post! Very exciting to see the power of Suite API. With REST, is it possibly to update the severity property of an alert definition for vROps? For example, changing the severity from Warning to Informational?
thanks, what do you mean? do you want to change the alert definition via the API?
Correct, I want to be able to change the properties of an alert definition with the API.
yes it appears to be possible, I have not done it myself but it does not appear to be to difficult… check the suite-api documentation for PUT /api/alertdefinitions
if I get some time I might write a blog post about it but not this week.
vMan
Thanks to your script, I was able to update the alert definition criticality state and other properties. I just needed to change the xml file and update these two lines:
$urlsend = ‘https://’ + $vRopsServer + ‘/suite-api/api/alertdefinitions/’
$ContentType = “application/xml;charset=utf-8”
Invoke-RestMethod -Method PUT -uri $urlsend -Body $xmlSend -Credential $cred -ContentType $ContentType
cool glad it helped you!