The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,839 other subscribers

Archive for the ‘Scripting’ Category

Hopefully datendomina (@sys_adm_ama) has followed up with some cool vi tips…

Posted by jpluimers on 2021/06/28

I hope that datendomina (@sys_adm_ama) has followed up with some cool vi/vim tips.

Though I can do basic editing (far more than quit-without-saving) and know about he various mode, I still feel not proficient.

[WayBack] Jeroen Pluimers on Twitter: “LOL! Boy was I glad that after finding my way in Ed and sed on SunOS in the 1980s, I discovered vi. Still not proficient in it (and I probably never will). However, knowing some of the basics allowed me to visually edit any file on any Unix like system. That’s still gold to me.…”

It also made me discover [WayBack] ed(1) Conference (@ed1conf) | Twitter.

One important tip:

[WayBack] Kristian Köhntopp on Twitter: “vi movement Kommandos haben System. Erkenne und lerne das System. hjkl + prefix+hjkl, Marken, prefix+jump to mark und so weiter. Und bleibe von den verblödeten Plugins weg. Die braucht kein Mensch und machen vim nur langsam im Start und kompliziert.”

The original thread, which I hoped would get longer: [WayBack] Thread by @sys_adm_ama: “Ich lerne jetzt vi(m). Klingt beknackt, oder?se […]”

Ich lerne jetzt vi(m).

Klingt beknackt, oder? Aber ich hab überlegt: ich möchte effizienter werden, meinen Kram stressfreier bewältigen. Und ich finde, es bietet sich an da an Baustellen anzusetzen, die täglich relevant sind. Und vi(m) nutze ich in der Tat täglich.

1/

Aber auch wenn ich ihn nutze und über den »Hilfe, wie komm ich aus dem Editor wieder raus?!«-Witz nur sehr müde die Augen rolle gehe ich davon aus, dass ich nicht mal einen Bruchteil der Möglichkeiten ausschöpfe, die er bietet (1. Release 1976, älter als ich!). Das ist spannend.
Das ist jetzt meine Mini-Challenge, auf die ich jeden Tag eine Viertelstunde verwenden will: wenn ich eine Funktion brauche mich nicht mehr drum herum zu hacken, sondern recherchieren wie es richtig geht und das dann gefälligst auch verinnerlichen. Mal sehen, ob das so klappt

3/

In dem Zuge will ich auch wieder verstärkt (neo)mutt in Verbindung mit vim nutzen – das wäre ein wunderbares tägliches Training 😎 Mails schreiben muss man irgendwie immer.

neomutt bietet leider auch einen Eimer voll Funktionen, die ich noch nicht ordentlich nutze. Gnah.

4/

An euren Replies erkenne ich, dass das mit dem »sich die Kürzel merken« echt heikel zu sein scheint 🤔 Wie handhabt ihr das im Alltag? Einfach ein paar Basics wie :u und CTRL+r und gut ist? Ich bin neugierig. Oder nutzt ihr alle nano? (Ich glaub, dann muss ich entfolgen) 😂
Nur als kleinen Zwischenstand: nach dem Lesen eurer Antworten schließe ich, dass ich mich mit meinem Kenntnisstand nicht verstecken muss 😂 Da hat mir der virtuelle Schulterblick schon weiter geholfen.

/5
vi(m), weil ich Admin bin und dieses Tool auf jedem System und ohne X-Geraffels üblicherweise vorfinde (wenn auch bei neueren Installationen dieser absurde „visual mode“ der Default ist 😳). Auch unter (Open)Solaris, IRIX, was weiß ich.

/6

Eben hab ich das Buch von @MasteringVim aus der Packstation gezogen (extrem vielversprechend!) – und klar, ich werde berichten 😎 Ich bin sehr gespannt.

/7ed

–jeroen

Read the rest of this entry »

Posted in *nix, *nix-tools, Development, ed, Power User, Scripting, sed, sed script, Software Development, vi/vim | Leave a Comment »

File Line Count: “built-in” line count for Windows

Posted by jpluimers on 2021/06/22

Windows if full of undocumented gizmo’s, like find alternative for wc -l counting all lines in a file: [WayBack] File Line Count

Use FIND command to count file lines, store line count into a variable.

