Skip to main content

How to Get the System Asset Tag in Batch Script

The asset tag is a string embedded in the system's BIOS or UEFI firmware by the manufacturer or the IT department. It is used for hardware inventory tracking, procurement records, and identifying machines within a fleet. Unlike the serial number (which is assigned by the hardware manufacturer at the factory), the asset tag can often be set or customized by the organization that purchased the equipment.

In this guide, we will explore how to retrieve the system asset tag using Batch Script via WMI queries.

What is an Asset Tag?

An asset tag is a label, either physical (a barcode sticker) or digital (embedded in firmware), that uniquely maps a computer to an entry in the organization's IT Asset Management (ITAM) database. Examples include:

  • ASSET-PC-00421
  • NYC-FLOOR3-WS007
  • FIN-LAPTOP-0089

On many enterprise-class machines (Dell, HP, Lenovo), the asset tag can be written into the BIOS through vendor-specific tools. Windows then exposes it via WMI, making it accessible from scripts.

Method 1: Using WMIC

The asset tag is stored in the Win32_SystemEnclosure WMI class under the SMBIOSAssetTag property.

@echo off
setlocal enabledelayedexpansion

echo Retrieving System Asset Tag...

set "asset_tag="
for /f "tokens=2 delims==" %%A in ('wmic systemenclosure get SMBIOSAssetTag /value 2^>nul ^| find "="') do set "asset_tag=%%A"

:: Check for empty, undefined, or common placeholder values
if not defined asset_tag goto :no_tag
if "!asset_tag!"=="" goto :no_tag
if /i "!asset_tag!"=="No Asset Tag" goto :no_tag
if /i "!asset_tag!"=="No Asset Information" goto :no_tag
if /i "!asset_tag!"=="Default string" goto :no_tag
if /i "!asset_tag!"=="To Be Filled By O.E.M." goto :no_tag

echo Asset Tag: !asset_tag!
goto :end

:no_tag
echo [INFO] Asset tag is not configured on this hardware.
if defined asset_tag echo Raw value: "!asset_tag!"

:end
pause
warning

The wmic command-line utility is deprecated as of Windows 10 version 21H1 and may be removed in future Windows releases. While it remains functional on current systems, consider using the PowerShell alternative in Method 4 for forward compatibility.

Understanding Empty Results

On consumer-grade machines (home laptops, custom-built desktops), the asset tag field is almost always empty or contains a placeholder like No Asset Tag, Default string, or To Be Filled By O.E.M.. This is normal. The field is only meaningful on enterprise machines where the IT department has configured it.

tip

WMIC outputs UTF-16 text that retains trailing carriage return (\r) characters when piped through find. The asset_tag variable may contain an invisible \r at the end, which causes exact string comparisons with == to fail for values you might expect to match. Using /i for case-insensitive matching and findstr for partial matching (as shown in later examples) helps work around this. For definitive validation, the PowerShell approach in Method 4 produces clean output without trailing characters.

Method 2: Comprehensive Hardware Identification Report

For inventory scripts, the asset tag is most useful when combined with other identifying information.

@echo off
setlocal enabledelayedexpansion

echo =============================================
echo HARDWARE IDENTIFICATION REPORT
echo =============================================
echo.

:: Helper: strip trailing carriage return (CR) from a variable
:: Usage: call :strip_cr variable_name
goto :main
:strip_cr
if not defined %1 goto :eof
set "tmp=!%1!"
:: Remove the last character if it is a CR (ASCII 13)
if "!tmp:~-1!"==" " (set "%1=!tmp:~0,-1!") else set "%1=!tmp!"
goto :eof
:main

:: Asset Tag
set "asset="
for /f "tokens=2 delims==" %%A in ('wmic systemenclosure get SMBIOSAssetTag /value 2^>nul ^| find "="') do set "asset=%%A"
call :strip_cr asset

:: Serial Number
set "serial="
for /f "tokens=2 delims==" %%A in ('wmic bios get SerialNumber /value 2^>nul ^| find "="') do set "serial=%%A"
call :strip_cr serial

:: Manufacturer
set "mfr="
for /f "tokens=2 delims==" %%A in ('wmic computersystem get Manufacturer /value 2^>nul ^| find "="') do set "mfr=%%A"
call :strip_cr mfr

:: Model
set "model="
for /f "tokens=2 delims==" %%A in ('wmic computersystem get Model /value 2^>nul ^| find "="') do set "model=%%A"
call :strip_cr model

:: Computer Name
set "hostname=%COMPUTERNAME%"

:: Chassis Type – extract only the numeric code (clean, no braces or CR)
set "chassis_num="
for /f "tokens=2 delims=={}" %%A in ('wmic systemenclosure get ChassisTypes /value 2^>nul ^| find "="') do set "chassis_num=%%A"
call :strip_cr chassis_num

