Search This Blog

Friday, September 11, 2026

How to Auto-Start and Auto-Stop a VMware Workstation VM with Windows

Automatically Start and Stop a VMware Workstation VM with Windows Boot and Shutdown

If you run a VM in VMware Workstation as a background server — a dev box, a build server, a lab appliance — clicking “Power On” every time you boot your host gets old fast. And if you forget to shut it down properly before you power off Windows, you risk an unclean guest shutdown.

This guide covers both directions:

  • Start the VM headlessly the moment Windows boots (or you log in), with no console window popping up.
  • Stop the VM gracefully the moment Windows begins shutting down.

Both use vmrun, VMware’s command-line control tool that ships with Workstation — no third-party software required.

Prerequisites

  • VMware Workstation Pro installed, with vmrun.exe present (usually under C:\Program Files\VMware\VMware Workstation\ or the (x86) variant, depending on your install).
  • VMware Tools installed and running in the guest OS. This is required for a graceful (“soft”) shutdown to work — without it, VMware can’t ask the guest to shut down cleanly.
  • The full path to your VM’s .vmx file. You can find it with:
    dir "C:\path\to\your\vm\*.vmx"

Throughout this guide, the examples use:

vmrun.exe:  C:\Program Files\VMware\VMware Workstation\vmrun.exe
VM file:    C:\Virtual Machines\Ubuntu 24.04\Ubuntu 24.04.vmx

Swap in your own paths.

Part 1: Auto-Start the VM at Windows Boot

The command

"C:\Program Files\VMware\VMware Workstation\vmrun.exe" -T ws start "C:\Virtual Machines\Ubuntu 24.04\Ubuntu 24.04.vmx" nogui

The nogui flag is the key part — it starts the VM entirely in the background. No Workstation window, no console tab, nothing to click through. You just SSH or RDP into the guest once it’s up.

Wrap it in a batch file

Save this as start-xubuntu.bat:

@echo off
set VMRUN="C:\Program Files\VMware\VMware Workstation\vmrun.exe"
set VMX="C:\Virtual Machines\Ubuntu 24.04\Ubuntu 24.04.vmx"

%VMRUN% -T ws start %VMX% nogui

If your VM ever comes up looking paused instead of fully booted, add a follow-up line to force it:

%VMRUN% -T ws reset %VMX%

Schedule it with Task Scheduler

The Startup folder (shell:startup) works, but Task Scheduler gives you a delay option, which matters here — VMware’s background networking services (vmnet, authd) need a moment to initialize before vmrun can talk to them.

  1. Open Task Scheduler (Win key → search “Task Scheduler”) and click Create Basic Task…
  2. Name it something like Start xUbuntu VM.
  3. Set the trigger:
    • When I log on — simplest, runs each time you sign in.
    • When the computer starts — runs even before anyone logs in (requires the setting below).
  4. Action: Start a program → Browse to start-xubuntu.bat.
  5. On finish, tick “Open Properties,” and if you chose “When the computer starts,” select Run whether user is logged on or not on the General tab.
  6. On the Triggers tab, edit the trigger → Advanced settings → check Delay task for and set it to 30–60 seconds. This avoids race conditions with VMware’s services on boot.
  7. Test it by right-clicking the task and choosing Run, then confirm with:
    "C:\Program Files\VMware\VMware Workstation\vmrun.exe" list

Note: If you use “When the computer starts” + “Run whether user is logged on or not,” test with a full reboot, not just “Run” from Task Scheduler — some Workstation licensing/session behavior can differ when nothing is logged in yet.

Part 2: Auto-Stop the VM at Windows Shutdown

The command

"C:\Program Files\VMware\VMware Workstation\vmrun.exe" -T ws stop "C:\Virtual Machines\Ubuntu 24.04\Ubuntu 24.04.vmx" soft

soft tells VMware Tools inside the guest to shut the OS down gracefully — the equivalent of running shutdown from within the guest itself, rather than yanking power.

Save this as stop-xubuntu.bat:

@echo off
"C:\Program Files\VMware\VMware Workstation\vmrun.exe" -T ws stop "C:\Virtual Machines\Ubuntu 24.04\Ubuntu 24.04.vmx" soft

Why Task Scheduler doesn’t have a simple “shutdown” trigger

