VMware {code} Community
probo
Enthusiast
Enthusiast

ReconfigVM throws an error

Hi Guys

I'm writing a script to shutdown a bunch of VMs, change their Memory or CPU allocation and bring them back up. But when I call the ReconfigVM method, I'm getting a strange error:

Reconfiguration failed:
Undefined subroutine &Active code page: 850
::ReconfigVM_Task called at C:\Users\probinso\Documents\dev\SetVMOffline.pl line 220

Here's my code

#!/usr/bin/perl use strict; use warnings; use VMware::VIRuntime; $SIG{INT} = sub { Util::disconnect(); exit; }; my %opts = (      name => {           type => "=s",           variable => "VM_NAME",           help => "VirtualMachine Name",           required => 1,      },      memory => {           type => "=i",           variable => "VM_MEM",           help => "The amount of Memory to be allocated to the VirtualMachine(s) in MB",           required => 0,      },      numcpu => {           type => "=i",           variable => "VM_CPU",           help => "The amount of CPUs to be allocated to the VirtualMachine(s)",           required => 0,      },      timeout => {           type => "=i",           variable => "TIMEOUT",           help => "Set this if you want to force VMs to be poweredOff after a given number of seconds",      }, ); Opts::add_options(%opts); Opts::parse(); Opts::validate(); Util::connect(); my (%poweredState, %updateState); my ($c, $mem, $cpu) = 0; my @vmList = (); my @vmnames = Opts::get_option('name'); my $memory = Opts::get_option('memory'); if($memory) {      $mem = (memoryMB => $memory); } my $numcpu = Opts::get_option('numcpu'); if($numcpu) {      $cpu = (numCPUs => $numcpu); } my $timeout = Opts::get_option('timeOut'); if(!$timeout) {      $timeout = 99999; } foreach (@vmnames) {      my $vm = Vim::find_entity_view (           view_type => 'VirtualMachine',           filter => { 'name' => qr/$_/i }      );      if(! $vm) {           # Please dial the number and try again           print "Could not find virtual machine of name $_\n Please check the spelling and CaPitAliSation\n";           exit;      }      push(@vmList, $vm);      $vm->update_view_data();      if($vm->runtime->powerState->val eq "poweredOn") {           $poweredState{$vm} = "poweredOn"; #          $vm->ShutdownGuest();           shutdown_guest($vm);      } else {           $poweredState{$vm} = "poweredOff";      }      $c++; } my $time = time(); while ($time) {      my $updatedvms = 0;      foreach my $vm (@vmList) {           $vm->update_view_data();           if($vm->runtime->powerState->val eq "poweredOff" && !$updateState{$vm}) {                my $ret = update_vm($vm);                if ($ret) {                     $updateState{$vm} = "TRUE";                } else {                     $updateState{$vm} = "FALSE";                }           } elsif(($time + $timeout) < time()) {                my $ret = poweroff_vm($vm);           }           if($updateState{$vm} eq "TRUE") {                $updatedvms++;           }      }      if(($time + ($timeout * $c)) > time() || $c == $updatedvms) {           last;      } }            foreach my $vm (@vmList) {      if($poweredState{$vm} eq "poweredOn") {           poweron_vm($vm);      }      $vm->update_view_data();      print $vm->name." was ".$poweredState{$vm}." ".$vm->name."\nWas updated? ".$updateState{$vm}."\n".$vm->name." is now ".$vm->runtime->powerState->val."\n"; } Util::disconnect(); sub shutdown_guest {       my $mor_host = $_->runtime->host;       my $hostname = Vim::get_view(mo_ref => $mor_host)->name;       eval {           $_->ShutdownGuest();           Util::trace (0,  "\nGuest '" . $_->name . "' under host $hostname shutdown ");       };       if ($@) {          if (ref($@) eq 'SoapFault') {             Util::trace (0, "\nError in '" . $_->name . "' under host $hostname: ");             if (ref($@->detail) eq 'InvalidState') {                Util::trace(0,"Current State of the "                       ." virtual machine is not supported for this operation");             }             elsif (ref($@->detail) eq 'InvalidPowerState') {                Util::trace(0, "The attempted operation".                           " cannot be performed in the current state" );             }             elsif (ref($@->detail) eq 'NotSupported') {                Util::trace(0, "The operation is not supported on the object");             }             elsif(ref($@->detail) eq 'ToolsUnavailable') {                Util::trace(0,"VMTools are not running in this VM");             }             else {                Util::trace(0, "VM '"  .$_->name. "' can't be shutdown \n"                       . $@ . "" );             }          }          else {             Util::trace(0, "VM '"  .$_->name. "' can't be shutdown \n"                       . $@ . "" );          }       return 0;       }       return 1; } sub poweroff_vm {       my $mor_host = $_->runtime->host;       my $hostname = Vim::get_view(mo_ref => $mor_host)->name;       eval {       $_->PowerOffVM();       Util::trace (0, "\nvirtual machine '" . $_->name .                        "' under host $hostname powered off ");       };           if ($@) {           if (ref($@) eq 'SoapFault') {              Util::trace (0, "\nError in '" . $_->name . "' under host $hostname: ");              if (ref($@->detail) eq 'InvalidPowerState') {                 Util::trace(0, "The attempted operation".                           " cannot be performed in the current state" );             }              elsif (ref($@->detail) eq 'InvalidState') {                 Util::trace(0,"Current State of the".                       " virtual machine is not supported for this operation");              }              elsif(ref($@->detail) eq 'NotSupported') {                 Util::trace(0,"Virtual machine is marked as template");              }              else {                Util::trace(0, "VM '"  .$_->name. "' can't be powered off \n"                       . $@ . "" );             }          }          else {             Util::trace(0, "VM '"  .$_->name. "' can't be powered off \n" . $@ . "" );          }       return 0;       }       return 1; } sub update_vm {      my $vmspec;      if($memory && $numcpu) {           $vmspec = VirtualMachineConfigSpec->new(memoryMB => $mem,                                    numCPUs => $cpu);      } elsif($memory) {           $vmspec = VirtualMachineConfigSpec->new(memoryMB => $mem);             } elsif($numcpu) {           $vmspec = VirtualMachineConfigSpec->new(numCPUs => $cpu);      } else {           Util::trace(0,"Nothing to do with these virtual machines!");           exit;      }      eval {           $_->ReconfigVM_Task(spec => $vmspec);      };      if ($@) {           Util::trace(0, "\nReconfiguration failed: ");           if (ref($@) eq 'SoapFault') {                if (ref($@->detail) eq 'TooManyDevices') {                        Util::trace(0, "\nNumber of virtual devices exceeds "                                   . "the maximum for a given controller.\n");                   }                   elsif (ref($@->detail) eq 'InvalidDeviceSpec') {                        Util::trace(0, "The Device configuration is not valid\n");                        Util::trace(0, "\nFollowing is the detailed error: \n\n$@");                   }                   elsif (ref($@->detail) eq 'FileAlreadyExists') {                        Util::trace(0, "\nOperation failed because file already exists");                   }                   else {                        Util::trace(0, "\n" . $@ . "\n");                   }             }             else {                   Util::trace(0, "\n" . $@ . "\n");             }             return 0;      }      return 1; } sub poweron_vm {       my $mor_host = $_->runtime->host;       my $hostname = Vim::get_view(mo_ref => $mor_host)->name;       eval {          $_->PowerOnVM();          Util::trace(0, "\nvirtual machine '" . $_->name .                          "' under host $hostname powered on \n");       };       if ($@) {          if (ref($@) eq 'SoapFault') {             Util::trace (0, "\nError in '" . $_->name . "' under host $hostname: ");             if (ref($@->detail) eq 'NotSupported') {                Util::trace(0,"Virtual machine is marked as a template ");             }             elsif (ref($@->detail) eq 'InvalidPowerState') {                 Util::trace(0, "The attempted operation".                           " cannot be performed in the current state" );             }             elsif (ref($@->detail) eq 'InvalidState') {                Util::trace(0,"Current State of the "                       ." virtual machine is not supported for this operation");             }             else {                Util::trace(0, "VM '"  .$_->name.                   "' can't be powered on \n" . $@ . "" );             }          }          else {             Util::trace(0, "VM '"  .$_->name.                            "' can't be powered on \n" . $@ . "" );          }       return 0;       }       return 1; }

Tags (1)
Reply
0 Kudos
1 Reply
probo
Enthusiast
Enthusiast

Fixed it.

Turns out it was because I was passing the virtualMachine object ($vm) as a scalar to the subroutine, this was causing things to break.

If I make $vm a global variable and reference it directly from the subroutine, it works fine.

Reply
0 Kudos