Description: Running the FIND command with option /v and empty search string will find all lines
Running the FIND command with option /c will output the line count only.
The FOR command with option /f will parse the output, the line count in this case, and the set command put the line number into the cnt variable.
Script:
1.
2.
3.
4.
set file=textfile.txt
set /a cnt=0
for /f %%a in ('type "%file%"^|find "" /v /c') do set /a cnt=%%a
echo %file% has %cnt% lines
Script Output:
 DOS Script Output
textfile.txt has 50 lines

[WayBack] Stupid command-line trick: Counting the number of lines in stdin | The Old New Thing

Windows doesn’t come with wc,
but there’s a sneaky way to count the number of lines anyway:

some-command-that-generates-output | find /c /v ""

It is a special quirk of the find command
that the null string is treated as never matching.
The /v flag reverses the sense of the test,
so now it matches everything.
And the /c flag returns the count.

The reason dates back to the original MS-DOS
version of find.exe,
which according to the comments appears to have been written
in 1982.
And back then, pretty much all of MS-DOS was written in assembly
language.

Via: batch file line count – Google Search and [WayBack] windows – How to count no of lines in text file and store the value into a variable using batch script? – Stack Overflow

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development, Windows Development | Leave a Comment »

GitHub – jjjake/internetarchive: A Python and Command-Line Interface to Archive.org

Posted by jpluimers on 2021/06/16

On my list of things to play with: [WayBack] GitHub – jjjake/internetarchive: A Python and Command-Line Interface to Archive.org.

Via:

Related:

  • [WayBack] The Internet Archive Python Library — Internet Archive item APIs 1.8.5 documentation
  • [WayBack] Command-Line Interface — Internet Archive item APIs 1.8.5 documentation
  • [WayBack] Quickstart — Internet Archive item APIs 1.8.5 documentation, including:

    Configuring

    Certain functionality of the internetarchive Python library requires your archive.org credentials. Your IA-S3 keys are required for uploading, searching, and modifying metadata, and your archive.org logged-in cookies are required for downloading access-restricted content and viewing your task history. To automatically create a config file with your archive.org credentials, you can use the ia command-line tool:

    $ ia configure
    Enter your archive.org credentials below to configure 'ia'.
    
    Email address: user@example.com
    Password:
    
    Config saved to: /home/user/.config/ia.ini
    

    Your config file will be saved to $HOME/.config/ia.ini, or $HOME/.ia if you do not have a .configdirectory in $HOME. Alternatively, you can specify your own path to save the config to via ia --config-file '~/.ia-custom-config' configure.

    If you have a netc file with your archive.org credentials in it, you can simply run ia configure --netrc. Note that Python’s netrc library does not currently support passphrases, or passwords with spaces in them, and therefore not currently suported here.

–jeroen

Read the rest of this entry »

Posted in Development, Internet, InternetArchive, Power User, Python, Scripting, Software Development, WayBack machine | Leave a Comment »

string – Change backslash to forward slash in windows batch file – Stack Overflow

Posted by jpluimers on 2021/06/10

One of the situations where setlocal enabledelayedexpansion comes on handy to replace \ with / which some unix based tools like better: [WayBack] string – Change backslash to forward slash in windows batch file – Stack Overflow

echo off

setlocal enabledelayedexpansion

for %%f IN ("C:\tools\workspace\*") DO (
  set old=%%f
  echo !old!
  set new=!old:\=/!
  echo !new!  
  echo.                 
)

Related, as it explains when the source and target replacements are in variables themselves: [WayBack] command line – String replacement in batch file – Stack Overflow, thanks Joey and Tom Warfield!

You can use the following little trick:

set word=table
set str="jump over the chair"
call set str=%%str:chair=%word%%%
echo %str%

The call there causes another layer of variable expansion, making it necessary to quote the original % signs but it all works out in the end.

Upvoting this answer because it works both ways, with the environment variable in either position, or in both the “before” and “after” positions:

set word=table
set str="jump over the chair"
call set str=%%str:chair=%word%%%
echo %str%
set word1=chair
set word2=desk
set str="jump over the chair"
call set str=%%str:%word1%=%word2%%%
echo %str%'

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »

Some VMS and DCL history links

Posted by jpluimers on 2021/05/25

Last week, I wrote about a bit of my command-line and scripting history at I wanted to know the loaded DLLs in a process like Process Explorer shows, but from the console: Sysinternals ListDLLs to the rescue.

