VMware Cloud Community
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Register VMs in a datastore in the vCenter inventory

Hi to all the scripting guru's out there,

I'm putting together a DR solution for our VM's, we are currently using the IBM Storwize V7000 with Remote Copy to replicate some Datastores.

Now I have done some extensive testing and found that when you perform a switch from PROD to DR there is a a bit of a process to get the VM's up and running.

1. I have to do a full rescan of the HBAs. Under storage adapters you can see the assigned storage devices as mounted, however you still need to go to Storage and go the the "Add Storage" wizard to readd the Datastore with the option resignaturing the volume. So this part isn't so painful except it appends a different naming convention to the datastore name, example a datastore named prd_lun100 gets named snap-5a18365a-prd_lun100 so I have to rename the datastore back to the default.

2. I have to go through the datastores and add every virtual machine into inventory which is very tedious, and the very part I need to automate.

I tried this one liner, which I found here -> http://www.wooditwork.com/2011/08/11/adding-vmx-files-to-vcenter-inventory-with-powercli-gets-even-e...

New-VM -VMFilePath "[prd_lun100] SERVER01/SERVER01.vmx" -VMHost "VMHost01.local"

If possible I would like to expand on this, in the following ways:

1. Automate adding the datastores with the correct naming convention, by using either the naa identifier of the LUN or LUN ID#, possibly pull this info from a CSV list.

2. Add VM as per the one liner above but from a CSV list of some sort, however add is to a DRS Cluster rather ESXi Host, if possible prioritize adding VMs by some sort of groups flag in the CSV.

3. Power on VMs based on a priority.

I would really really appreciate if some one can help with this, I know probably a big ask, but scripting is not my forte and wouldn't know where to start.

Nicholas
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

That shouldn't be too difficult.

Read the filenames from a CSV file and then check for each VMX file you find if it is in the list.

Something like this

$targetVMX = Import-Csv C:\vmxnames.csv -UseCulture

$Cluster
= "LON_PROD1"
$Datastores
= "lonservers*"
$VMFolder = "LondonAppServers"
$ESXHost
= Get-Cluster $Cluster | Get-VMHost | select -First 1
foreach
($Datastore in Get-Datastore $Datastores) {    # Set up Search for .VMX Files in Datastore    $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}    $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
   $SearchSpec.matchpattern = "*.vmx"
   $dsBrowser = Get-View $ds.browser
   $DatastorePath = "[" + $ds.Summary.Name + "]"
  
# Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)    $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}    #Register all .vmx Files as VMs on the datastore    foreach($VMXFile in $SearchResult) {      if($targetVMX -contains $VMXFile){       New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $Folder -RunAsync
    }    } }


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

View solution in original post

Reply
0 Kudos
96 Replies
nicholas1982
Hot Shot
Hot Shot
Jump to solution

OK so I test this which works well, but if someone can help with modifying it so it pulls the VMX info from a list would suite me better

$Cluster = "LON_PROD1"
$Datastores = "lonservers*"
$VMFolder = "LondonAppServers"
$ESXHost = Get-Cluster $Cluster | Get-VMHost | select -First 1
foreach($Datastore in Get-Datastore $Datastores) {
   # Set up Search for .VMX Files in Datastore
   $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}
   $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
   $SearchSpec.matchpattern = "*.vmx"
   $dsBrowser = Get-View $ds.browser
   $DatastorePath = "[" + $ds.Summary.Name + "]"
   # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)
   $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}
   #Register all .vmx Files as VMs on the datastore
   foreach($VMXFile in $SearchResult) {
      New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $Folder -RunAsync
   }
}
Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

What exactly do you mean by pulling the VMX info from a list ?

Do you want to provide a list of VM names and only register the corresponding VMX files ?

Note that this will only work if the DisplayName in the VMX is the same as the filename of the VMX file.


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

Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

Thanks for your reponse, yes was thinking a list like

List

[V7K_LUN60] SRV102/SRV102.vmx

[V7K_LUN60] SRV103/SRV103.vmx
However I have been playing arround with search datastore and add VM to inventory, and it seems to work wel, I guess i wanted to take a little more control of what I was adding. In addition I need a way of scripting/automating the powering on of the VM's based on a priority, not to mention answer that question "I moved it"
I found a two liner that can power on VM's in a folder and answer that question but as you can see its not perfect.
Get-VM -Location (Get-Folder -Name "DR_Folder") | Start-VM -RunAsync
Get-VMQuestion | Set-VMQuestion -Option "I moved it" -Confirm:$false
Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That shouldn't be too difficult.

Read the filenames from a CSV file and then check for each VMX file you find if it is in the list.

Something like this

$targetVMX = Import-Csv C:\vmxnames.csv -UseCulture