:: Map numeric code to readable name
set "chassis=Unknown"
if "!chassis_num!"=="1" set "chassis=Other"
if "!chassis_num!"=="2" set "chassis=Unknown"
if "!chassis_num!"=="3" set "chassis=Desktop"
if "!chassis_num!"=="4" set "chassis=Low Profile Desktop"
if "!chassis_num!"=="6" set "chassis=Mini Tower"
if "!chassis_num!"=="7" set "chassis=Tower"
if "!chassis_num!"=="8" set "chassis=Portable"
if "!chassis_num!"=="9" set "chassis=Laptop"
if "!chassis_num!"=="10" set "chassis=Notebook"
if "!chassis_num!"=="14" set "chassis=Sub Notebook"
if "!chassis_num!"=="30" set "chassis=Tablet"
if "!chassis_num!"=="31" set "chassis=Convertible"
if "!chassis_num!"=="32" set "chassis=Detachable"
if "!chassis_num!"=="35" set "chassis=Mini PC"
if "!chassis_num!"=="36" set "chassis=Stick PC"

:: Display results (replace empty values with "Not Available")
echo Computer Name: !hostname!
if "!mfr!"=="" (echo Manufacturer: Not Available) else echo Manufacturer: !mfr!
if "!model!"=="" (echo Model: Not Available) else echo Model: !model!
if "!serial!"=="" (echo Serial Number: Not Available) else echo Serial Number: !serial!
if "!asset!"=="" (echo Asset Tag: Not Available) else echo Asset Tag: !asset!
if "!chassis_num!"=="" (echo Chassis Type: Unknown) else echo Chassis Type: !chassis! (code !chassis_num!)

echo.
pause
info

The ChassisTypes property returns a SAFEARRAY formatted as {N} (e.g., {9} for Laptop). Some systems return multiple values like {9,10} for multi-chassis configurations, though this is rare. The findstr /c:"{N}" approach used above performs substring matching, so {3} will not falsely match {30} because the closing brace is part of the search pattern. However, {3} used alone would match {3,10} - a rare multi-chassis edge case.

Method 3: Exporting to a CSV File

For fleet-wide audits, you can run this script on every machine via a login script or remote execution tool and collect the results centrally.

@echo off
setlocal enabledelayedexpansion

:: Define the output file (shared network path or local)
set "output_dir=\\SERVER\ITShared\Inventory"
set "output_file=%output_dir%\asset_inventory.csv"

:: Gather data
set "asset="
set "serial="
set "mfr="
set "model="

for /f "tokens=2 delims==" %%A in ('wmic systemenclosure get SMBIOSAssetTag /value 2^>nul ^| find "="') do set "asset=%%A"
for /f "tokens=2 delims==" %%A in ('wmic bios get SerialNumber /value 2^>nul ^| find "="') do set "serial=%%A"
for /f "tokens=2 delims==" %%A in ('wmic computersystem get Manufacturer /value 2^>nul ^| find "="') do set "mfr=%%A"
for /f "tokens=2 delims==" %%A in ('wmic computersystem get Model /value 2^>nul ^| find "="') do set "model=%%A"

:: Sanitize values: replace commas with semicolons to prevent CSV column misalignment
set "asset=!asset:,=;!"
set "serial=!serial:,=;!"
set "mfr=!mfr:,=;!"
set "model=!model:,=;!"

:: Verify the output directory is reachable
if not exist "%output_dir%\" (
echo [ERROR] Cannot reach output directory: %output_dir%
echo Check network connectivity and share permissions.
pause
exit /b 1
)

:: Write CSV header if file does not exist yet
if not exist "%output_file%" (
echo ComputerName,Manufacturer,Model,SerialNumber,AssetTag,Timestamp> "%output_file%"
)

:: Get current date/time for the timestamp
set "timestamp=%DATE% %TIME:~0,8%"

:: Append this machine's data
>> "%output_file%" echo %COMPUTERNAME%,!mfr!,!model!,!serial!,!asset!,!timestamp!

echo [OK] Inventory data exported to %output_file%.
warning

When multiple machines write to the same CSV file simultaneously (e.g., during mass login events), file locking conflicts can cause data loss. For large-scale deployments, consider writing to per-machine files (%COMPUTERNAME%.csv) and consolidating them with a separate aggregation script, or use a database endpoint instead of a flat file.

Method 4: PowerShell Alternative

For modern environments where wmic is being phased out:

@echo off
setlocal enabledelayedexpansion

echo Retrieving Asset Tag via PowerShell...

set "asset="
for /f "delims=" %%A in ('powershell -NoProfile -Command "(Get-CimInstance Win32_SystemEnclosure).SMBIOSAssetTag -replace '^\s+|\s+$'" 2^>nul') do set "asset=%%A"

:: Validate for placeholders
set "valid=1"
if not defined asset set "valid=0"
if "!asset!"=="" set "valid=0"
if /i "!asset!"=="No Asset Tag" set "valid=0"
if /i "!asset!"=="No Asset Information" set "valid=0"
if /i "!asset!"=="Default string" set "valid=0"
if /i "!asset!"=="To Be Filled By O.E.M." set "valid=0"

if "!valid!"=="1" (
echo Asset Tag: !asset!
) else (
echo [INFO] Asset tag is not configured on this hardware.
)

pause
info

The PowerShell approach has two advantages over WMIC: (1) Get-CimInstance is the supported, non-deprecated replacement for wmic.exe, and (2) the .Trim() call removes trailing carriage return and whitespace characters that WMIC leaves in parsed values, eliminating the invisible \r issue that causes string comparisons to fail in Batch.