Since information about VMS and DCL is harder to find nowadays, I saved some information in the wayback machine:

By now, there should be a good x86_64 version of OpenVMS, so this is also a reminder to self to see if that can run as a VM and is affordable enough to do some experimentation with.

–jeroen

Posted in Development, History, Scripting, Software Development | Leave a Comment »

Small batch file wrapper around PowerShell to uniquely sort file based content

Posted by jpluimers on 2021/05/19

From my batch file library; note this PowerShell wrapper does not support stdin, but that is OK for me.

For Windows 10 and up, sort /unique works too and supports stdin.

:: note: does not work on stdin, unliqke sort which does support standard input
:: http://secretgeek.net/ps_duplicates
PowerShell Get-Content %1 ^| Sort-Object ^| Get-Unique
:: note that for Windoww 10 and up, there is a sort /unique switch, but Windows versions below it do not.
:: https://superuser.com/questions/1316317/is-there-a-windows-equivalent-to-the-unix-uniq

Related:

–jeroen

Posted in Batch-Files, CommandLine, Development, PowerShell, PowerShell, Scripting, Software Development | Leave a Comment »

Chocolatey: I favor ‘choco upgrade’ over ‘choco install’

Posted by jpluimers on 2021/05/06

A while ago I found out that choco upgrade will install a package when it is not installed, and that choco upgrade all will upgrade all installed packages.

So I looked up the documentation of both choco install and choco upgrade (and choco update which will be deprecated) where I bolded parts of the upgrade command:

Given that upgrade can do both an upgrade and an install, I have switched all my install scripts to use upgrade in steaf of install.

Not all of the above commands accept the same set of [Wayback] Chocolatey Software Docs | Commands: Default Options and Switches

-?, --help, -h
     Prints out the help menu.

 -d, --debug
     Debug - Show debug messaging.

 -v, --verbose
     Verbose - Show verbose messaging. Very verbose messaging, avoid using 
       under normal circumstances.

     --trace
     Trace - Show trace messaging. Very, very verbose trace messaging. Avoid 
       except when needing super low-level .NET Framework debugging. Available 
       in 0.10.4+.

     --nocolor, --no-color
     No Color - Do not show colorization in logging output. This overrides 
       the feature 'logWithoutColor', set to 'False'. Available in 0.10.9+.

     --acceptlicense, --accept-license
     AcceptLicense - Accept license dialogs automatically. Reserved for 
       future use.

 -y, --yes, --confirm
     Confirm all prompts - Chooses affirmative answer instead of prompting. 
       Implies --accept-license

 -f, --force
     Force - force the behavior. Do not use force during normal operation - 
       it subverts some of the smart behavior for commands.

     --noop, --whatif, --what-if
     NoOp / WhatIf - Don't actually do anything.

 -r, --limitoutput, --limit-output
     LimitOutput - Limit the output to essential information

     --timeout, --execution-timeout=VALUE
     CommandExecutionTimeout (in seconds) - The time to allow a command to 
       finish before timing out. Overrides the default execution timeout in the 
       configuration of 2700 seconds. '0' for infinite starting in 0.10.4.

 -c, --cache, --cachelocation, --cache-location=VALUE
     CacheLocation - Location for download cache, defaults to %TEMP% or value 
       in chocolatey.config file.

     --allowunofficial, --allow-unofficial, --allowunofficialbuild, --allow-unofficial-build
     AllowUnofficialBuild - When not using the official build you must set 
       this flag for choco to continue.

     --failstderr, --failonstderr, --fail-on-stderr, --fail-on-standard-error, --fail-on-error-output
     FailOnStandardError - Fail on standard error output (stderr), typically 
       received when running external commands during install providers. This 
       overrides the feature failOnStandardError.

     --use-system-powershell
     UseSystemPowerShell - Execute PowerShell using an external process 
       instead of the built-in PowerShell host. Should only be used when 
       internal host is failing. Available in 0.9.10+.

     --no-progress
     Do Not Show Progress - Do not show download progress percentages. 
       Available in 0.10.4+.

     --proxy=VALUE
     Proxy Location - Explicit proxy location. Overrides the default proxy 
       location of ''. Available for config settings in 0.9.9.9+, this CLI 
       option available in 0.10.4+.

     --proxy-user=VALUE
     Proxy User Name - Explicit proxy user (optional). Requires explicit 
       proxy (`--proxy` or config setting). Overrides the default proxy user of 
       ''. Available for config settings in 0.9.9.9+, this CLI option available 
       in 0.10.4+.

     --proxy-password=VALUE
     Proxy Password - Explicit proxy password (optional) to be used with 
       username. Requires explicit proxy (`--proxy` or config setting) and 
       user name.  Overrides the default proxy password (encrypted in settings 
       if set). Available for config settings in 0.9.9.9+, this CLI option 
       available in 0.10.4+.

     --proxy-bypass-list=VALUE
     ProxyBypassList - Comma separated list of regex locations to bypass on 
       proxy. Requires explicit proxy (`--proxy` or config setting). Overrides 
       the default proxy bypass list of ''. Available in 0.10.4+.

     --proxy-bypass-on-local
     Proxy Bypass On Local - Bypass proxy for local connections. Requires 
       explicit proxy (`--proxy` or config setting). Overrides the default 
       proxy bypass on local setting of 'True'. Available in 0.10.4+.

     --log-file=VALUE
     Log File to output to in addition to regular loggers. Available in 0.1-
       0.8+.

