Centralized Startup Scripting for Automated VM Load Testing

When building or troubleshooting infrastructure, it is often useful to simulate high CPU or memory usage withou deploying full production workloads. To assist with this, I previously created a few purpose built, like cpubusy.sh and memfill.sh.

Historically, I created multiple Tiny Core Linux templates, each designed for a specific purpose, a generic one for troubleshooting, one that would fill mem and a another to load up the CPU. I’d then place these scripts in /opt/bootlocal.sh, allowing each VM to run its designated script automatically at startup. I’d then control load by simply powering VMs on or off.

The Problem

That setup works fine for simple use cases, but it doesn’t scale well. What if I want:

  • One VM to simulate CPU load,
  • Another to test download speeds,
  • A third to run a custom test script—all using the same base image?

The Common Control Script

This script runs at boot and checks for specific instructions to execute. The idea is simple: deploy a single generic VM template that decides what to do based on either:

  • Metadata (via guestinfo)
  • Network identity (IP, MAC, hostname)
  • Shared config (via GuestStore or a web server)

This common control script can be found here: code-snips/cc.sh.

Where It Looks for Instructions

When a VM boots, the script checks for commands in the following order:

  1. Web server:
    • http://<web>/<macaddress>.txt
    • http://<web>/<ipaddress>.txt
    • http://<web>/<hostname>.txt
    • http://<web>/all.txt
  2. VM Guest Store (using VMware tools):
    • guestinfo.ccScript (specified via advanced VM setting)
    • /custom/cc/cc-all.txt

This layered approach gives flexibility:

  • Set a global script via all.txt
  • Override per host via metadata or identifiers
  • Or push custom scripts directly via GuestInfo

Example: Setting the GuestInfo Property

Using PowerCLI, we can set the script filename per VM like this:

Get-VM h045-tc16-02 | New-AdvancedSetting -Name 'guestinfo.ccScript' -Value 'memfill.sh' -confirm:$false

We can also modify this via the vSphere Web Client.

Demonstration

Here’s a test case from my lab:

  • I set guestinfo.ccScript to memfill.sh
  • The all.txt file includes a simple command to print system time

Upon boot, the VM fills 90% of available RAM using a memory-backed filesystem and prints the time, confirming that both script sources are active.

Later, I removed the guestinfo.ccScript setting and added a <hostname>.txt script to download a file repeatedly from a test web server. After reboot, the VM behaved differently, now acting as a network test client. No changes to the template required.

Sample Scripts

Here are a few lightweight test scripts used in the demo:

  • cpubusy.sh – uses sha1sum to keep all the configured CPU cores busy
  • download.sh – uses wget to get the same webserver file x times and save it to /dev/null
  • memfill.sh – creates a memory backed filesystem using 90% of RAM, then uses dd to fill it

Conclusion

This ‘common config’ approach provides template reuse, easier script management, and dynamic testing control, all without modifying the template.

Whether testing CPU, memory, or network load across dozens of VMs, the common control script simplifies the process and reduces maintenance overhead.

In future iterations, this setup could be extended to include conditional logic (based on boot time, VM tags, or other metadata), or integration with CI pipelines for even more powerful automation.

This entry was posted in Scripting, Virtualization. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Notify me of followup comments via e-mail. You can also subscribe without commenting.