Unlike startup, Windows has no built-in “run this at shutdown” checkbox in the Task Scheduler wizard. There are two supported ways to get a script to fire before the OS actually powers off:

Option A: Group Policy shutdown script (Windows 11 Pro/Enterprise)

  1. Press Win+R, type gpedit.msc, Enter. (Not available on Windows 11 Home — use Option B instead.)
  2. Navigate to Computer Configuration → Windows Settings → Scripts (Startup/Shutdown), and double-click Shutdown.
  3. Click Add…, browse to stop-xubuntu.bat, and confirm.
  4. Increase the script wait time. A Linux guest’s graceful shutdown can take well over a minute, but Windows may cut scripts off before that. Go to Computer Configuration → Administrative Templates → System → Scripts, open Specify maximum wait time for Group Policy scripts, set it to Enabled, and give it something like 120 seconds.
  5. Test by shutting down or restarting Windows normally — you’ll see a brief pause on the shutdown screen while the script runs. Check afterward that the VM shows as cleanly powered off, not suspended.

Option B: Task Scheduler with an event trigger (Windows 11 Home, or if you prefer avoiding gpedit)

Windows logs an event the moment a shutdown or restart is requested, before it actually happens — you can trigger off that.

  1. Open Task Scheduler → Create Task… (the full dialog, not “Create Basic Task,” since you need an event trigger).
  2. Triggers tab → New → “Begin the task” = On an event.
  3. Set Log: System, Source: User32, Event ID: 1074.
  4. Actions tab → Start a Program → point it at stop-xubuntu.bat.
  5. General tab → check Run whether user is logged on or not and Run with highest privileges.

A Caveat Worth Knowing

A soft stop only works if VMware Tools is installed and responsive inside the guest. If Tools isn’t running or the guest is hung, the soft stop request does nothing — and Windows will simply kill the VM process when it shuts down anyway, the same as an unclean power-off. It won’t corrupt most workloads, but it’s not a substitute for making sure Tools is actually running.

Wrapping Up

With both pieces in place, your VM behaves like any other background service: it comes up shortly after you boot Windows and shuts down cleanly the moment you power off — no console window, no manual clicks, no half-shut-down guest left behind.

Monday, August 31, 2026

grep lines from one file which are in another file

A frequent task in shell scripting and data processing is filtering out lines from one text file that appear in another (e.g., subtracting a list file from a dataset). Rather than writing loops or complex awk scripts, standard GNU grep provides an efficient, one-line solution.


The Solution

grep -v -x -F -f list.txt dataset.txt > filtered_output.txt

(This command outputs all lines from dataset.txt that do not match any exact lines listed in list.txt.)


Flag Breakdown