–jeroen

Posted in Batch-Files, Chocolatey, Development, Power User, Scripting, Software Development, Windows | Leave a Comment »

ESXi: where are my log files actually stored? Actually, most of them are in `/scratch/log` which points to a hidden `.locker` directory in a datastore.

Posted by jpluimers on 2021/05/05

A summary of the full gist at [Wayback/Archive.is] ESXi-where-are-my-log-files-stored.txt:

# ls -al / /var/ /var/log/ /var/run/ /scratch/ /scratch/log/ | grep "/\|log\|-\>"
/:
...
lrwxrwxrwx    1 root     root            57 Apr  4 18:16 scratch -> /vmfs/volumes/5ce2d440-72311161-75c5-0025907d9d5c/.locker
...
/scratch/:
drwxr-xr-x    1 root     root        106496 Apr 10 08:40 log
/scratch/log/:
-rw-------    1 root     root           411 Apr  4 18:20 Xorg.log
...
-rw-------    1 root     root         78835 Apr  4 10:30 syslog.0.gz
-rw-------    1 root     root         61136 Mar 18 15:05 syslog.1.gz
-rw-------    1 root     root         60589 Feb 24 00:30 syslog.2.gz
-rw-------    1 root     root         60373 Feb  1 08:01 syslog.3.gz
-rw-------    1 root     root         60203 Jan  9 15:50 syslog.4.gz
-rw-------    1 root     root         59889 Dec 17 23:20 syslog.5.gz
-rw-------    1 root     root         60398 Nov 25 06:50 syslog.6.gz
-rw-------    1 root     root         60563 Nov  2 14:25 syslog.7.gz
-rw-------    1 root     root        531794 Apr 10 09:35 syslog.log
...
-rw-------    1 root     root        157255 Apr  4 18:17 vvold.log
/var/:
...
drwxr-xr-x    1 root     root           512 Apr  5 19:19 log
...
/var/log/:
-rw-r--r--    1 root     root           416 Apr  4 18:16 .vmsyslogd.err
...
-rw-r--r--    1 root     root         38069 Apr  4 18:20 configRP.log
-rw-r--r--    1 root     root             0 Apr  4 18:16 cryptoloader.log
...
-rw-r--r--    1 root     root            87 Apr  5 21:57 esxcli.log
...
-rw-------    1 root     root          3350 Apr  4 18:16 init.log
-rw-r--r--    1 root     root           966 Apr  4 18:16 iofilter-init.log
...
-rw-r--r--    1 root     root         21769 Apr  4 18:16 jumpstart-esxcli-stdout.log
-rw-r--r--    1 root     root         18857 Apr  4 18:16 jumpstart-native-stdout.log
-rw-r--r--    1 root     root         10837 Apr  4 18:16 jumpstart-stdout.log
-rw-r--r--    1 root     root             0 Apr  4 18:16 kickstart.log
...
-rw-------    1 root     root         10916 Apr  4 18:16 sysboot.log
...
-rw-------    1 root     root            64 Apr 10 09:13 tallylog
...
/var/run/:
lrwxrwxrwx    1 root     root            12 Apr  4 18:16 log -> /scratch/log
  • Almost all log files (most from /var/log and all from /var/run/log) are actually persistently stored in /scratch/log and survive reboots. Just a few are non-persistent.
  • /var/log/syslog is being archived as .gz files (compressed by gzip).
  • syslog is special: the location can be configured, and even be external: [Wayback] Configuring syslog on ESXi (2003322)

    VMware vSphere ESXi 5.0 and higher hosts run a Syslog service (vmsyslogd) that provides a standard mechanism for logging messages from the VMkernel and other system components. By default in ESXi, these logs are placed on a local scratch volume or a ramdisk. To preserve the logs further, ESXi can be configured to place these logs to an alternate storage location on disk and to send the logs across the network to a Syslog server.

  • A summary of some of the above log files is at [Wayback] ESXi Log File Locations