$Cluster
= "LON_PROD1"
$Datastores
= "lonservers*"
$VMFolder = "LondonAppServers"
$ESXHost
= Get-Cluster $Cluster | Get-VMHost | select -First 1
foreach
($Datastore in Get-Datastore $Datastores) {    # Set up Search for .VMX Files in Datastore    $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}    $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
   $SearchSpec.matchpattern = "*.vmx"
   $dsBrowser = Get-View $ds.browser
   $DatastorePath = "[" + $ds.Summary.Name + "]"
  
# Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)    $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}    #Register all .vmx Files as VMs on the datastore    foreach($VMXFile in $SearchResult) {      if($targetVMX -contains $VMXFile){       New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $Folder -RunAsync
    }    } }


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

Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Thanks Luc,

Would posible to have the VMs power on in the same script or would have to have 2 script and run it after this one completes?

I need to be able to power on and answer the question about keeping the UUID

Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you remove the RunAsync parameter on the New-VM cmdlet, you should be able to insert your 2 lines to start and asnwer in the same block.


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

nicholas1982
Hot Shot
Hot Shot
Jump to solution

Thanks Luc, I will gave that a try.

Sorry just one more dumb question, I tried the CSV list modified script but it didnt work, its possible the CSV is formatted in the correct way, do mind explaining how should be?

Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The blank in the VMX filename probably causes a problem.

Use the Get-Content cmdlet instead, like this

$targetVMX = Get-Content C:\vmxnames.csv

The rest of the script should stay the same


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

nicholas1982
Hot Shot
Hot Shot
Jump to solution

Thanks again, I will give that a try Smiley Happy

Nicholas
Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

I must not be creating the CSV list correctly, it doesn't do anything. On the other hand the other script which adds all vms from specified datastores works well, I have even appended the start-vm and answer question as you suggested. but some reason i get some errors in the task list, it does work but wondering if the script requires some tweaks, please see screenshot. I have attached both scripts as well.

Capture.JPG

Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Could it be that some of these VMs are already powered on ?

That's what the error seems to suggest.


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

Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

No I'm testing it on 5 vms, each time it test it I power them off and remove it from inventory.

Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Are the Tasks in the screenshot from 1 run of the script ?

I see the same VM being powered on multiple times.


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

Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

Yes I just run the script once, it appears to be trying to start a vm that is already in the process of powering on.

Sent from my iPhone

Nicholas
Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

I removed the -RunAsync on line 20 and the errors in the tasks don't appear anymore but now i get heaps of errors showing up on CLI, however it does all work fine, I have attached the output of the CLI, you may know exactly what it is causing it.

Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

There seem to be several errors that appear.

  • one VM already seems to be registered. You could test if the VM already exists before trying to register the VMX file
  • The poweron seems to happen before the question was answered in some cases. Could it be that the order of the Start-VM and the Set-VMQuestion cmdlets is incorrect ?
  • You try to poweron some VMs that are apparently already powered on. You could check the powersate of the VM before you do a Start-VM

Is the script you are using the one you included in a previous post ?

Otherwise attach the latest version.


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

Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

I actually power off and unregister all the vm's NSTESTPC, SRV100, SRV101, SRV102, SRV103 prior to running the script. I even browse the datastore move those VM's into another directory, to simulate the question. I have attached the script in this post.

What I thisk would be good is registering and powering on VMs based on a list, that way I can group the powering on of VM based on priority, im not sure if that would be easier. i just don't understand why it work but shows errors.

Nicholas
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You were retrieving all the VMs in that folder, not just the VM you just registered.

Try it like this (I made some other changes as well)

$Cluster = "V7000 Cluster" 
$Datastores
= get-datastore snap*$DatastoreNames*
$VMFolder = "DR_Folder"
$ESXHost
= Get-Cluster $Cluster | Get-VMHost | select -First 1
foreach
($Datastore in Get-Datastore $Datastores) {    # Set up Search for .VMX Files in Datastore    $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}    $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
   $SearchSpec.matchpattern = "*.vmx"
  
$dsBrowser = Get-View $ds.browser
   $DatastorePath = "[" + $ds.Summary.Name + "]"    # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)    $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}    #Register all .vmx Files as VMs on the datastore    foreach($VMXFile in $SearchResult) {       $vm = New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder
     
if($vm.PowerState -ne "PoweredOn"){         $vm = Start-VM -VM $vm
      }      
while($vm.PowerState -ne "PoweredOn"){         sleep 5
       
$vm = Get-VM $vm.Name
      }      
Get-VMQuestion -VM $vm | Set-VMQuestion -Option "I moved it" -Confirm:$false
   } } }


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

Reply
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

Thanks for your time with this, I wish there were some way I could repay you??

Anyway the last script doesn't run, I get the following error. Also just to clarify does $VMFolder specify what folder in the inventory to add the VM to?

PowerCLI C:\scripts> .\poor-man-SRM.ps1

Invalid assignment expression. The left hand side of an assignment operator nee
ds to be something that can be assigned to like a variable or a property.
At C:\scripts\poor-man-SRM.ps1:4 char:12
+ $VMFolder = <<<<  "DR_Folder"
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : InvalidLeftHandSide
Nicholas
Reply
0 Kudos