1 2 3 Previous Next 33 Replies Latest reply on Sep 21, 2012 2:10 PM by IRCScott

    How to script adding .VMX's from a Datastore (NFS) to Virtual Center

    sddunne Novice

       

      Hi Guys,

       

       

      I'm hoping someone with a much better understanding of scripting than I will know of a simple way of doing this?

       

       

      Basically, here is the scenario...

       

       

      We use NFS Datastores running on Netapp Filers to house all of our Virtual Machines. This normally works great however we have had a few incidents recently with the filer which has meant us having to switch to our snapmirrored backups. Basically how this works is that each datastore, say for example Datastore1 normally runs on Filer1. This datastore is regulary 'snapmirrored' across to Filer2. this snapmirror is a readonly copy of the datastore. If we have a problem with Filer1, it is possible to reconfigure Filer2 to make the backup snapmirror writeable, effectively allowing us to see the vm's again.

       

       

      Currently, if this happens, in order to get the Vm's back we need to remove all the vm's from Virtual Center Inventory, then add the snapmirrored datastore to all the hosts in Virtual Center, then Browse the datastore and manually add back all the vm's individually by doing the usual right click/add to inventory on each vm.

       

       

      As i say we recently had an issue and had to invoke this for 10 datastores housing almost 250 vm's so as you can imagine was quite a slow and labour intensive task!!!

       

       

      What i've been trying to work out is how i could script this in Power CLI? I've seen LuCD's excellent looking add .vmx script and looks very similar to what i'd like to do but can't work out how to modify it for my purposes.

       

       

      What id' ideally love to get to would be a script that i can specify a Virtual Center instance, Datastore and Cluster as variables (say vcname$ = "ukvir0001" , cluster$ = "Datacentre1" and dsname$ = "datastore1") and then have the script read the datastore and add any .vmx's it finds to the specified Cluster.

       

       

      I've been reading with interest the new Datastore Provider functionality in PowerCLI4 and that sounds like something that may provide an easy way of doing it i just can't work out how!

       

       

      Any help would be very much appreciated as i have the daunting task of having to move almost 250 vm's back over to Filer1 now that the filer has been repaired and don't have the luxury of a several hour maintenance window to do it manually!

       

       

      Many thanks,

      Sean.

       

       

       

       

       

        • 1. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
          LucD Guru
          Community WarriorsUser ModeratorsvExpert

          Hi Sean,

          I have adapted my earlier script a bit to able to work with the parameters you specified.

          The function Register-Vmx can be called with the 3 parameters (VCname, ClusterName, DSName) as you preferred.

          
          function Register-Vmx{
               param($vcname, $cluster ,$dsname)
          
               Connect-VIServer -Server $vcname
               $datacenter = (Get-View (Get-View -Id (Get-Cluster $cluster).parentid).parent).Name
               $ESXname = Get-Cluster $cluster | Get-VMHost | select -First 1
          
               $folder = Get-View (Get-Datacenter -Name $datacenter | Get-Folder -Name "vm").ID
               $pool = Get-View (Get-Cluster -Name $cluster | Get-ResourcePool -Name "Resources").ID
          
               $esxImpl = Get-VMHost -Name $ESXname
               $esx = Get-View $esxImpl.ID 
               $dsBrowser = Get-View $esx.DatastoreBrowser
               foreach($dsImpl in $dsBrowser.Datastore){
                    $ds = Get-View $dsImpl
                    $vms = @()
                    foreach($vmImpl in $ds.Vm){
                         $vm = Get-View $vmImpl
                         $vms += $vm.Config.Files.VmPathName
                    }
                    $datastorepath = ""
          
                    $searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
                    $searchSpec.matchpattern = "*.vmx"
          
                    $taskMoRef = $dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec) 
                    $task = Get-View $taskMoRef 
                    while ($task.Info.State -eq "running"){$task = Get-View $taskMoRef}
          
                    foreach ($file in $task.info.Result){
                         $found = $FALSE
                         foreach($vmx in $vms){
                              if(($file.FolderPath + $file.File[0].Path) -eq $vmx){
                                   $found = $TRUE
                              }
                         }
                         if (-not $found -and $task.Info.Result[0].File -ne $null){
                              $vmx = $file.FolderPath + $file.File[0].Path
                              $params = @($vmx,$null,$FALSE,$pool.MoRef,$null)
                              $folder.GetType().GetMethod("RegisterVM_Task").Invoke($folder, $params)
          
                         }
                    }
               }
               Disconnect-VIServer -Server $vcname
          }
          
          # Sample function call
          Register-Vmx "MyVCName" "MyClusterName" "MyDatastoreName"
          
          

           

          The RegisterVM_Task doesn't contain an ESX server pointer. It's DRS that will decide to which ESX server in the cluster the guest will be registered.

          This should guarantee an good spread of the guests over the different ESX servers in the cluster.

          • 2. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
            sddunne Novice

            Hi LucD,

             

            Thanks for the very speedy reply!!

             

            I just tried the script using the following ;

             

            Register-Vmx "ukvir09100" "IOC Management Cluster" "test"

             

            The Datastore is called test!

             

            And got the following error;

             

            C:\Powershell\TestScripts> .\AddAllVMX.ps1

             

            Name                       Port                       User

            -


                                   -


                                   -


            ukvir09100                 443                        UK\a-sdunne

            Get-Cluster : 03/06/2009 13:21:12    Get-Cluster        Cluster with name 'its'

            not found, using the specified filter(s).

            At C:\Powershell\TestScripts\AddAllVMX.ps1:5 char:52

            +     $datacenter = (Get-View (Get-View -Id (Get-Cluster  <<<< its).parentid).p

            arent).Name

            Get-View : The argument cannot be null or empty.

            At C:\Powershell\TestScripts\AddAllVMX.ps1:5 char:39

            +     $datacenter = (Get-View (Get-View -Id  <<<< (Get-Cluster its).parentid).p

            arent).Name

            Get-Datacenter : The argument cannot be null or empty.

            At C:\Powershell\TestScripts\AddAllVMX.ps1:8 char:42

            +     $folder = Get-View (Get-Datacenter -Name  <<<< $datacenter | Get-Folder -

            Name "vm").ID

            C:\Powershell\TestScripts>

             

            The other thing i forgot to add to the mix is that the way Netapp NFS Datastores work is that they also produce a .snapshot folder in every datastore that holds all the snapshot backups for that datastore, i'm guessing the script would also need to exclude that folder somehow to stop all the backup snapshots from being added?

             

            Thanks again for your help with this, lifesaving work here!!

             

            Sean.

            • 3. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
              LucD Guru
              vExpertCommunity WarriorsUser Moderators

              There was an error in the attached script.

              It's corrected now. Sorry about that.

              • 4. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                sddunne Novice

                Hi LucD,

                 

                I can't see the revised script, did you attach it?

                 

                Many thanks!

                Sean.

                • 5. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                  LucD Guru
                  User ModeratorsvExpertCommunity Warriors

                  Yes, I replaced the faulty script in my first reply.

                  • 6. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                    sddunne Novice

                    Hi LucD,

                     

                    Doh! Can see it now! Just tried it again and getting;

                     

                    C:\Powershell\TestScripts> .\AddAllVMX.ps1

                    Name                       Port                       User

                    -


                                           -


                                           -


                    ukvir09100                 443                        UK\a-sdunne

                    Get-View : The argument cannot be null or empty.

                    At C:\Powershell\TestScripts\AddAllVMX.ps1:5 char:39

                    +     $datacenter = (Get-View (Get-View -Id  <<<< (Get-Cluster $cluster).parent

                    id).parent).Name

                    Get-Datacenter : The argument cannot be null or empty.

                    At C:\Powershell\TestScripts\AddAllVMX.ps1:8 char:42

                    +     $folder = Get-View (Get-Datacenter -Name  <<<< $datacenter | Get-Folder -

                    Name "vm").ID

                    C:\Powershell\TestScripts>

                    C:\Powershell\TestScripts>

                     

                    The script is far to complex for my skills (i can just about work my way through piping cmdlets into each other ), any ideas? Also any idea on excluding the .snapshot folder? I was thinking if excluding a folder is hard it might possibly be easier to set the folder depth to 1? I.e. the .snapshot folder looks like this;

                     

                    .snapshot

                           >>> hourly.0

                          >>> hourly.1

                          >>> nightly.0

                                   >>> VM1

                                        >>> VM1.vmx

                    VM2

                      >>> VM2.vmx

                     

                    If you see what i mean?

                     

                    Thanks again!

                    Sean.

                    • 7. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                      LucD Guru
                      Community WarriorsUser ModeratorsvExpert

                      I think I found the problem. A cluster is not always located directly under a datacenter.

                      The method to get at the datacenter's name has been changed.

                       

                      Can you try this version?

                      function Register-Vmx{
                           param($vcname, $cluster ,$dsname)
                      
                           $VCserver = Connect-VIServer -Server $vcname
                           $datacenter = (Get-Datacenter -VMHost (Get-Cluster $cluster | Get-VMHost | select -First 1)).Name
                           $ESXname = Get-Cluster $cluster | Get-VMHost | select -First 1
                      
                           $folder = Get-View (Get-Datacenter -Name $datacenter | Get-Folder -Name "vm").ID
                           $pool = Get-View (Get-Cluster -Name $cluster | Get-ResourcePool -Name "Resources").ID
                      
                           $esxImpl = Get-VMHost -Name $ESXname
                           $esx = Get-View $esxImpl.ID 
                           $dsBrowser = Get-View $esx.DatastoreBrowser
                           foreach($dsImpl in $dsBrowser.Datastore){
                                $ds = Get-View $dsImpl
                                if($ds.Summary.Name -ne $dsname){continue}
                                $vms = @()
                                foreach($vmImpl in $ds.Vm){
                                     $vm = Get-View $vmImpl
                                     $vms += $vm.Config.Files.VmPathName
                                }
                                $datastorepath = ""
                      
                                $searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
                                $searchSpec.matchpattern = "*.vmx"
                      
                                $task = Get-View ($dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec))
                                while ($task.Info.State -eq "running" -or $task.Info.State -eq "queued"){
                                     $task.UpdateViewData("Info.State")
                                     sleep 5
                                }
                                foreach ($file in $task.info.Result){
                                     $found = $FALSE
                                     foreach($vmx in $vms){
                                          if(($file.FolderPath + $file.File[0].Path) -eq $vmx){
                                               $found = $TRUE
                                          }
                                     }
                                     if (-not $found -and $task.Info.Result[0].File -ne $null){
                                          $vmx = $file.FolderPath + $file.File[0].Path
                                          $params = @($vmx,$null,$FALSE,$pool.MoRef,$null)
                                          $folder.GetType().GetMethod("RegisterVM_Task").Invoke($folder, $params)
                      
                                     }
                                }
                           }
                           Disconnect-VIServer -Server $VCserver -Confirm:$false
                      }
                      
                      # Sample function call
                      Register-Vmx "ukvir09100" "IOC Management Cluster" "test"
                      

                      Note: new attachment on this reply.

                       

                      Are you sure the .Snapshot folder is visible to the datastore ?

                      Can you check with the Datastore Browser in the VIC.

                      Could perhaps include a screenshot of the Datastore Browser so I can see which folders should be used to get at the .vmx files ?

                       

                      If the .Snapshot folder is visible it could be excluded while handling the results.

                      • 8. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                        sddunne Novice

                        Morning LucD,

                         

                        Alas its not working still, coming up with;

                         

                        PS C:\> .\addallvmxtest.ps1

                        Get-Datacenter : A parameter cannot be found that matches parameter name 'VMHos

                        t'.

                        At C:\addallvmxtest.ps1:5 char:39

                        +     $datacenter = (Get-Datacenter -VMHost  <<<< (Get-Cluster $cluster | Get-V

                        MHost | select -First 1)).Name

                        Get-Datacenter : The argument cannot be null or empty.

                        At C:\addallvmxtest.ps1:8 char:42

                        +     $folder = Get-View (Get-Datacenter -Name  <<<< $datacenter | Get-Folder -

                        Name "vm").ID

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        Exception calling "UpdateViewData" with "1" argument(s): "Object reference not

                        set to an instance of an object."

                        At C:\addallvmxtest.ps1:29 char:24

                        +             $task.UpdateViewData( <<<< "Info.State")

                        PS C:\>

                         

                        I've attached a couple of screenshots showing the .snapshot folder in the Datastore;

                         

                        Thanks again for your help with this, must be becoming a bit of a pain now!

                         

                        Cheers,

                        Sean.

                        • 9. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                          jahallen01 Lurker

                           

                          We have the same requirements as the original poster. The only difference is that we have two different datastores for each VM. Your original script works great however when we failover the NetApp and run the script it registers the first volume fine (because its on the same volume as the vmx) however the second datastore stays the same.

                           

                           

                          vmx is on vmprod-nj so it registers and sets the datastore to vmprod1-nj (which contains the VM's C and D drive)

                           

                           

                          The E drive is held on vmdata-nj so when we run the script everything works fine, when we failover the system:

                           

                           

                          vmprod-nj   ---&gt; vmprod_nj_dr

                           

                           

                          vmdata-nj ---&gt; vmdata_nj_dr

                           

                           

                          Now when we run the script the VM registers the vmx fine on vmprod_nj_dr however the E drive is still registered as vmdata-nj instead of vmdata_nj_dr.

                           

                           

                          Is there a way to change the datastore setting for the E drive on each VM?

                           

                           

                           

                           

                           

                          We change the script so that it looks for a single datastore during DR because we really only want to look for the mirrored volume and not all of the other datastores attached to the ESX host (we have a lot of NFS mounts)

                           

                           

                          $folder = Get-View (Get-Datacenter -Name "North America" | Get-Folder -Name "dr").ID

                           

                           

                          $pool = Get-View (Get-Folder "NYC" | Get-Cluster -Name "Servers" | Get-ResourcePool -Name "Production").ID

                           

                           

                          $esxImpl = Get-VMHost -Name ny-esxprd001.comp.com

                           

                           

                          $esx = Get-View $esxImpl.ID

                           

                           

                          $dsBrowser = Get-View $esx.DatastoreBrowser

                           

                           

                          foreach($dsImpl in $dsBrowser.Datastore){

                           

                           

                          $ds = Get-View $dsImpl

                           

                           

                          $vms = @()

                           

                           

                          foreach($vmImpl in $ds.Vm){

                           

                           

                          $vm = Get-View $vmImpl

                           

                           

                          $vms += $vm.Config.Files.VmPathName

                           

                           

                          }

                           

                           

                           

                           

                           

                          $datastorerr = ""

                           

                           

                          if ($datastorerr -eq "[vmprod_nj_dr]"){

                           

                           

                          $datastorepath = $datastorerr

                           

                           

                          $datastorepath

                           

                           

                          $searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec

                           

                           

                          $searchSpec.matchpattern = "*.vmx"

                           

                           

                          $taskMoRef = $dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec)

                           

                           

                          $task = Get-View $taskMoRef

                           

                           

                          while ($task.Info.State -eq "running"){$task = Get-View $taskMoRef}

                           

                           

                          foreach ($file in $task.info.Result){

                           

                           

                          $found = $FALSE

                           

                           

                          foreach($vmx in $vms){

                           

                           

                          if(($file.FolderPath + $file.File[0].Path) -eq $vmx){

                           

                           

                          $found = $TRUE

                           

                           

                          }

                           

                           

                          }

                           

                           

                          if (-not $found -and $task.Info.Result[0].File -ne $null){

                           

                           

                          $vmx = $file.FolderPath + $file.File[0].Path

                           

                           

                          $params = @($vmx,$null,$FALSE,$pool.MoRef,$null)

                           

                           

                          $folder.GetType().GetMethod("RegisterVM_Task").Invoke($folder, $params)

                           

                           

                          }

                           

                           

                          }}

                           

                           

                          }

                           

                          *

                          Disconnect-VIServer -Confirm:$False

                           

                          *

                           

                           

                           

                           

                          • 10. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                            LucD Guru
                            User ModeratorsCommunity WarriorsvExpert

                            After some PMs between Sean and myself, we came up with a working version.

                             

                            Note that this latest version of the script was tested in a vSphere environment against an ESXi v4 server.

                            • 11. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                              sddunne Novice

                              This works excellently and has saved our Bacon! Thanks again LucD!!!

                              • 13. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                                bulletprooffool Virtuoso
                                User Moderators

                                 

                                I'll be reviving this thread . .

                                 

                                 

                                I intend to use it as the second half of a VM failover script that I intend to try write.

                                 

                                 

                                Our scenario is 2 clusters in different physical datacentres (same VCentre and datacentre in VC though) that have NetApps replicating the vmdks etc.

                                 

                                 

                                 

                                 

                                 

                                The intention is to be able to release the i[ps on vms, shut them down and remove friom inventory on the source cluster, manually do the netapp failover, then re-add them to the inventory on the remote end.

                                 

                                 

                                • 14. Re: How to script adding .VMX's from a Datastore (NFS) to Virtual Center
                                  Daune Mattoon Novice

                                  I have an issue where 2 out of 3 of my esx hosts will not return newly mounted NFS stores to the databrowser object.  Anyone else have this problem?

                                  1 2 3 Previous Next