–jeroen

Posted in *nix, *nix-tools, ash/dash, ash/dash development, BusyBox, Development, ESXi6, ESXi6.5, ESXi6.7, ESXi7, gzip, Power User, Scripting, Software Development, Virtualization, VMware, VMware ESXi | Leave a Comment »

Preference variable $ConfirmPreference allows getting more or less PowerShell confirmation prompts

Posted by jpluimers on 2021/05/04

On my list to experiment with are [Wayback] about_Preference_Variables – PowerShell | Microsoft Docs, especially

$ConfirmPreference

Determines whether PowerShell automatically prompts you for confirmation before running a cmdlet or function.

The $ConfirmPreference variable’s valid values are HighMedium, or Low. Cmdlets and functions are assigned a risk of HighMedium, or Low. When the value of the $ConfirmPreference variable is less than or equal to the risk assigned to a cmdlet or function, PowerShell automatically prompts you for confirmation before running the cmdlet or function.

If the value of the $ConfirmPreference variable is None, PowerShell never automatically prompts you before running a cmdlet or function.

To change the confirming behavior for all cmdlets and functions in the session, change $ConfirmPreference variable’s value.

To override the $ConfirmPreference for a single command, use a cmdlet’s or function’s Confirm parameter. To request confirmation, use -Confirm. To suppress confirmation, use -Confirm:$false.

Valid values of $ConfirmPreference:

  • None: PowerShell doesn’t prompt automatically. To request confirmation of a particular command, use the Confirm parameter of the cmdlet or function.
  • Low: PowerShell prompts for confirmation before running cmdlets or functions with a low, medium, or high risk.
  • Medium: PowerShell prompts for confirmation before running cmdlets or functions with a medium, or high risk.
  • High: PowerShell prompts for confirmation before running cmdlets or functions with a high risk.

–jeroen

Posted in .NET, CommandLine, Development, PowerShell, PowerShell, Scripting, Software Development | Leave a Comment »

VMware ESXi console: viewing all VMs, suspending and waking them up: part 5

Posted by jpluimers on 2021/04/30

Yesterday’s post got a bit longer than anticipated as there were most steps than I hoped for to create the listing script vim-cmd-list-all-VMs.sh:

#!/bin/sh
# https://wiert.me/2021/04/29/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-4/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
done

This means that today there is a new try to cover the rest of these lists I started yesterday with:

Available commands

  • vim-cmd vmsvc/power.getstate vmid
  • vim-cmd vmsvc/power.hibernate vmid
  • vim-cmd vmsvc/power.off vmid
  • vim-cmd vmsvc/power.on vmid
  • vim-cmd vmsvc/power.reboot vmid
  • vim-cmd vmsvc/power.reset vmid
  • vim-cmd vmsvc/power.shutdown vmid
  • vim-cmd vmsvc/power.suspend vmid
  • vim-cmd vmsvc/power.suspendResume vmid

Unavailable commands

  • vim-cmd vmsvc/power.startup vmid
  • vim-cmd vmsvc/power.resume vmid
  • vim-cmd vmsvc/power.wakeup vmid

So here we go:

vim-cmd-hibernate-running-VMs.sh and vim-cmd-suspend-running-VMs.sh

These files are almost the same: the echo and command are different (Hibernating versus Suspending and power.hibernate versus suspend)

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Powered on" ] ; then
        echo "Powered on  VM with id ${vmid} and name: $name"
        echo "Hibernating VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.hibernate ${vmid}
    fi
done

This hibernates all VMs with power state Powered on and waits for each VM to complete hibernation.

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Powered on" ] ; then
        echo "Powered on VM with id ${vmid} and name: $name"
        echo "Suspending VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.suspend ${vmid}
    fi
