VMware Cloud Community
bridrod
Enthusiast
Enthusiast

Finding a VM in vROPS and vCenter VM belongs to using Powershell

Hi,

I am trying to use PowerShell to pull some VM info from vRealize Operations Manager (vROPS). The idea is to search for a VM, and find out if the VM exists in any of our vCenters and display which one if found. Since vROPS is plugged with all the vCenters, I though leveraging that would be the way to go (instead of connecting to dozens of vCenters). So far I was able to do this:

$VM = "TESTVM"
Connect-OMServer VROPS_SERVERR -User USERNAME -Password PASSWORD
Get-OMResource -AdapterKind VMWARE -ResourceKind VirtualMachine | where { $_.Name -match $VM }

It finds the VM, but it does not provide the vCenter where the VM is registered under.

When I use the GUI, it shows me the vCenter too.

Any help is greatly appreciated!

Rod

0 Kudos
10 Replies
KabirAli82
Expert
Expert

You're getting the VM name because you are looking for just the VM. While which vCenter is a property of that VM.

 

Maybe Get-Omstatkey can help you:

https://developer.vmware.com/docs/powercli/latest/vmware.vimautomation.vrops/commands/get-omstatkey/...

 

Else you'll have to do an API call. Personally I don't use the vROps cmdlets, I always use the API which gives me more freedom.


Was I helpful? Give a kudo for appreciation!
Braindumping @ http://kablog.nl/
Tweeting @ https://twitter.com/_Kabir_Ali_
0 Kudos
bridrod
Enthusiast
Enthusiast

Thanks for the info. I am playing with it currently, trying to find out if and where the vCenter information would be.

I also found this: https://docs.vmware.com/en/vRealize-Operations-Manager/8.2/com.vmware.vcom.metrics.doc/GUID-E68037C7...

Under "Summary Properties Collected for Virtual Machine Objects" it mentions:

Property Key                              Property Name              Description

summary|parentVcenterParent vCenterParent vCenter

 

Not yet sure how to pull that property, though.

Talking about the API, if I go that route, where in the API would the VM vCenter information be stored? Do you have a code snippet to share (or API URL) ?

Thanks,

Rod

0 Kudos
KabirAli82
Expert
Expert

Check this out!

https://www.kablog.nl/2021/10/26/again-helping-the-community/

 


Was I helpful? Give a kudo for appreciation!
Braindumping @ http://kablog.nl/
Tweeting @ https://twitter.com/_Kabir_Ali_
0 Kudos
bridrod
Enthusiast
Enthusiast

Thanks for taking the time to create the script! Really appreciate it! 😊

Unfortunately it did not work for me. I tried on 2 x different versions of vROPS, just in case (8.0.0-1.11.0-14857692 and 8.2.0-1.13.0-16949153). This is the error I get (tried in 2 x different machines):

System.Management.Automation.ParameterBindingValidationException: Cannot validate argument on parameter 'Uri'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. ---> System.M
anagement.Automation.ValidationMetadataException: The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
at System.Management.Automation.ValidateNotNullOrEmptyAttribute.Validate(Object arguments, EngineIntrinsics engineIntrinsics)
at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)


Exception : System.Management.Automation.ParameterBindingValidationException: Cannot validate argument on parameter 'Uri'. The argument is null or empty. Provide an argument that is not null or empty, and then try the
command again. ---> System.Management.Automation.ValidationMetadataException: The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
at System.Management.Automation.ValidateNotNullOrEmptyAttribute.Validate(Object arguments, EngineIntrinsics engineIntrinsics)
at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : InvalidData: (:) [Invoke-RestMethod], ParameterBindingValidationException
FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, C:\temp\vROPS-Query.ps1: line 79
at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
PSMessageDetails :

Thanks,

bridrod

0 Kudos
KabirAli82
Expert
Expert

Ah there was an typo in the script. Download it again.


Was I helpful? Give a kudo for appreciation!
Braindumping @ http://kablog.nl/
Tweeting @ https://twitter.com/_Kabir_Ali_
0 Kudos
bridrod
Enthusiast
Enthusiast

Found the issue: I had to replace $nee with $VMvCenterURI then it worked. I found a couple of cases, where (for whatever reason) some VMs are found with multiple resourceIDs, causing the script not to work properly, giving out the below error message.

Is is possible to loop through the different IDs and display the parent vCenter?

System.Net.WebException: The remote server returned an error: (400) Bad Request.
   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()

