Search code examples
bashawksedesxi

Parse ESXI vim-cmd hostsvc/autostartmanager/get_autostartseq to get each VM stopDelay param


I have shutdown script for each ESXI when the UPS is on battery. I need to make this script better to read "stopDelay" which can be set in ESXI host UI. This value can be found in console with command vim-cmd. I need script which will return "stopDelay" for desired VM ID as input param.

e.g.:

[root@localhost:~] vim-cmd hostsvc/autostartmanager/get_autostartseq

(vim.host.AutoStartManager.AutoPowerInfo) [
   (vim.host.AutoStartManager.AutoPowerInfo) {
      key = 'vim.VirtualMachine:1',
      startOrder = 1,
      startDelay = 10,
      waitForHeartbeat = "systemDefault",
      startAction = "powerOn",
      stopDelay = 13,
      stopAction = "systemDefault"
   },
   (vim.host.AutoStartManager.AutoPowerInfo) {
      key = 'vim.VirtualMachine:2',
      startOrder = 2,
      startDelay = -1,
      waitForHeartbeat = "systemDefault",
      startAction = "powerOn",
      stopDelay = 5,
      stopAction = "systemDefault"
   },
   (vim.host.AutoStartManager.AutoPowerInfo) {
      key = 'vim.VirtualMachine:3',
      startOrder = 3,
      startDelay = -1,
      waitForHeartbeat = "systemDefault",
      startAction = "powerOn",
      stopDelay = -1,
      stopAction = "systemDefault"
   }
]

How to parse this output to get VM ID and its stopDelay value? e.q.:

./getVMStopDelay 1 => 13
./getVMStopDelay 2 => 5
./getVMStopDelay 3 => -1

Solution

  • I would harness GNU AWK for this task following way, let file.txt content be

    (vim.host.AutoStartManager.AutoPowerInfo) [
       (vim.host.AutoStartManager.AutoPowerInfo) {
          key = 'vim.VirtualMachine:1',
          startOrder = 1,
          startDelay = 10,
          waitForHeartbeat = "systemDefault",
          startAction = "powerOn",
          stopDelay = 13,
          stopAction = "systemDefault"
       },
       (vim.host.AutoStartManager.AutoPowerInfo) {
          key = 'vim.VirtualMachine:2',
          startOrder = 2,
          startDelay = -1,
          waitForHeartbeat = "systemDefault",
          startAction = "powerOn",
          stopDelay = 5,
          stopAction = "systemDefault"
       },
       (vim.host.AutoStartManager.AutoPowerInfo) {
          key = 'vim.VirtualMachine:3',
          startOrder = 3,
          startDelay = -1,
          waitForHeartbeat = "systemDefault",
          startAction = "powerOn",
          stopDelay = -1,
          stopAction = "systemDefault"
       }
    ]
    

    then

    awk 'index($0,"(vim.host.AutoStartManager.AutoPowerInfo)")>1{cnt+=1}/stopDelay/{sub(/,/,"");print "./getVMStopDelay",cnt,"=>",$NF}' file.txt
    

    gives output

    ./getVMStopDelay 1 => 13
    ./getVMStopDelay 2 => 5
    ./getVMStopDelay 3 => -1
    

    Explanation: I use index function to detect line where (vim.host.AutoStartManager.AutoPowerInfo) is indented, i.e. start is after 1st character, if it is so I do increase cnt value by 1. When I find line with stopDelay I replace , using empty string i.e. delete it and print in format compliant with your requirements using value of cnt and content of last field ($NF).

    (tested in GNU Awk 5.1.0)