done

This suspends all VMs with power state Powered on and waits for each VM to complete suspending.

vim-cmd-resume-suspended-VMs.sh and vim-cmd-wakeup-suspended-VMs.sh

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Suspended" ] ; then
        echo "Suspended VM with id ${vmid} and name: $name"
        echo "Resuming  VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.on ${vmid}
    fi
done

This resumes (as there is no vim-cmd vmsvc/power.resume vmid) all VMs with power state Suspended and waits for each VM to complete resume.

vim-cmd-power-off-powered-on-VMs.sh

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Powered on" ] ; then
        echo "Powered on   VM with id ${vmid} and name: $name"
        echo "Powering off VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.off ${vmid}
    fi
done

This powers off all VMs with power state Power on and waits for each VM to start powering off (but does not wait for them to complete powering off, so parts run in parallel).

vim-cmd-power-on-powered-off-VMs.shvim-cmd-power-on-shutdown-VMs.sh and vim-cmd-startup-shutdown-VMs.sh

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Powered off" ] ; then
        echo "Powered off VM with id ${vmid} and name: $name"
        echo "Powering on VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.on ${vmid}
    fi
done

These powers on all VMs with power state Powered off and waits for each VM to complete power on (but does not wait for them to complete boot, so part runs in parallel!).

These are exactly the same, as you cannot distinguish a VM that has been shutdown by vim-cmd vmsvc/power.off vmid from vim-cmd vmsvc/shutdown vmid.

vim-cmd-reboot-powered-on-VMs.sh

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Powered on" ] ; then
        echo "Powered on VM with id ${vmid} and name: $name"
        echo "Rebooting  VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.reboot ${vmid}
    fi
done

This reboots all VMs with power state Power on and waits for each VM to start rebooting (but does not wait for them to complete reboot, so parts run in parallel).

vim-cmd-reset-powered-on-VMs.sh

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Powered on" ] ; then
        echo "Powered on VM with id ${vmid} and name: $name"
        echo "Resetting  VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.reset ${vmid}
    fi
done

This resets all VMs with power state Power on and waits for each VM to start rebooting (but does not wait for them to complete reboot, so parts run in parallel).

vim-cmd-suspendResume-powered-on-VMs.sh

#!/bin/sh
# https://wiert.me/2021/04/30/vmware-esxi-console-viewing-all-vms-suspending-and-waking-them-up-part-5/
vmids=`vim-cmd vmsvc/getallvms | sed -n -E -e "s/^([[:digit:]]+)\s+((\S.+\S)?)\s+(\[\S+\])\s+(.+\.vmx)\s+(\S+)\s+(vmx-[[:digit:]]+)\s*?((\S.+)?)$/\1/p"`
for vmid in ${vmids} ; do
    powerState=`vim-cmd vmsvc/power.getstate ${vmid} | sed '1d'`
    name=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/\(vim.vm.ConfigInfo\) \{/,/files = \(vim.vm.FileInfo\) \{/ s/^ +name = "(.*)",.*?/\1/p'`
    vmPathName=`vim-cmd vmsvc/get.config ${vmid} | sed -n -E -e '/files = \(vim.vm.FileInfo\) \{/,/tools = \(vim.vm.ToolsConfigInfo\) \{/ s/^ +vmPathName = "(.*)",.*?/\1/p'`
    # echo "VM with id ${vmid} has power state ${powerState} (name = ${name}; vmPathName = ${vmPathName})."
    if [ "${powerState}" == "Powered on" ] ; then
        echo "Powered on      VM with id ${vmid} and name: $name"
        echo "SuspendResuming VM with id ${vmid} and name: $name"
        vim-cmd vmsvc/power.suspendResume ${vmid}
    fi
done

This suspends and resumes on all VMs with power state Power on and waits for each VM to start this shirt cycle (but does not wait for them to complete the suspend and resume cycle, so parts run in parallel).

Future episodes

For now, this is OK enough for me, but I might write a new installment trying to run more of these in parallel (as parts already are done on the ESXi side).

–jeroen

Posted in *nix, *nix-tools, ash/dash, ash/dash development, Development, ESXi6, ESXi6.5, ESXi6.7, ESXi7, Power User, Scripting, sed, sed script, Software Development, Virtualization, VMware, VMware ESXi | Leave a Comment »