1 2 3 4 Previous Next 56 Replies Latest reply on Aug 12, 2011 4:45 AM by julianwood

    HowTo search for all VMX files in all datastores and register them into VC?

    angoletti1 Enthusiast

       

      Hi,

       

       

      I want to search in all datastores for VMX files and if the VM for each founded file is not registered in VC, register it.

       

       

      How can this be done by the powershell using the easiest way?

       

       

       

       

       

      Thanks in advance

       

       

      Chris

       

       

        • 1. Re: HowTo search for all VMX files in all datastores and register them into VC?
          LucD Guru
          User ModeratorsCommunity WarriorsvExpert

          I'm not sure this is the easiest way but at least it works for me.

           

          Some notes:

          1) the script uses 2 methods from the SDK

              a) SearchDatastoreSubFolders_Task: to find all .vmx files in a specific datastore

              b) RegisterVM_Task: to register a guest from it's .vmx file

          2) Contrary to a sample in the FAQ the RegisterVM_Task method seems to require a resourcepool

          3) The guests will be registered in a specific datacenter and cluster in that datacenter

          4) The folder where the guests will be registered is the hidden folder "vm"

          5) the pool where the guests will be registered is the hidden resourcepool "Resources"

          6) the RegisterVM_Task method will fail if there is already a registered guest with the same name

          7) the name of the guest that will be registered is the filename of the .vmx file. For example for PC1.vmx it will be guest PC1

           

          $folder = Get-View (Get-Datacenter -Name <datacenter-name> | Get-Folder -Name "vm").ID
          $pool = Get-View (Get-Cluster -Name <cluster-name> | Get-ResourcePool -Name "Resources").ID
          $guestname = [regex]"^([\w]+).vmx"
          
          $esxImpl = Get-VMHost -Name <VMHost-name> 
          $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 = "[http://" + $ds.Summary.Name + "|http://" + $ds.Summary.Name + "]"
            
            $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){
                $vmx = $file.FolderPath + $file.File[0].Path
                $res = $file.File[0].Path -match $guestname
                $folder.RegisterVM_Task($vmx,$matches[1],$FALSE,$pool.MoRef,$null)     
              }
            }
          }
          

           

          • 2. Re: HowTo search for all VMX files in all datastores and register them into VC?
            bassarchist Novice

            Thanks for the pointer LucD! But I seem to be having some difficulties ...

             

            First of all, how can I specify the DataStore to parse for VMX's? In my case, I've got an iSCSI LUN -- the script seems to only pull local storage devices.

             

            Second, it doesn't appear that $file.File[0] ever gets populated in the bottom half of your suggestion.

             

            I get this error every time this array is referenced:

             

            Cannot index into a null array.

            (line numbers differ -- i was playing with some debug output)

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

             

            I've got some things to try to fix these issues, but if you can replicate my error and have ideas, I'd be most grateful!

             

            Thanks again!

             

            -Mars

             

             

             

            (edit)

            Oh yeah, I forgot to mention -- I 'sploded out your script into my own formatting, so the line numbers would be goofy in the first place. When I copy'n'paste your solution, I get this error (which I solved by using my own formatting):

             

            Parsing error:

            At line 1, position 345

            Unexpected token 'in' in expression or statement.

             

             

            It's referring to this:

             

            foreach($dsImpl in $dsBrowser.Datastore){ (.....)

             

            Apparently, it doesn't like the 'in' used in that foreach ... not sure what that was all about.

            • 3. Re: HowTo search for all VMX files in all datastores and register them into VC?
              bassarchist Novice

              DUH! I just had an epiphany.

               

              It's not that your script pulls the 'wrong' storage device, it's that it specifically references a VMHost -- which you can't do when you want to parse VMX's located on an iSCSI Lun! It hadn't even occurred to me until i noticed the VMHosts and the Networked storage was listed in parallel in the datastore browser in VIC :P

               

              We don't have any VMX's on our VMHost:storage1, which might explain why that array never gets populated. I think I was concentrating on the wrong part of the script ...

               

              Ok SO ....

               

              I'll try to mess around with that Get-iSCSILun function i saw you post somewhere else. Any pointers? :P

              • 4. Re: HowTo search for all VMX files in all datastores and register them into VC?
                LucD Guru
                Community WarriorsvExpertUser Moderators

                There were 2 problems in the script.

                 

                1) the forum SW doesn't like square brackets.

                To avoid the reformatting I have attached the script.

                 

                2) the script had a bug when an empty datastore was encountered.

                That problem should be fixed now by the updated if-statement in line 33.

                 

                Concerning your remark about the iSCSI LUNs, that should be of no importance to the script.

                The script scans the datastores, irrespective if they are on SAN, iSCSI, NFS or local disks.

                • 5. Re: HowTo search for all VMX files in all datastores and register them into VC?
                  bassarchist Novice

                  Brilliant!

                   

                  I see that it's correctly locating our network storage device, and I see the correct number of tasks sent to VIC, but now I'm getting this error:

                   

                  In VIC, the status of each of the tasks reports "   " is invalid or too long."  (yeah, the status begins with a double-quote)

                   

                  In the script editor under locals, i've located this:

                   

                  $file.DynamicType -- Cannot process argument because the value of "obj" is null. Change the value of argument "obj" to a non-null value."

                  $file.DynamicProperty -- Cannot process argument because the value of "obj" is null. Change the value of argument "obj" to a non-null value."

                  $file.File[0].DynamicType -- Cannot process argument because the value of "obj" is null. Change the value of argument "obj" to a non-null value."

                  $file.File[0].DynamicProperty -- Cannot process argument because the value of "obj" is null. Change the value of argument "obj" to a non-null value."

                   

                  These values don't appear directly accessible via the script, are these values returned by the SDK functions you mentioned? Or, rather, null returns of an SDK function? :P

                   

                  Setting any of those to "1" didn't seem to help either, except in doing so, I only received the error on $file.DynamicType and $file.DynamicProperty. Does that make sense?

                  I figured it was worth a shot :P

                   

                   

                  So to reiterate -- the script locates all the vmx's properly, sends the task to VIC, but it looks like there is a bit of data missing ...

                   

                   

                   

                   

                   

                   

                  (edit)

                   

                  Oh wait .. I've received that error on more than just those four keys ... on second glance, it looks like those errors are to be expected because some of those values are useless. For example, for the variable $searchspec, everything except $searchspec.matchpattern gets the same error mentioned above. It's obvious in the script that .matchpattern is the only one we are explicitly defining ... so any other ideas on why VIC doesn't like the task?

                   

                   

                   

                   

                   

                   

                  (edit again twice here sorry)

                   

                  Ok I've officially really confused myself. My head hurts.

                   

                  I noticed that the value of $vmx at the end of the script had the path up to the vmx, but did not include the filename! After some playing with it, VIC did in fact add one VM, with the name "cp_vms", which just happens to be the name of the resource pool they are supposed to be part of. Obviously, when it tried to add all the other vms, it errored with "The name 'cp_vms' already exists.

                   

                  So I started over fresh with your script again to see what I could do.

                   

                  So the first thing that confused me was that two variables were defined with different names. It looks like PowerTools will cover the user in this case, and just define the values for each variation of the same variable name. In this case, $searchspec, $searchSpec, $datastorepath, and $datastorePath were all defined, all with the same values according to the 'locals' section. I tried cleaning that up ... but it didn't seem to help.

                   

                  Also, what is $res for? I see it defined, but it's not utilized anywhere. Is it used by $folder.RegisterVM_Task() by chance? Am I trying too hard?!? :P

                   

                  And one last thing .. the values I changed to fit our environment were: VIserver, the vmhost, the name of the datacenter, the name of the cluster, and the name of the resource pool. I did not change the name of the folder, because I wasn't really sure how this part was relevant. I tried running a few variations from the command like of what I thought that value 'should' be, but failed miserably :\

                   

                  Does that value need to be changed as well?

                   

                  Thanks again for any assistance ... sorry to be such a newb, I'm trying! :P

                  • 6. Re: HowTo search for all VMX files in all datastores and register them into VC?
                    LucD Guru
                    Community WarriorsvExpertUser Moderators

                    I'll start from your last edit.

                     

                    1) $vmx is indeed the pathname to the VMX file.

                    That is the first parameter to the RegisterVM_Task method.

                    There is no need to specify the VMX filename with the RegisterVM_Task. It will look for it in the folder.

                     

                    2) In PowerShell variable names are case-insensitive.

                    Although I admit it's not good coding practice to use that "feature". You got me there

                     

                    3) The variables $res is indeed not used because I don't really want it but it is to avoid that the result of that line is displayed on screen.

                    The key is the "-match" operator in the same line.

                    This will use a regular expression (in $guestname) on the variable $file.File[0].

                    The "-match" operator stores the matching results automatically in the array $matches.

                     

                    I use that regex construct to get the VM name from the VMX filename.

                    That is the 2nd parameter to the RegisterVM_Task method.

                     

                    4) The values you need to change for your environment are now all indicated with triangular brackets.

                    I have updated the script in my previous post.

                    You do not need to change the folder ("vm") and the resource pool ("Resources").

                    These are predefined objects present in every VC (but not visisble in the VI CLient).

                     

                    I hope this will get you further.

                    • 7. Re: HowTo search for all VMX files in all datastores and register them into VC?
                      bassarchist Novice

                       

                      LucD -- You are invaluable to this community

                       

                       

                       

                       

                       

                      So I had another Aha! moment. A couple, actually.

                       

                       

                      I realized that your regexp looks for a word and an extension, from the beginning of the pathname. That was my first problem -- we've got a vm that we clone from called "Base Install.vmx".  "Install.vmx" was all that matched this expression.

                       

                       

                      Then I realized that because of the way we are trying to populate this environment (explanation below), I had sixty folders, each with their own pathnames, but all of the files were also called "Base Install.vmx". Thats why I got that error sixty some times -- it was trying to add all my different VMs with the same name, which is not what it should have been!

                       

                       

                      I ran into this issue because I'm a novice VMWare user taking on tasks that are bigger than my understanding. But thanks to you, I think I know enough to do it "the right way".

                       

                       

                       

                       

                       

                      The story:

                       

                       

                      We used to "clone to new vm" from an existing vm we called "Base Install". That worked, because every time we cloned, VIC changed configurations, generated new mac addresses, changed filenames, etc. But now we've built up sixty-some VMs, and need to get all of them over to a new environment, with minimal downtime. I realized that I couldn't script "new vm from clone", only "new vm from template". But I tried to make our old procedure work (partially because I was instructed to), by writing a bash script to copy from Base Install a bunch of times, changing the pathname as it went. Then I'd have had to write another script to rename all the VMX files and change all the configuration settings. Then I'd use the script you provided here to add everything from inventory. But thats kind of a janky work around, when I could instead just create a template, and script adding new VMs from template, which would automatically register them under whichever ESX server I scripted. 

                       

                       

                      The crux:

                       

                       

                      I'm not entirely confident I can make a script like that work, due to my inexperience. However, I'm gonna try

                       

                       

                      So thats basically what happend. Now I need a script that will clone from a template multiple times, changing the pathname and filename each successive iteration. As I understand, this will automatically register the newly created VM, right? It sounds simple enough, especially with the "new-vm" switches. I'll give it a shot on my own, but any input/examples/solutions are certainly welcome!

                       

                       

                      Thanks again to all the help here, I'm learning more than I knew I didn't know, which is awesome

                       

                       

                       

                       

                       

                      Also, if there is a simpler way of doing what I'm trying to do, I'd definitely like to know! Thanks again!

                       

                       

                      • 8. Re: HowTo search for all VMX files in all datastores and register them into VC?
                        LucD Guru
                        vExpertUser ModeratorsCommunity Warriors

                        You could give my GPS application a try (see  Guest Provisioning System (cloning from templates)).

                        It does in fact what you want (and a bit more).

                        Since the configuration data is stored in an XML file it shouldn't be too hard to create the file for cloning sixty VMs from within a file editor.

                         

                        I shall be publishing a newer version of the application shortly.

                        • 9. Re: HowTo search for all VMX files in all datastores and register them into VC?
                          bassarchist Novice

                          Most excellent! Thats a tool we can certainly put to good use!

                           

                          Naturally, I'm having some issues getting it to work. Here's what I've done so far:

                           

                           

                           

                           

                           

                          • Sysprep files (sysprep.exe and setupcl.exe) exist in c:\sysprep

                          • Our BaseInstall image has been converted to a Template

                          • GPS is able to locate and communicate with all the moving parts (datacenters, datastores, folders, etc are all found, commands are successfully submitted to VIC)

                          • XML files are created, saved, and loaded properly

                          • Tried configuring and not configuring OS options, just in case GPS was having issues communicating with Sysprep ...

                           

                          Using VIC/VC 2.5.0, ESX 3.5.0 (the documentation refers to 3.5 U2, however), PowerShell 1.0, not sure which build

                           

                           

                          However, when I submit the job, VIC logs "The operation is not supported on the object". Furthermore, PowerShell prints some errors to standard out:

                           

                           

                           

                          Get-Template: Template with the name 'Virtual1-1' not found, using the specified filter(s).

                           

                           

                           

                          Subsequently, a bunch of other stuff breaks too. 

                           

                           

                           

                          At this point, I guess I don't fully understand how GPS is supposed to work -- the Virtual1-1 was a guest I added, that I wanted to be created from the template selected in the interface. Is this not how the tool is used?

                          • 10. Re: HowTo search for all VMX files in all datastores and register them into VC?
                            LucD Guru
                            vExpertCommunity WarriorsUser Moderators

                            1) The sysprep files should not be stored in C:\sysprep

                            See the Basic System Administration guide, appendix B "Installing the Microsoft Sysprep Tools".

                             

                            2) GPS v2 should work with with ESX 3.5 and VC 2.5 as well.

                            I only tested the published version with U2

                             

                            3) Is " Virtual1-1" a template in your VC ?

                            From the message it looks as if it is not a template.

                             

                            The tool creates a new guest (name defined in the field Computername under OS Options).

                            The template from which the new guest is deployed is selected in the drop-down list Template under Guest Options.

                             

                            Is "Virtual1-1" in the list when you do a Get-Template from the VITK prompt ?

                            • 11. Re: HowTo search for all VMX files in all datastores and register them into VC?
                              bassarchist Novice

                               

                              1) I see! I was using Microsoft's documentation for a single client. Oops. Ok, all the files are where they need to be on the VC Server, and I've confirmed by deploying a template with OS customizations successfully.

                               

                               

                              2) I hear there was quite the snafu with U2 :P  Is that all cleared up now?

                               

                               

                              3) No, Virtual1-1 is not a template on my machine, that was supposed to be the target VM's name, which is why i'm confused. The template is called "BaseInstall", and does display correctly, after the tools successfullylocates all the other information (datastore, resource pool, vmhost, etc). It appears that when the task is submitted, GPS gets confused and wants to use the target name as the template. At least, thats what my untrained eye catches. Grr. What can I do to debug?

                               

                               

                              • 12. Re: HowTo search for all VMX files in all datastores and register them into VC?
                                benbjamin24 Novice

                                 

                                hey everyone,

                                 

                                 

                                I was having a problem with the -match expression in this script, it was giving me the following error.

                                 

                                 

                                Cannot index into a null array.

                                At line 36, position 51

                                      $folder.RegisterVM_Task($vmx,$matches[1],$FALSE,$pool.MoRef,$null)   

                                 

                                 

                                but i found a workaround in the meantime that seems to work fine for the moment. 

                                 

                                 

                                just changed the line

                                 

                                 

                                $res  = $file.File[0].Path -match $guestname

                                 

                                 

                                to

                                 

                                 

                                      $res = $file.File[0].Path

                                      $res = $res.TrimEnd(".vmx")

                                 

                                 

                                and that seemed to solve my problem. 

                                thanks for the script.

                                 

                                 

                                Ben

                                 

                                 

                                • 13. Re: HowTo search for all VMX files in all datastores and register them into VC?
                                  artist-06 Novice

                                   

                                  Hi all,

                                   

                                   

                                  I wanted to share my experience with register vm script and powercli. I have been playing with powercli all week. The register-vm automation task pulled me to this area. I have given a VC with loads of orphaned VMs. Resolution was to remove from inventory and readd to inventory which was a painful repetitive task.

                                   

                                   

                                  I installed VI Toolkit, powercli etc and then I was amazed what things could be done with Powercli. I could not get this register script work to start with. I finally edited these lines at the beginning to my VCs values below;

                                   

                                   

                                  Connect-VIServer -Server localhost

                                  $folder = Get-View (Get-Datacenter -Name Cristie | Get-Folder -Name "vm").ID

                                  $pool = Get-View (Get-Cluster -Name Cristie | Get-ResourcePool -Name "Resources").ID

                                  $guestname = "^(+).vmx"

                                  $esxImpl = Get-VMHost -Name 10.5.5.80

                                   

                                   

                                  localhost: Script running in VC

                                   

                                   

                                  Datacenter name "Cristie", Cluster Name is "Cristie", Host Name is "10.5.5.80"

                                   

                                   

                                  To resolve the main problem (orphaned VMs), I wrote a tiny script to remove all the VMs which were PoweredOff. Note you cannot PowerOn Oprhaned VMs.

                                   

                                   

                                  remove-vm script is here;

                                   

                                   

                                  Connect-VIServer -Server localhost

                                  get-vm -name *| where{$_.PowerState -eq "PoweredOff"}

                                  foreach($i in $vms)

                                  {

                                  Write-Host "Removing VM";

                                  remove-vm -vm $i -Confirm:$false

                                  Write-Host "$i vm is removed";

                                  }

                                   

                                   

                                  I watched all my Powered Off VMs disappearing in Vsphere Client and then ran the Register-VM script which registered allremoved VMs back again.

                                   

                                   

                                  Thanks for the community.

                                   

                                   

                                  I hope someone else finds this helpful and not waste so much time like I did.

                                   

                                   

                                  Burak Uysal

                                   

                                   

                                   

                                   

                                   

                                   

                                   

                                   

                                  • 14. Re: HowTo search for all VMX files in all datastores and register them into VC?
                                    frdgn Lurker

                                    Hi Luc,

                                     

                                    I find your script to be an invaluable example.I run into a problem reregistering VM's from a different datastore than the original one though.

                                    Here is the situation: We ran into serious trouble with our SAN storage System recently and decided to run remote copy jobs to a different Storage group to be able to restart machines from there.

                                     

                                    I've written a script to shut down the machines in question, remove them from inventory, activate the Lun's on the remote storage and rescan the hba's on my esx servers with resignaturing in place.

                                    Result is with slight modifications to your script I'am able to search the new Lun's for my VM's. So far so good, but when I'm trying to register these copies registration fails because there is still a record of the sanfs uuid in the vmx file.

                                     

                                    I know i can register these machines from an esx server using the local filepath through vmware-cmd -s register, I just wonder if there is a way to do this through PowerCli as well.

                                     

                                    Greetings Frank

                                    1 2 3 4 Previous Next