Setting the Asset Tag (Vendor-Specific)

While reading the asset tag is universal via WMI, setting the asset tag requires vendor-specific tools because it is written directly into the BIOS/UEFI firmware.

ManufacturerToolCommand Example
DellDell Command Configure (cctk.exe)cctk --asset=MYASSET123
HPHP BIOS Configuration Utility (BiosConfigUtility64.exe)Config file with Asset Tracking Number
LenovoLenovo BIOS WMI InterfacePowerShell via Lenovo_SetBiosSetting

For example:

:: Example: Setting asset tag on a Dell machine
@echo off

:: Verify Admin Rights
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)

set "new_tag=NYC-WS-00421"
set "cctk_path=C:\Program Files\Dell\Command Configure\cctk.exe"

if not exist "%cctk_path%" (
echo [ERROR] Dell Command Configure not found at:
echo %cctk_path%
echo Install it from Dell support before running this script.
pause
exit /b 1
)

echo Setting Dell Asset Tag to "%new_tag%"...
"%cctk_path%" --asset=%new_tag%

if %errorlevel% equ 0 (
echo [OK] Asset tag updated. A reboot is required for the change
echo to be reflected in WMI queries.
) else (
echo [ERROR] Failed to set asset tag. Error code: %errorlevel%
echo A BIOS admin password may be required.
)

pause
warning

Setting the BIOS asset tag typically requires a reboot for the new value to be reflected in WMI queries. Some vendors also require a BIOS admin password to be provided alongside the command. Always verify the change after reboot by querying the asset tag again.

Common Mistakes

The Wrong Way: Expecting All Machines to Have Asset Tags

:: WRONG - Assumes the asset tag is always populated with a real value
for /f "tokens=2 delims==" %%A in ('wmic systemenclosure get SMBIOSAssetTag /value ^| find "="') do set "asset=%%A"
echo Asset: %asset%
if "%asset%"=="" echo ERROR: No tag found!
danger

On consumer machines, the variable may contain No Asset Tag, Default string, or To Be Filled By O.E.M. instead of being truly empty. The if "%asset%"=="" check passes (no error reported), but the displayed "asset tag" is a meaningless placeholder. Your validation logic must check for these known placeholder strings as well as empty values. Additionally, WMIC's trailing \r character means even a truly empty field may not match "" in a string comparison.

The Correct Way: Validate for Known Placeholders

set "valid=1"
if not defined asset set "valid=0"
if /i "!asset!"=="" set "valid=0"
if /i "!asset!"=="No Asset Tag" set "valid=0"
if /i "!asset!"=="No Asset Information" set "valid=0"
if /i "!asset!"=="Default string" set "valid=0"
if /i "!asset!"=="To Be Filled By O.E.M." set "valid=0"

if "!valid!"=="1" (
echo Valid Asset Tag: !asset!
) else (
echo [WARNING] Asset tag is not configured on this machine.
)

The Wrong Way: Writing CSV Data Without Sanitizing

:: WRONG - If any value contains a comma, CSV columns shift
echo %COMPUTERNAME%,%mfr%,%model%,%serial%,%asset% >> inventory.csv
warning

Some manufacturer or model strings can contain commas (e.g., VMware, Inc.). Writing these values directly into a comma-delimited CSV without sanitization causes column misalignment. Either replace commas in the values before writing (as shown in Method 3), or wrap each field in double quotes.

Best Practices

  1. Use wmic systemenclosure for the asset tag: The SMBIOSAssetTag property is the standard location across all manufacturers.
  2. Validate for placeholder strings: Many machines ship with generic placeholder text instead of a blank field. Check for No Asset Tag, Default string, To Be Filled By O.E.M., and other known placeholders.
  3. Combine with Serial and Model: An asset tag alone is rarely sufficient for inventory. Always capture the serial number, model, and computer name alongside it.
  4. Export to a central location: Use network shares or database inserts to aggregate inventory data from login scripts running across the fleet.
  5. Initialize variables before WMIC parsing: Always set "var=" before a for /f loop that parses WMIC output to prevent stale values from previous runs or the existing environment.
  6. Add 2>nul to WMIC commands: Redirect stderr on all wmic invocations to prevent error messages from corrupting for /f parsing, especially on systems where WMIC has been removed.
  7. Sanitize values before CSV export: Replace or escape commas in WMIC-retrieved values before writing them to comma-delimited files to prevent column misalignment.
  8. Transition to PowerShell: As wmic enters deprecation, use Get-CimInstance Win32_SystemEnclosure with .Trim() for clean, reliable output without trailing carriage return characters.

Conclusion

Retrieving the system asset tag in Batch Script is a straightforward WMI query against the Win32_SystemEnclosure class. While the data is only meaningful on enterprise machines where IT departments have configured the BIOS-level tag, it serves as a critical piece of the hardware inventory puzzle. By combining the asset tag with serial numbers, manufacturer details, and chassis types, administrators can build comprehensive, automated inventory reports that keep their asset management databases accurate and current.