VMware Cloud Community
hansis
Contributor
Contributor

Get all VMs with "vmware-vim-cmd vmsvc/getallvms"

hello!

I have following problem.

I have a shell-script and want to get all IDs and Names of virtual machines: for i in `vmware-vim-cmd vmsvc/getallvms | sed '1d' | awk '{print $1":"$2}'`

all is fine, but in my list i get the notes  of the machine I have written in Vcenter.

For example:

1000   TESTSERVER1    [Storagename]      TESTSERVER1/TESTSERVER1.vmx                        winNetStandardGuest       vmx-07    TESTSERVER this is our testsystem

- built on 2012-01-01

- for testing office

In my "for" I get "this is our testsystem" "- built on 2012-01-01" "- for testing office" as an VirtualMachine.

When I want to ask for the powerstate I get an error, because no correct Id is given.

How can get all VMs without listing the Annotation to the machine?

I hope you understand my problem Smiley Happy

thx.

hansi

0 Kudos
6 Replies
Sreejesh_D
Virtuoso
Virtuoso

Try this out

vim-cmd vmsvc/getallvms | sed '1d' | awk '{if ($1 > 0) print $1":"$2}'

0 Kudos
hansis
Contributor
Contributor

hello

many thanks but same result.

I have another solution:

ID=$(echo $i | awk -F: '{print $1}')

RESULT=$(echo $ID |egrep ^[[:digit:]]+$)
if [ "$RESULT" != "" ]; then

...

and this works

0 Kudos
Sreejesh_D
Virtuoso
Virtuoso

thats good and thanks for sharing the script.

One liner works fine for me.

~ # vmware -lv
VMware ESXi 5.0.0 build-469512
VMware ESXi 5.0.0 GA
~ # vim-cmd vmsvc/getallvms
Vmid       Name                           File                             Guest OS          Version                             Annotation
1      win-7           [vmfs5-vol] win-7/win-7.vmx                   windows7_64Guest        vmx-08    this is our testsystem
-built on 2012-01-01
-for testing office
2      2k8R2-64b-VC    [vmfs5-vol] 2k8R2-64b-VC/2k8R2-64b-VC.vmx     windows7Server64Guest   vmx-08    - test machine 3
- test 3
3      win7-vdi   [vmfs5-vol] win7-vdi/win7-vdi.vmx   windows7_64Guest        vmx-08
4      2k8R2-64b-DC    [vmfs5-vol] 2k8R2-64b-DC/2k8R2-64b-DC.vmx     windows7Server64Guest   vmx-08    - machine 2
- test 2
5      2k8R2-64b-CB    [vmfs5-vol] 2k8R2-64b-CB/2k8R2-64b-CB.vmx     windows7Server64Guest   vmx-08
6      ESXi 5.0        [vmfs5-vol] ESXi 5.0/ESXi 5.0.vmx             vmkernel5Guest          vmx-08
7      ubuntu          [vmfs5-vol] ubuntu/ubuntu.vmx                 ubuntu64Guest           vmx-08    -test machine
- machine 2
~ # vim-cmd vmsvc/getallvms | sed '1d' | awk '{if ($1 > 0) print $1":"$2}'
1:win-7
2:2k8R2-64b-VC
3:win7-vdi
4:2k8R2-64b-DC
5:2k8R2-64b-CB
6:ESXi
7:ubuntu
0 Kudos
RebeccaG
Expert
Expert

Hi, this answer actually is incorrect. It does not handle VM names which include spaces, and the conditional 'if ($1 > 0)' is not adequate to screen out all nondigit characters. In the above post you can see VM #6 is "ESXi 5.0", yet the name returned by the script is simply "ESXi".

Here's a better solution:

vim-cmd vmsvc/getallvms | sed -e '1d' -e 's/ \[.*$//' | awk '$1 ~ /^[0-9]+$/ {print $1":"substr($0,8,80)}'

As explanation:

-e 's/ \[.*$//' truncates the string starting with the LUN name ("[vmfs5-vol]")
$1 ~ /^[0-9]+$/ requires the Vmid column to contain only digits.
{print $1":"substr($0,8,80)} if the above condition is met, we print the Vmid, colon, then the VM name which starts at position 8. VM name can be maximum 80 characters long.

The only failure condition for this script will be if the VM name contains the substring " [", in which case the remainer of VM name will be truncated starting at the substring.

Output from "vim-cmd vmsvc/getallvms" is really challenging to process. Our normal approches such as awk column indexes, character index, and regular expression are all error prone here. The character index of each column varies depending on maximum field length of, for example, VM name. And the presence of spaces in VM names throws off processing as awk columns. And VM name could contain almost any character, foiling regex's.

mheyman
Contributor
Contributor

Okay, you can do it for VMs that have a name with "[" in it. But, it is ugly. The following command gives you vmid, vmname, and vmpath.

vim-cmd vmsvc/getallvms | awk '{ if ($1 == "Vmid") { fcol=((index($0, "Name") - 1)*2) + 1; flen=index($0, "Guest OS") - fcol } else { if (substr($0, fcol + 1,

1) == "[") fcol = fcol + 1; beg=substr($0, 1, fcol - 1); vmid=beg; sub(/[^0-9].*/, "", vmid); name=beg; sub(/[0-9]+\s+/,"",name); sub(/\s*$/, "", name); path=sub

str($0, fcol, flen); sub(/\s+\w*$/, "", path); if (vmid != "") print vmid "\" name "\" path } }

In the awk script:

  1. Look in the header for the "Name" text
  2. Use the magic formula [ file column = 2("Name" column - 1) + 1 ] (found through educated guessing about how I would write the header)
  3. Get a representative length of the file path by using the index of the "Guest OS" header (this length runs into the middle of the Guest OS but that gets stripped out later.
  4. If it isn't the header, first check to see if the magic formula is off by one and if it is, fix it
  5. Using the file column value, fcol, get the beginning of the getallvms line that contains the vmid and the vm name
  6. Parse that beginning part into the vmid and the name.
  7. Parse the path out of substr($0, fcol,flen) by stripping off the remaining piece of the guest OS and the trailing whitespace.

Note that the VM name is not necessarily unique - the same name can be reused in a different resource pool.

I used backslashes to separate the fields because they get translated into %5C in the VM name.

0 Kudos
m_gogebakan
Contributor
Contributor

Hi

Here's best solution:

vim-cmd vmsvc/getallvms | awk '$3 ~ /^\[/ {print $1":"$2}'

Sample:

[root@localhost:/tmp] vim-cmd vmsvc/getallvms

Vmid    Name                   File                   Guest OS      Version       Annotation

1      TestVm1   [datastore1] TestVm1/TestVm1.vmx   rhel7_64Guest   vmx-11    test1

test2

3 test

[root@localhost:/tmp] vim-cmd vmsvc/getallvms | sed '1d' | awk '{if ($1 > 0) print $1":"$2}'

1:TestVm1

test2:

3:test

[root@localhost:/tmp] vim-cmd vmsvc/getallvms | sed -e '1d' -e 's/ \[.*$//' | awk '$1 ~ /^[0-9]+$/ {print $1":"substr($0,8,80)}'

1:TestVm1

3:

[root@localhost:/tmp] vim-cmd vmsvc/getallvms | awk '$3 ~ /^\[/ {print $1":"$2}'

1:TestVm1

0 Kudos