Flag Full Option Function
-v --invert-match Selects non-matching lines (inverts the filter).
-x --line-regexp Forces matches to span the entire line, preventing partial substring exclusions.
-F --fixed-strings Treats input patterns as literal strings rather than regular expressions (much faster and avoids escaping special characters like ., *, or [).
-f FILE --file=FILE Reads exclusion patterns line-by-line from the specified file.

Regex Patterns vs. Fixed Strings

  • When to omit -F: Use grep -v -x -f patterns.txt data.txt if lines inside patterns.txt contain intentional regular expression syntax (such as wildcard matchers like ^server-[0-9]+).
  • When to include -F (Recommended): Use -F whenever you want a strict, exact text match (WYSIWYG). It prevents characters like dots, brackets, and dollar signs from being parsed as regular expressions, while significantly speeding up processing on large datasets.

From Code to Commercials: 10 Harsh Realities Every Engineer Needs to Hear

After more than ten years as an electronics engineer, I have seen brilliant minds get stuck while others thrive in leadership and business. Technical skill is essential, but it is rarely enough on its own. Here are ten direct, practical lessons for building a successful, well-rounded career.


1. Plan Your Career Intentionally

Do not drift purely on impulse. Choose a solid industry, gain deep domain knowledge, and avoid frequent job-hopping for minor pay raises. Long-term stability and industry depth build compounding value—once you truly master a sector, financial rewards follow naturally.


2. Do Not Get Trapped in Pure Technology

Technical skill is only one pillar of your career value, not the entire foundation. Unless your sole lifetime goal is remaining an individual bench technician, avoid obsessing over narrow technical details at the expense of everything else.


3. Cultivate Broad Professional Skills

Never look down on managers or peers with less technical depth. If someone advances, they usually excel at things you might lack: coordinating teams, aligning with leadership priorities, and resolving conflict. Strong communication and diplomacy matter just as much as technical ability.


4. Expand Your Social Circle

Do not limit your network strictly to other engineers. Build relationships with people across sales, marketing, finance, and different walks of life. Understanding how different people think and operate is essential if you ever want to lead a business or manage projects.


5. Broaden Your Knowledge Base

Depth in your core field is necessary, but breadth makes you versatile. Read and learn about business basics: finance, accounting, taxation, contracts, and logistics. This broad perspective helps you avoid costly mistakes later on.


6. Transition to Management or Sales When Ready

Individual technical execution has a natural ceiling. Moving into technical management develops leadership skills, while moving toward sales sharpens commercial intuition and builds an extensive business network—the true drivers of long-term career growth.


7. Overcome Classic Engineering Weaknesses

Engineers often struggle with perfectionism, over-analysis, indecision, and thin skin. Overcome these traits through real-world practice: take on public-facing tasks, negotiate with vendors, or participate directly in commercial discussions.


8. Build Your Own Workspace and Products

Set up a personal lab at home with essential tools, test equipment, and computing resources. Take on practical side projects to develop market sense. Working products and prototypes carry far more weight with partners and investors than diplomas or certificates.


9. Learn to Market Yourself

Skill without visibility leads nowhere. Learn to present your work clearly in writing and speaking. Share knowledge, publish articles, and build a recognizable personal brand so opportunities find you directly.


10. Take Action Without Waiting for 100% Certainty

Waiting for complete certainty leads to missed opportunities. When conditions are reasonably good, take decisive action. Success requires practical experimentation and learning through iterative attempts.

Pentaho Data Integration faster setup

If you run Pentaho Data Integration (PDI / Kettle) jobs via kitchen.sh or pan.sh, you may notice that startup latency has steadily increased across modern releases. A basic CLI invocation can take over 10 seconds just to initialize the JVM and load dependencies before processing a single row. By eliminating network reverse-DNS stalls and pruning unused heavy-weight plugins, you can cut CLI startup time down to ~1.2 seconds.


Benchmark: Startup Degradation Over Time

Measuring cold startup latency using a minimal test job (time ./kitchen.sh -file=test.kjb):

PDI Release Phase Real Time (Wall Clock) User Time (CPU)
Legacy Lightweight Releases 0.49s – 1.10s 0.78s – 2.14s
Early Modular Releases 5.97s – 34.11s 3.86s – 18.86s
Modern Default Installations 11.25s – 12.43s 26.17s – 28.83s
Pruned & Optimized Build 1.25s 3.23s

Step 1: Eliminate Hostname & Reverse DNS Lookups

When user CPU time is significantly lower than real clock time, Kettle is idling on network I/O timeouts trying to resolve the local machine's hostname.

  • Explicitly define the hostname: Add KETTLE_SYSTEM_HOSTNAME=localhost to your ~/.kettle/kettle.properties file.
  • Map the local hostname in /etc/hosts: Ensure your current machine hostname points directly to 127.0.0.1 to prevent remote DNS lookups.
  • Force IPv4 Resolution: Pass -Djava.net.preferIPv4Stack=true into your Java options inside kitchen.sh or spoon.sh to bypass IPv6 reverse-lookup timeouts:
    PENTAHO_DI_JAVA_OPTIONS="-Djava.net.preferIPv4Stack=true -Xms512m -Xmx2048m"

Step 2: Prune Unused Heavyweight Plugins & OSGi/Karaf Runtimes

Kettle scans and initializes OSGi bundles, Karaf runtimes, Mondrian models, and Big Data shims on every CLI run. If your workflow only uses standard database, text, or transform steps, you can safely remove these subsystems.

Files and Folders to Move Out

Move the following directories, descriptors, and unused engine/driver JARs into a backup location outside your PDI installation directory:

# Move OSGi, Karaf, and Mondrian system runtimes
mv system/karaf /path/to/pdi-backup/
mv system/mondrian /path/to/pdi-backup/
mv system/osgi /path/to/pdi-backup/

# Move heavy plugins
mv plugins/pentaho-big-data-plugin /path/to/pdi-backup/
mv plugins/kettle*-log4j-plugin /path/to/pdi-backup/
mv plugins/pdi-xml-plugin /path/to/pdi-backup/

# Move lifecycle descriptors
mv classes/kettle-lifecycle-listeners.xml /path/to/pdi-backup/
mv classes/kettle-registry-extensions.xml /path/to/pdi-backup/

# Move unused engine, spark, and platform JARs from lib/
mv lib/mondrian-*.jar /path/to/pdi-backup/
mv lib/org.apache.karaf.*.jar /path/to/pdi-backup/
mv lib/pdi-engine-api-*.jar /path/to/pdi-backup/
mv lib/pdi-engine-spark-*.jar /path/to/pdi-backup/
mv lib/pdi-osgi-bridge-core-*.jar /path/to/pdi-backup/
mv lib/pdi-spark-driver-*.jar /path/to/pdi-backup/
mv lib/pentaho-capability-manager-*.jar /path/to/pdi-backup/
mv lib/pentaho-connections-*.jar /path/to/pdi-backup/
mv lib/pentaho-cwm-*.jar /path/to/pdi-backup/
mv lib/pentaho-database-model-*.jar /path/to/pdi-backup/
mv lib/pentaho-hadoop-shims-api-*.jar /path/to/pdi-backup/
mv lib/pentaho-metaverse-api-*.jar /path/to/pdi-backup/
mv lib/pentaho-osgi-utils-api-*.jar /path/to/pdi-backup/
mv lib/pentaho-platform-*.jar /path/to/pdi-backup/
mv lib/pentaho-registry-*.jar /path/to/pdi-backup/
mv lib/pentaho-service-coordinator-*.jar /path/to/pdi-backup/

Long-Term Architecture Tip

If you execute hundreds of transformations in rapid batches, repeated JVM cold starts will always introduce cumulative latency. For high-frequency workloads, run transformations via the Carte slave server daemon or integrate directly with the Kettle Java API to keep the JVM warmed up continuously.

group iptables rules in chain

When managing multiple firewall rules for a specific application, service, or policy, adding them directly to default chains (like INPUT, FORWARD, or PREROUTING) makes bulk updates and cleanups difficult. If you need to remove or disable that policy later, you would normally have to delete every single rule one by one.

The cleanest solution in iptables is to create a custom user-defined chain. By grouping related rules inside their own chain and linking that chain to a default table, you can enable, disable, or flush all associated rules in a single command.


The Problem: Cluttered Default Chains

Consider applying several packet-marking or filtering rules for a specific service across different hooks:

iptables -t mangle -A PREROUTING -p udp --dport 4444 -j MARK --set-mark 100
iptables -t mangle -A INPUT -p udp --dport 4444 -j MARK --set-mark 100
iptables -t mangle -A OUTPUT -p udp --dport 4444 -j MARK --set-mark 200

Deleting these later requires referencing each specific rule line or rule number individually, which is tedious and error-prone in production environments.


The Solution: Group Rules into a Custom Chain

Step 1: Create the Custom Chain in the Target Table

Create a custom chain (e.g., MYCHAIN). Remember that user-defined chains exist only within the specific table where they are created (e.g., mangle, filter, or nat):

# Create MYCHAIN inside the mangle table
iptables -t mangle -N MYCHAIN

Step 2: Add Rules into Your Custom Chain

Populate your chain with the relevant match criteria and actions:

iptables -t mangle -A MYCHAIN -p udp --dport 4444 -j MARK --set-mark 100
iptables -t mangle -A MYCHAIN -p udp --sport 4444 -j MARK --set-mark 200

Step 3: Link Your Custom Chain to Built-in Chains

To make the rules active, direct traffic from the standard hooks (such as PREROUTING or INPUT) into your custom chain:

iptables -t mangle -A PREROUTING -j MYCHAIN
iptables -t mangle -A OUTPUT -j MYCHAIN

How to Easily Manage and Delete the Group

When you need to clear or completely remove the rule group, the workflow is clean and immediate:

  1. Unlink the Chain: Remove the single jump rule from the built-in chains:
    iptables -t mangle -D PREROUTING -j MYCHAIN
    iptables -t mangle -D OUTPUT -j MYCHAIN
  2. Flush the Rules: Clear all rules inside your custom chain in one step:
    iptables -t mangle -F MYCHAIN
  3. Delete the Empty Chain: Remove the custom chain definition:
    iptables -t mangle -X MYCHAIN