Greetings friends, today we start with some well deserved empathy, especially after an amazing Veeam 100 event in Prague. If you have upgraded to Veeam Software Appliance, and deployed the VSA + components based in JeOS, I am sure you have already felt the pain of rotating dozens of local OS passwords across Veeam Software Appliance, Hardened Repositories, and VIA based machines, you are not alone. By the way, this is nothing to with Veeam specifically, it is a DISA STIG requirement.
The thread that triggered this work is here: Veeam Forums: [V13] Question regarding Veeam B&R 13.x. Read the story, it is intense but true at the same time.
TLDR – what is this post all about
This is the field-friendly write up for Veeam Appliance Local Account Password Rotation. The goal is simple: reduce pain as safe as possible. I am not expecting to change product policy, just giving you some steps that mimic the UI, so you can rotate many local accounts with OTP, logs, and CSV output for your vault.
Why this matters
The Veeam Software Appliance and its Host Management UI, and by default all VIA based machines have local OS accounts. With only 2 accounts per node, 60 VIA based machines means 120 local OS accounts, plus 4 more on the VBR appliance. In total 124 accounts to change every 60 days. That is a lot of work. Doing 3 accounts on 28 systems took about 4 hours. At 60 to 70 nodes this becomes 1 to 1.5 days every 2 months. Forums veeam.com
That is the kind of repetitive work no one enjoys. The script below gives you a way to automate the rotation through the Host Management API, including a special self change flow for veeamadmin and a proper self flow for Security Officer users that require currentPassword and OTP.
Important note
NOT OFFICIALLY SUPPORTED. Use at your own risk. Keep your environment files protected. Move the generated CSV straight to your password manager and remove the local copy. Please give this a try on some small environment, and then remember this is not supported, it just uses the APIs the Host Manager uses, but in any case as it has not been officially approved, not supported.
What you get
- Rotation through API only. No SSH.
- OTP support: interactive prompt or TOTP secret.
- Self rotation for
veeamadmin(uid 2000) using/v2/users/self/passwd. - Security Officer self flow using
/v2/users/self/passwdwithcurrentPasswordand OTP. - Password policy preflight and strong generator with guardrails.
- Optional description timestamp update on standard users.
- CSV output:
user_id,new_password,timestampwith secure umask.
Requirements
- Veeam Software Appliance or VIA based nodes reachable on Host Management API.
- Linux host to run the script.
- Tools:
bash,curl,jq,oathtool,awk,sed,coreutils. - Python 3 for password generation.
On Rocky Linux you can install small bits with:
sudo dnf install -y jq oathtool
Download and folder layout
Clone or drop the script in a clean folder and make it executable. You can find the code here – https://github.com/jorgedlcruz/veeam-appliance-password-rotate
mkdir -p ~/vbr-rotate && cd ~/vbr-rotate # Save your script as veeam-appliance-rotate-passwords.sh chmod +x veeam-appliance-rotate-passwords.sh
Create your .env
Keep it tight. Use chmod 600 and store only what you need. You can also export the variables in your shell for one time use.
cat > .env <<'EOF' ######################################## # Core connection ######################################## BASE="https://YOURVSAIP:10443" # Required ADMIN_USER="veeamadmin" # Required ADMIN_PASS="" # Optional. Leave empty to be prompted VERIFY_TLS="false" # Optional. Set true if valid cert ######################################## # OTP and TOTP ######################################## OTP_MODE="prompt" # Required. "prompt" or "totp" TOTP_SECRET="" # Required only if OTP_MODE="totp" # Security Officer rotation settings SO_OTP_MODE="totp" # Optional. "prompt" or "totp" TOTP_SO_SECRET="" # Required if SO_OTP_MODE="totp" CURRENT_SO_PASS="" # Required if rotating an SO account ######################################## # Target users to rotate ######################################## # Space separated list of UIDs. Include 2000 to self rotate veeamadmin. USER_IDS="2003 2004 2000" ######################################## # Password policy knobs ######################################## #MIN_LEN="20" # Optional #MAX_SAME_CLASS_RUN="3" # Optional #SPECIAL_SET="!@#\$%^*_+=-?" # Optional ######################################## # Output ######################################## #OUT_FILE="rotated_passwords_$(date +%Y%m%d_%H%M%S).csv" # Optional EOF chmod 600 .env
Run it
Load the env and start. If ADMIN_PASS is empty the script will prompt for it. With OTP_MODE=prompt it will also ask for OTP codes just in time.
set -a . ./.env set +a ./veeam-appliance-rotate-passwords.sh
Examples
Interactive veeamadmin plus two service users
export BASE="https://vbr-appliance:10443" export ADMIN_USER="veeamadmin" export OTP_MODE="prompt" export USER_IDS="2000 2003 2004" ./veeam-appliance-rotate-passwords.sh
Non interactive window with TOTP
export BASE="https://vbr-appliance:10443" export ADMIN_USER="veeamadmin" export ADMIN_PASS="********" export OTP_MODE="totp" export TOTP_SECRET="BASE32SECRET" export USER_IDS="2003 2004" ./veeam-appliance-rotate-passwords.sh
Rotate an SO account as well
export BASE="https://vbr-appliance:10443" export ADMIN_USER="veeamadmin" export ADMIN_PASS="********" export SO_OTP_MODE="totp" export TOTP_SO_SECRET="SO_BASE32" export CURRENT_SO_PASS="********" export USER_IDS="2002" ./veeam-appliance-rotate-passwords.sh
What good looks like
[INFO] Login step 1 [INFO] Login step 2 with OTP [OK] Login success with OTP [INFO] CSRF extracted [INFO] Rotating: 2003 2004 2000 [STEP] POST /v1/users/check/password uid=2003 [STEP] PUT /v2/users/2003/passwd [OK] uid=2003 password rotated [OK] uid=2003 description updated [STEP] POST /v1/users/check/password uid=2004 [STEP] PUT /v2/users/2004/passwd [OK] uid=2004 password rotated [OK] uid=2004 description updated [INFO] Rotating SO password via self endpoint for uid=2002 user=veeamso [OK] uid=2002 SO password rotated [OK] uid=2000 veeamadmin password rotated [DONE] Saved rotated passwords to rotated_passwords_20251112_135105.csv
Troubleshooting
- http=401 or 428 during PUT – Server wants a fresh OTP. The script retries once. If it keeps failing, check time sync and codes.
- Could not create SO session – Validate
CURRENT_SO_PASSandTOTP_SO_SECRET, or useSO_OTP_MODE=prompt. - CSV is empty – Verify
USER_IDS, authentication success, and API reachability. - jq or oathtool missing – Install with your package manager.
Closing thoughts
This script exists because real operators shared real pain. Thank you to everyone who keeps pushing for practical ways to keep environments secure without burning a full day doing manual password changes. If you try it and it is useful for you, drop a comment or a PR in GitHub. If you find an edge case, tell me and I will try to fix it.
Stay safe and keep backups immutable, my friends.

Leave a Reply