Automating Lenovo BIOS Configuration Across a Multi-Site Enterprise Fleet — What Actually Works
There's a particular kind of frustration that comes from knowing a task is automatable, spending hours trying to automate it, and hitting walls at every turn. This is that story.
We run a global fleet of Lenovo ThinkPad laptops spread across multiple offices — US, London, Dubai, and Asia. New machines arrive, older ones get re-imaged, and every single one requires manual BIOS intervention before it's production-ready. We're talking 10 to 15 minutes per machine. Standing at a desk, tabbing through BIOS menus, setting supervisor passwords, disabling User Presence Sensing, enabling Intel AMT, turning off Lenovo Cloud Services and Computrace. Every. Single. Machine.
At scale, across a global fleet with multiple sites, that's a significant operational overhead — and a consistency problem. Manual processes mean variation. Variation in a trading environment is a risk.
For context — our existing fleet was Dell, and we had a mature, fully automated deployment pipeline in place for those machines. BIOS configuration, password setup, settings standardisation — all handled without manual intervention. When the decision was made to move to Lenovo ThinkPads, we had to build equivalent infrastructure from scratch. There was no existing Lenovo automation to draw on, no institutional knowledge of Lenovo's deployment tooling, and to add to the complexity, we were simultaneously rolling out Windows 11 across the organisation. New hardware platform. New OS. Machines arriving that needed to be production-ready. There had to be a better way. Spoiler: there was. But it took a lot of dead ends to find it.
The Problem — Two Parts, One Solution
Before getting into what went wrong and what finally worked, it's worth being clear about the scope because this problem has two distinct parts:
Part 1 — Initial BIOS Password Setup (during imaging) Setting a BIOS supervisor password on a machine that has no password. This is the hard part. It has to happen during the imaging process, in WinPE, before Windows boots. This is where most of the roadblocks live and where the key breakthrough — Lenovo's System Deployment Boot Mode — comes in.
Part 2 — Comprehensive BIOS Configuration (post-imaging) Once Windows is running and the machine is on the domain, a separate script handles the full BIOS configuration — around 40 settings covering security, power management, boot behaviour, and hardware access. This runs as part of a broader post-deployment automation framework (GPInstall), not just for BIOS but for the complete machine build.
These are two parts of the same deployment workflow, but they're separate scripts running at different phases. Understanding that distinction matters for how you implement it.
WinPE Phase (SDBM active)
→ Set initial supervisor password
Windows Phase (domain joined)
→ Configure ~40 BIOS settings
The Dead Ends
The Contradictory Documentation
The obvious starting point was Lenovo's own WMI documentation. Their BIOS Setup using Windows Management Instrumentation Deployment Guide (also searchable as the "Lenovo WMI BIOS Deployment Guide") — published in 2012 and still widely referenced — states clearly on page 12:
"A password cannot be set using this method when one does not already exist. Passwords can only be updated or cleared."
Fine. Except page 4 of the same document shows the exact syntax for initial password setup: "pap,,NEW_PASSWORD,ascii,us" — note the double comma, indicating no existing password.
The documentation simultaneously says it's impossible and shows you how to do it. Welcome to enterprise vendor documentation.
WinPE Has No Network Access (By Default)
The logical place to run the initial BIOS password work is during the imaging process itself — specifically in the POSTIMAGE phase of SmartDeploy, after the image is applied but before Windows boots. Scripts live on a network share, WinPE runs the script, done.
Except WinPE doesn't have network access by default. Scripts stored on UNC paths were completely inaccessible. The imaging process would reach the POSTIMAGE phase, attempt to call the script, and fail silently.
SmartDeploy Support Pointed at a GUI Tool
Reaching out to SmartDeploy support for guidance on running scripts from network shares during deployment returned a suggestion to look at Lenovo's Think BIOS Config Tool (TBCT). TBCT is a GUI application. Helpful for manually configuring individual machines — which is exactly what we were trying to eliminate.
The PowerShell 7 Trap
Once further along in testing, scripts that worked fine when called manually would fail whenever the execution chain invoked pwsh.exe. The culprit took time to identify: PowerShell 7 (pwsh.exe) does not include Get-WmiObject and relies on CIM instead. Lenovo's BIOS WMI provider depends on classic WMI methods that do not behave correctly under PowerShell 7.
If you're running Lenovo BIOS scripts and they fail with something like:
Method invocation failed because [Deserialized.System.Management.ManagementObject] does not contain a method named 'SetBiosPassword'
That error occurs because PowerShell 7 returns deserialized WMI objects, which no longer expose the underlying COM methods Lenovo's BIOS provider expects.
In practice, this almost always means PowerShell 7 is being invoked somewhere in the execution chain. Always use powershell.exe — Windows PowerShell 5.1 — for anything touching Lenovo BIOS via WMI. This applies even if you've set PowerShell 7 as your default shell. Explicitly call powershell.exe in every task, every GPO, every PDQ Deploy step.
The Breakthrough: System Deployment Boot Mode
After exhausting the obvious paths, the answer turned up buried in Lenovo's Commercial Deployment Readiness Team documentation — not the general support site, but the enterprise-focused CDRT resources at docs.lenovocdrt.com.
The feature is called System Deployment Boot Mode (SDBM).
SDBM is available on all ThinkPad models from the Whiskey Lake generation (2018) onwards and exists specifically to solve the enterprise deployment problem. When active, it allows you to:
- Set an initial BIOS supervisor password programmatically — the thing the 2012 documentation said was impossible
- Disable TPM Physical Presence requirements
- Configure security settings that would otherwise require user interaction
Here's how you activate it:
- Power on the Lenovo laptop
- Press F12 to open the boot menu
- Press DELETE
- Look for "System Deployment Boot Mode" in the upper right corner of the screen
- Select your PXE boot option and continue
That's it. Five seconds of manual interaction.
SDBM remains active for the duration of that boot session and automatically deactivates on the next reboot — a deliberate security design to prevent remote triggering.
It must be activated manually before PXE boot, cannot be triggered remotely, and does not persist across reboots.
It's documented in Lenovo's Commercial Deployment Readiness Team resources rather than their general support site, which likely explains why many organisations miss it. If you're running a ThinkPad fleet and you didn't know SDBM existed, you're not alone.
Part 1: Initial Password Setup During Imaging
This is the core of what SDBM unlocks. The script runs as a POSTIMAGE task in SmartDeploy — after the image is applied, while still in WinPE, before Windows boots.
Credit where it's due: The foundation for this script is imabdk's Config-LenovoBIOS.ps1, documented in detail on his blog. We adapted it for our SmartDeploy environment, but the core WMI logic is his work. If you're implementing this, read his original post — it's thorough and covers the ConfigMgr/SCCM path if that's your deployment tool.
Solving the WinPE network problem first: The wpeinit command initialises the network stack in WinPE. Without it, UNC paths are completely inaccessible. A 60-second sleep after wpeinit ensures the network is fully up before the script attempts to connect.
The POSTIMAGE task in the SmartDeploy Answer File:
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "& { wpeinit; Start-Sleep -Seconds 60; & '\\corp-fileserver\DFS\Install\SmartDeploy\ImageScripts\Config-LenovoBIOS.ps1' -SetSupervisorPass 'YourBuildPassword' }"
Note: Replace the UNC path and password parameter with your own values — ideally retrieved from your vault at runtime rather than hardcoded.
The script checks BIOS password state via WMI:
$passwordState = (Get-WmiObject -Namespace root\wmi -Class Lenovo_BiosPasswordSettings).PasswordState
- State 0 — No password set. SDBM is active, proceed with initial password setup.
- State 2 — Supervisor password already exists. This is a re-image. Skip password setup entirely.
The password format for initial setup uses a double comma (no old password):
# Initial setup - note the double comma
"pap,,NEW_PASSWORD,ascii,us"
# Subsequent changes - old password required
"pap,OLD_PASSWORD,NEW_PASSWORD,ascii,us"
That double comma is critical and easy to miss. If it's incorrect, the method may return 'Success' but the BIOS password will not actually change. Always validate the password state after setting it:
# Validate password state after setting/saving (expect 2; if in doubt, confirm after reboot as well)
$passwordState = (Get-WmiObject -Namespace root\wmi -Class Lenovo_BiosPasswordSettings).PasswordState
# 0 = no password (something went wrong), 2 = supervisor password set (success)
Results log to X:\Windows\Config-LenovoBIOS.log during the WinPE phase for post-imaging review.
Part 2: Comprehensive BIOS Configuration Post-Deployment
Once the image is applied and the machine reboots into Windows, Part 2 handles the full BIOS configuration. But it helps to understand where this fits in the complete build first.
The Full Build Sequence
After SmartDeploy completes and the machine boots into Windows for the first time, the build isn't done. The full post-deployment sequence is:
SmartDeploy imaging complete → Windows first boot
↓
GPInstall runs automatically (via Group Policy)
└─ BIOS_Config_Lenovo\PREInstall.ps1 ← BIOS configuration
└─ Other application and settings scripts
↓
Lenovo System Update → latest drivers and firmware
↓
PDQ Deploy → remaining default packages pushed
↓
Machine ready
The BIOS configuration script (PREInstall.ps1) lives inside the GPInstall framework — a wrapper that orchestrates a collection of deployment scripts. BIOS configuration is one component. GPInstall also handles other applications, configurations, and settings as part of the full build. It runs as SYSTEM and can also be triggered manually via PDQ Deploy for existing machines or remediation.
What the BIOS Configuration Script Covers
Approximately 40 settings across the following areas:
Security — Virtualisation: VT-x, VT-d (IOMMU), Intel TXT
Security — TPM and Protection: SecurityChip, DataExecutionPrevention, KernelDMAProtection, SecureRollBackPrevention, EnhancedWindowsBiometricSecurity
Critical Business Requirements: - UserPresenceSensing → Disable (prevents machines sleeping when no presence is detected — problematic in a trading environment) - AMTControl → Enable (Intel AMT for out-of-band remote management) - AbsolutePersistenceModuleActivation → Disable (Computrace) - ReinstallWindowsFromCloud → Disable - LenovoCloudServices → Disable
Power Management: SpeedStep, CPUPowerManagement, AdaptiveThermalManagement profiles for AC and battery
Boot Behaviour: Quick boot mode, F12 boot menu, startup key options
Network: Wake on LAN, IPv4/IPv6 network stacks, PXE boot priority
Hardware Access: Camera, microphone, USB, WiFi, Bluetooth, Thunderbolt — all enabled by policy
Model-Aware Configuration
Testing across multiple ThinkPad variants uncovered a real problem: not all models have the same BIOS settings. The X9-15 Gen 1 is missing UserPresenceSensing and AMTControl entirely — they're simply not in that model's firmware. The P1 Gen 7 has both. The X1 Carbon Gen 13 has both plus WWAN options.
A script that blindly tries to configure non-existent settings will fail. The solution is to query what's available before attempting anything:
function Test-LenovoBiosSettingExists {
param([string]$SettingName)
$value = Get-LenovoBiosSetting -SettingName $SettingName
return ($null -ne $value)
}
function Set-LenovoBiosSetting {
param([string]$SettingName, [string]$Value, [string]$Password = "")
if (!(Test-LenovoBiosSettingExists -SettingName $SettingName)) {
Write-Log " [SKIP] $SettingName - Not available on this model"
return
}
$currentValue = Get-LenovoBiosSetting -SettingName $SettingName
if ($currentValue -eq $Value) {
Write-Log " [OK] $SettingName - Already set to $Value"
return
}
Write-Log " [CHANGE] $SettingName - Changing from '$currentValue' to '$Value'..."
# ... WMI calls to set and save
}
Every setting is checked for existence before any attempt to configure it. The log uses clear status indicators throughout — [OK], [SUCCESS], [SKIP], [CHANGE], [ERROR] — so you can assess any machine at a glance.
Password Migration for Existing Machines
Some machines in the fleet predate this process and carry different BIOS passwords. The script handles this with a migration array — it tests the current vault password first, and if that fails, works through known legacy passwords:
$oldPasswords = @("LegacyPassword1", "LegacyPassword2")
foreach ($oldPwd in $oldPasswords) {
$migrateResult = $setPassword.SetBiosPassword("pap,$oldPwd,$newPassword,ascii,us")
if ($migrateResult.Return -eq "Success") { break }
}
Exit Codes That Actually Tell You Something
Generic failures waste time. Every exit code maps to a specific scenario with step-by-step remediation written into the log:
| Exit Code | Meaning | What to Do |
|---|---|---|
| 0 | Success | Nothing |
| 1 | No password set | Re-image with SDBM (F12 > DELETE) |
| 2 | Password mismatch | Add legacy password to migration array |
| 3 | Vault file missing | Deploy GPInstall vault |
| 4 | WMI error | Check PowerShell version or WMI service |
These exit codes bubble up into GPInstall and PDQ logs, so failures are immediately visible in existing deployment monitoring.
Multi-Site Reality
One hard requirement was that the same process had to work identically across all sites — US, London, Dubai, Asia — with zero site-specific configuration.
DFS replication handles this cleanly. Scripts and images live on the primary server and replicate to each site automatically. All sites use the same UNC namespace and DFS redirects each site to its local replica transparently. A London technician imaging a machine accesses local copies of everything. So does a US technician, or one in Dubai. Zero cross-site traffic during the imaging process.
One Answer File, one set of scripts, every site.
The Complete Workflow
New machine — end to end:
Technician: Press F12 → DELETE (5 seconds, activates SDBM)
↓
SmartDeploy: wpeinit → network initialises → image applies
↓
POSTIMAGE: Config-LenovoBIOS.ps1 sets initial supervisor password
↓
Windows first boot → Sysprep specialisation → domain join
↓
GPInstall: Runs automatically via GPO
├─ BIOS_Config_Lenovo\PREInstall.ps1 (40+ BIOS settings)
└─ Other app and settings scripts
↓
Lenovo System Update: Latest drivers and firmware
↓
PDQ Deploy: Remaining default packages pushed
↓
Machine ready
Re-image of existing machine:
Technician: Press F12 → PXE (no DELETE needed, password already set)
↓
Everything else identical — POSTIMAGE script detects existing password, skips
Total manual intervention on a new machine: Five seconds.
Security Considerations
- SDBM automatically deactivates after reboot — it cannot be left in an insecure state
- Scripts run under SYSTEM context — restrict access to deployment share accordingly
- Supervisor password is required for all post-deployment BIOS changes
- Password vault is stored separately from deployment scripts with restricted NTFS permissions
- Supervisor password is passed from vault at runtime — never hardcoded in the script itself
- Logs do not expose plaintext passwords
Key Lessons
1. Check vendor CDRT documentation, not just general support docs. Lenovo's 2012 WMI guide is foundational but outdated. The real answers for enterprise deployment are at docs.lenovocdrt.com. SDBM exists specifically to solve this problem — it just takes some digging to find it.
2. Always query available settings before configuring them. ThinkPad models vary significantly across generations. The X9-15 Gen 1 is missing settings that the P1 Gen 7 has. Query first, configure second, never assume a setting exists.
3. PowerShell 5.1, not 7. powershell.exe always. pwsh.exe never. Explicitly call powershell.exe in every automated context — GPO, PDQ, SmartDeploy tasks — regardless of your default shell setting.
4. wpeinit is non-negotiable in WinPE. WinPE doesn't initialise the network stack automatically. Run wpeinit, wait 60 seconds, then proceed. Without this, any UNC path access will fail silently and you'll spend time debugging the wrong thing.
5. Separate your concerns. Initial password setup and comprehensive BIOS configuration are two different problems requiring two different approaches. Don't try to solve both in one script at one phase. Phase 1 in WinPE for the password, Phase 2 in Windows for the full configuration.
6. Make your error messages actionable. "Failed" is useless. "Failed: No BIOS password set — re-image with SDBM (F12 > DELETE during PXE boot)" tells a technician exactly what to do. Good error handling pays for itself every time something goes wrong at 7am before markets open.
Resources
- Lenovo SDBM Documentation: docs.lenovocdrt.com/ref/bios/sdbm
- imabdk's Config-LenovoBIOS.ps1: github.com/imabdk/Lenovo-BIOS-Configurator
- imabdk's Blog Post: imab.dk — Configure Lenovo BIOS Supervisor Password during OSD (OS Deployment)
- ConfigJon's Firmware Management: github.com/ConfigJon/Firmware-Management
- SmartDeploy Answer File Tasks: smartdeploy.pdq.com
Scripts available on GitHub — [link to follow once repo is live]
If it can be optimised, it will be — averagejoeuk.com.