Exception             : System.Net.WebException: The remote server returned an error: (400) Bad Request.
                           at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
                           at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
TargetObject          : System.Net.HttpWebRequest
CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, C:\temp\vROPS-Query.ps1: line 81
                        at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
PSMessageDetails      : 

 Thanks,

 

0 Kudos
KabirAli82
Expert
Expert

Try the version 1.1. I worked around the multiple resourceIDs by filtering on virtualMachines only.


Was I helpful? Give a kudo for appreciation!
Braindumping @ http://kablog.nl/
Tweeting @ https://twitter.com/_Kabir_Ali_
bridrod
Enthusiast
Enthusiast

Perfect! Thanks a bunch! 😁

I went ahead and made some modifications to that original script for my needs:

1 - Added a foreach loop to the script, to be able to search for multiple VMs;

2 - Added a foreach loop to the script, to be able to search for multiple ResourceIDs when multiple are found when matching the VM name (i.e.: SRM VMs, possible re-imaged VM or duplicate VM names in different vCenters);

3 - Added a foreach loop to search in multiple vROPS;

4 - Added a couple of error handling/messages, in case VM is not found or multiple VMs are found;

Could not get here without your involvement! Kudos to you! 👍

0 Kudos
KabirAli82
Expert
Expert

Sweet! If you don't mind share your code, i'll update mine. That way we help the next person looking for a simular solution. 🙂


Was I helpful? Give a kudo for appreciation!
Braindumping @ http://kablog.nl/
Tweeting @ https://twitter.com/_Kabir_Ali_
0 Kudos
bridrod
Enthusiast
Enthusiast

Sure thing! Here's my code:

 

cls
Write-Host "Gathering VM Information..."

$vROpsServers = "VROPS1 VROPS2 VROPS3 etc" | Foreach-object {$_ -split " "} | where{$_ -ne ""}
$VMNames = "VM1 VM2 VM3 etc" | Foreach-object {$_ -split " "} | where{$_ -ne ""}
$vROpsUser = "username1"
$vROpsPass = "password1"

foreach ($VM in $VMNames){
foreach ($vROpsServer in $vROpsServers){

Write-Host "======Searching for VM=$VM using Server=$vROpsServer======"

# Adding certificate exception to prevent API errors
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

# Building vROps API string & invoking REST API
$BaseURL = "https://" + $vROpsServer + "/suite-api/api/"
$BaseAuthURL = "https://" + $vROpsServer + "/suite-api/api/auth/token/acquire"
$Type = "application/json"

# Creating JSON for Auth Body
$AuthJSON =
"{
  ""username"": ""$vROpsUser"",
  ""password"": ""$vROpsPass""
}"
# Authenticating with API
Try {
    $vROpsSessionResponse = Invoke-RestMethod -Method POST -Uri $BaseAuthURL -Body $AuthJSON -ContentType $Type
}
Catch {
    $_.Exception.ToString()
    $error[0] | Format-List -Force
}
# Extracting the session ID from the response
$vROpsSessionHeader = @{"Authorization"="vRealizeOpsToken "+$vROpsSessionResponse.'auth-token'.token
"Accept"="application/json"}

# Get VM's unique identifier
Try {
$VMNamesURI = $BaseURL+"resources?resourceKind=virtualmachine&name="+$VM
$VMNamesID = (Invoke-RestMethod -Method GET -Uri $VMNamesURI -Headers $vROpsSessionHeader -ContentType $Type).resourceList.identifier
if($VMNamesID -like $null){
  Write-Host "We were not able to find VM=$VM on Server=$vROpsServer. There is no Resource ID present!"
}
}
Catch {
    $_.Exception.ToString()
    $error[0] | Format-List -Force
}

# Get VM's vCenter
foreach ($RID in $VMNamesID) {

Try {
$VMvCenterURI = $BaseURL+"resources/properties?resourceId="+$RID
$VMvCenter = ((Invoke-RestMethod -Method GET -Uri $VMvCenterURI -ContentType $Type -Headers $vROpsSessionHeader).resourcePropertiesList.property | where {$_ -like "*summary|parentVcenter*"}).value
}
Catch {
    $_.Exception.ToString()
    $error[0] | Format-List -Force
}

# Output
Write-Host "Found VM:" $VM "on vCenter:" $VMvCenter
}

# Close sessions and done
Invoke-RestMethod -Method POST -Uri $BaseURL"/auth/token/release" -Headers $vROpsSessionHeader -ContentType $Type
}
}

 

 

0 Kudos