Hello all
Hoping someone might be able to help me please.
According to the Documentation Centre here, you can create a report of the Protected VM's using the below script:
1. List all protection groups associated with the SRM server.
$srmApi = $srm.ExtensionData
$protectionGroups = $srmApi.Protection.ListProtectionGroups()
2. Generate a report of the protected virtual machines.
$protectionGroups | % {
$protectionGroup = $_
$protectionGroupInfo = $protectionGroup.GetInfo()
# The following command lists the virtual machines associated with a protection group
$protectedVms = $protectionGroup.ListProtectedVms()
# The result of the above call is an array of references to the virtual machines at the vSphere API
# To populate the data from the vSphere connection, call the UpdateViewData method on each virtual machine view object
$protectedVms | % { $_.Vm.UpdateViewData() }
# After the data is populated, use it to generate a report
$protectedVms | %{
$output = "" | select VmName, PgName
$output.VmName = $_.Vm.Name
$output.PgName = $protectionGroupInfo.Name
$output
}
} | Format-Table @{Label="VM Name"; Expression={$_.VmName} }, @{Label="Protection group name"; Expression={$_.PgName} }
The problem I am having is in step 1, specifically this part: $protectionGroups = $srmApi.Protection.ListProtectionGroups()
I'm using PowerCLI version VMware-PowerCLI-6.3.0-3639347, and can successfully connect-viserver and subsequently connect-srmserver works too.
The first variable of $srmApi = $srm.ExtensionData is set successfully, but the second returns the error "You cannot call a method on a null-valued expression".
Here's the exact output from the CLI session:
PowerCLI C:\> $protectionGroups = $srmApi.Protection.ListProtectionGroups()
You cannot call a method on a null-valued expression.
At line:1 char:1
+ $protectionGroups = $srmApi.Protection.ListProtectionGroups()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
PowerCLI C:\>
My end goal is to have a script that will create a list of all SRM protected VM's within the estate, but I would also like to have additional information for the VM's - like vCPU count, vRAM, hostname and OS version for example. I just can't even get over the first hurdle.
Thanks all.
Comes back empty:
PS C:\WINDOWS\system32> $srmApi.Protection
PS C:\WINDOWS\system32>
So does $srmAPI.
And what does Connect-SrmServer -Server <your-SRM-server> | Get-Member show?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I had to amend it slightly, as it couldn't find the server hostname (despite DNS resolving it successfully). But here's the output:
PS C:\WINDOWS\system32> Connect-SrmServer -SrmServerAddress <srm-ip-address> | Get-Member
TypeName: VMware.VimAutomation.Srm.Impl.V1.SrmServerImpl
Name MemberType Definition
---- ---------- ----------
BeginConnectionUse Method void SrmServerInterop.BeginConnectionUse()
ConvertToVersion Method T ConvertToVersion[T](), T VersionedObjectInterop.ConvertToVersion[T]()
EndConnectionUse Method void SrmServerInterop.EndConnectionUse(bool force)
Equals Method bool Equals(System.Object obj)
GetClient Method void GetClient(), VMware.VimAutomation.Srm.Interop.V1.SrmClientInterop SrmServerIntero...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
IsConvertableTo Method bool IsConvertableTo(type toType), bool VersionedObjectInterop.IsConvertableTo(type type)
LockUpdates Method void ExtensionData.LockUpdates()
ToString Method string ToString()
UnlockUpdates Method void ExtensionData.UnlockUpdates()
Build Property string Build {get;}
ExtensionData Property System.Object ExtensionData {get;}
Id Property string Id {get;}
InstanceUuid Property string InstanceUuid {get;}
IsConnected Property bool IsConnected {get;}
IsInUse Property bool IsInUse {get;}
Name Property string Name {get;}
Port Property int Port {get;}
ProductLine Property string ProductLine {get;}
RefCount Property int RefCount {get;}
ServiceUri Property uri ServiceUri {get;}
SessionSecret Property string SessionSecret {get;}
Uid Property string Uid {get;}
User Property string User {get;}
Version Property string Version {get;}
That seems ot be ok.
Now try
$srmApi = $SrmConnection.ExtensionData
$srmApi | Get-Member
If that returns a list including the Protection property, do
$srmApi.Protection | Get-Member
If that list contains a method called ListProtectionGroups, do
$srmApi.Protection.ListProtectionGroups()
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Every part came back as described.
The final output was a MoRef, with multiple lines that looked like this:
SrmProtectionGroup-srm-vm-protection-group-<different-number-here>
Those are pointers, you can get the actual object with
Get-View -Id $_
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
A little bit beyond my understanding... sorry to ask more questions.
Do I just run that section of code following the previous one, or should I run them together or pipe one to the other please?
Like this
$srmApi = $SrmConnection.ExtensionData
$srmApi.Protection.ListProtectionGroups() |
ForEach-Object -Process {
Get-View -Id $_
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks. Here's the output (first section as its repeated multiple times):
Get-View : Cannot bind parameter 'Id'. Cannot convert the "VMware.VimAutomation.Srm.Views.SrmProtectionGroup" value
of type "VMware.VimAutomation.Srm.Views.SrmProtectionGroup" to type "VMware.Vim.ManagedObjectReference".
At line:8 char:17
+ Get-View -Id $_
+ ~~
+ CategoryInfo : InvalidArgument: (:) [Get-View], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInter
op.GetVIView
My bad (I'm obviously not a regular SRM user and your MoRef mention threw me off).
Try this instead
$SrmConnection = Connect-SrmServer -Server <srm-ip-address>
$srmApi = $SrmConnection.ExtensionData
$srmApi.Protection.ListProtectionGroups() |
ForEach-Object -Process {
$_.GetInfo()
$_.ListAssociatedVms()
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Don't worry about it - without your help I wouldn't be this far
So that gets me to authenticate, and then shows the following output:
Name Description Type
---- ----------- ----
<group-name> <description-here> vr
The output table isn't formatted in a readable way as such, but it does contain some of the groups we have configured. It didn't show any VM's within the groups.
So the line $_.ListAssociatedVms() didn't return anything?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Btw, this recaps most of what we have been doing, and I assume it is still valid.
See PowerCLI 5.5 R2 and the Site Recovery Manager API
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
[EDIT] My bad, just saw your screenshot. It is vSphere replication (vr) - (worth mentioning the guide though, it's good)
How is your replication handled? ListAssociatedVMs() only works for vSphere replication. Not ABR.
more info in the Site Recovery Manager API Developer's Guide
Replication is via VR as far as I can tell.
Whilst we are on that subject, is there a way to do a get-vm, and filter the results by what is replicated, and how often its replicated please?
I use array based replication in my environment which is different from vSphere replication so I can't do any tests.
However I recommend you check out this github, the guy did an amazing job at wrapping the main operations into funcitons.
The annoying bit with the SRM module is that you get MoRef IDs which you must then use to get the actual VI object.
To give you an idea you could do something like this to get the replicated VMs as "VM" objects.
Function Get-ReplVMs {
$pg = $SRM.extensiondata.protection.listprotectiongroups()
$RepVM = $pg.listprotectedvms()
$VmID = $RepVM.vm.moref
Get-VM -id $VmID
}
Now that's a quick and dirty function to show you the different steps involved, don't take it too seriously .
Because vSphere replication and ABR are quite different I suggest you do some tests and see for yourself how it handles cases where a VMs is unprotected, left with an ISO, deleted ...
That GitHub link was really useful, thanks.
The output looks like this:
VM Name Protection group name
------- ---------------------
<VM-name> <PG-name>
The code I ran was is below, which is taken from ReadMe of the Git link:
Get-SrmProtectionGroup | %{
$pg = $_
Get-SrmProtectedVM -ProtectionGroup $pg } | %{
$output = "" | select VmName, PgName
$output.VmName = $_.Vm.Name
$output.PgName = $pg.GetInfo().Name
$output
} | Format-Table @{Label="VM Name"; Expression={$_.VmName} },
@{Label="Protection group name"; Expression={$_.PgName}
}
It's almost exactly what I need, but some of the VM names are longer than the table column is allowing - so they look like "myvmnam..." rather than "myvmname" for example.
Any ideas how I can format the table to expand as required please? What about outputting the table to a file / csv?
This is taking it to the next stage, and would be ideal if it worked... I'd have thought it can be tweaked even further, to include the memory and CPU counts too for example, in the output table. I have used "get-vm $vmList | Select-object Name, Guest, UsedSpaceGB, ProvisionedSpaceGB, MemoryGB, NumCPU, Notes | Export-Csv C:\Users\<username>\Documents\srm_vm_details.csv", and that gives all the details of the VM's that have been requested.
I'd guess the line "$output = "" | select VmName, PgName" above could have the other bits added, but not sure how the rest of the code would have to be changed to accommodate the additional information.
Can you try this way?
It makes it a lot easier to add columns to the output, just add properties on the Select (like I did with NumCpu and MemoryGB.
ForEach-Object -Process {
$pgInfo = $_.GetInfo()
Get-SrmProtectedVM -ProtectionGroup $pg |
ForEach-Object -Process {
Get-VM -Name $_.Vm.Name |
Select @{N = "VM Name"; E = {$_.Name} },
NumCpu, MemoryGB,
@{N = "Protection group name"; E = {$pgInfo.Name}}
}
} | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
EDIT: Sorry, but the output isn't quite right having reviewed it. It's listed some of the VM's and their details, but it's listing 12 VM's and then starting the next line with the same 12 VM's.
Awesome!
Last request... promise!
Can the current Protection Status be pulled into the same table?
For example, if I do a simple export from the GUI, the column headers are:
Virtual Machine, Protection Status, Recovery Resource Pool, Recovery Host, Recovery Folder, Recovery Network and Recovery Plans.
If the rest can be grabbed too... well. That would make my day :smileylaugh:.