Skip to content

Instantly share code, notes, and snippets.

@jsmcnair
Created September 24, 2025 18:25
Show Gist options
  • Select an option

  • Save jsmcnair/17008cf1a294b3d7006a637ba6a74ec0 to your computer and use it in GitHub Desktop.

Select an option

Save jsmcnair/17008cf1a294b3d7006a637ba6a74ec0 to your computer and use it in GitHub Desktop.
smbios-extractor.sh
#!/bin/bash
# SMBIOS Information Extractor for libvirt
# This script extracts SMBIOS information from the current system
# and outputs it in formats suitable for libvirt configuration
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_section() {
echo -e "${BLUE}=== $1 ===${NC}"
}
print_info() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}WARNING: $1${NC}"
}
print_error() {
echo -e "${RED}ERROR: $1${NC}"
}
# Check if running as root (required for dmidecode)
check_root() {
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root to access DMI information"
echo "Please run: sudo $0"
exit 1
fi
}
# Check if dmidecode is available
check_dmidecode() {
if ! command -v dmidecode &> /dev/null; then
print_error "dmidecode is not installed"
echo "Install it with:"
echo " Ubuntu/Debian: apt-get install dmidecode"
echo " RHEL/CentOS/Fedora: yum install dmidecode"
exit 1
fi
}
# Get DMI information safely
get_dmi_info() {
local type="$1"
local field="$2"
dmidecode -s "$type-$field" 2>/dev/null | head -n1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' || echo "Unknown"
}
# Generate UUID if system UUID is not available
generate_uuid() {
if command -v uuidgen &> /dev/null; then
uuidgen
else
# Fallback UUID generation
cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "12345678-1234-1234-1234-123456789012"
fi
}
# Extract SMBIOS information
extract_smbios() {
print_section "Extracting SMBIOS Information"
# BIOS Information (Type 0)
BIOS_VENDOR=$(get_dmi_info "bios" "vendor")
BIOS_VERSION=$(get_dmi_info "bios" "version")
BIOS_DATE=$(get_dmi_info "bios" "release-date")
# System Information (Type 1)
SYSTEM_MANUFACTURER=$(get_dmi_info "system" "manufacturer")
SYSTEM_PRODUCT=$(get_dmi_info "system" "product-name")
SYSTEM_VERSION=$(get_dmi_info "system" "version")
SYSTEM_SERIAL=$(get_dmi_info "system" "serial-number")
SYSTEM_UUID=$(get_dmi_info "system" "uuid")
SYSTEM_SKU=$(get_dmi_info "system" "sku-number")
SYSTEM_FAMILY=$(get_dmi_info "system" "family")
# Base Board Information (Type 2)
BOARD_MANUFACTURER=$(get_dmi_info "baseboard" "manufacturer")
BOARD_PRODUCT=$(get_dmi_info "baseboard" "product-name")
BOARD_VERSION=$(get_dmi_info "baseboard" "version")
BOARD_SERIAL=$(get_dmi_info "baseboard" "serial-number")
BOARD_ASSET=$(get_dmi_info "baseboard" "asset-tag")
# Chassis Information (Type 3)
CHASSIS_MANUFACTURER=$(get_dmi_info "chassis" "manufacturer")
CHASSIS_VERSION=$(get_dmi_info "chassis" "version")
CHASSIS_SERIAL=$(get_dmi_info "chassis" "serial-number")
CHASSIS_ASSET=$(get_dmi_info "chassis" "asset-tag")
CHASSIS_TYPE=$(get_dmi_info "chassis" "type")
# Handle empty or invalid UUID
if [[ "$SYSTEM_UUID" == "Unknown" ]] || [[ -z "$SYSTEM_UUID" ]] || [[ "$SYSTEM_UUID" =~ ^[0-]+$ ]]; then
SYSTEM_UUID=$(generate_uuid)
print_warning "System UUID was invalid, generated new one: $SYSTEM_UUID"
fi
}
# Output raw information
output_raw() {
print_section "Raw SMBIOS Information"
echo "BIOS Information:"
echo " Vendor: $BIOS_VENDOR"
echo " Version: $BIOS_VERSION"
echo " Date: $BIOS_DATE"
echo
echo "System Information:"
echo " Manufacturer: $SYSTEM_MANUFACTURER"
echo " Product: $SYSTEM_PRODUCT"
echo " Version: $SYSTEM_VERSION"
echo " Serial: $SYSTEM_SERIAL"
echo " UUID: $SYSTEM_UUID"
echo " SKU: $SYSTEM_SKU"
echo " Family: $SYSTEM_FAMILY"
echo
echo "Base Board Information:"
echo " Manufacturer: $BOARD_MANUFACTURER"
echo " Product: $BOARD_PRODUCT"
echo " Version: $BOARD_VERSION"
echo " Serial: $BOARD_SERIAL"
echo " Asset Tag: $BOARD_ASSET"
echo
echo "Chassis Information:"
echo " Manufacturer: $CHASSIS_MANUFACTURER"
echo " Version: $CHASSIS_VERSION"
echo " Serial: $CHASSIS_SERIAL"
echo " Asset Tag: $CHASSIS_ASSET"
echo " Type: $CHASSIS_TYPE"
echo
}
# Output libvirt XML format
output_libvirt_xml() {
print_section "Libvirt XML Configuration"
cat << EOF
<!-- Add this to your libvirt domain XML -->
<sysinfo type='smbios'>
<bios>
<entry name='vendor'>$BIOS_VENDOR</entry>
<entry name='version'>$BIOS_VERSION</entry>
<entry name='date'>$BIOS_DATE</entry>
</bios>
<system>
<entry name='manufacturer'>$SYSTEM_MANUFACTURER</entry>
<entry name='product'>$SYSTEM_PRODUCT</entry>
<entry name='version'>$SYSTEM_VERSION</entry>
<entry name='serial'>$SYSTEM_SERIAL</entry>
<entry name='uuid'>$SYSTEM_UUID</entry>
<entry name='sku'>$SYSTEM_SKU</entry>
<entry name='family'>$SYSTEM_FAMILY</entry>
</system>
<baseBoard>
<entry name='manufacturer'>$BOARD_MANUFACTURER</entry>
<entry name='product'>$BOARD_PRODUCT</entry>
<entry name='version'>$BOARD_VERSION</entry>
<entry name='serial'>$BOARD_SERIAL</entry>
<entry name='asset'>$BOARD_ASSET</entry>
</baseBoard>
<chassis>
<entry name='manufacturer'>$CHASSIS_MANUFACTURER</entry>
<entry name='version'>$CHASSIS_VERSION</entry>
<entry name='serial'>$CHASSIS_SERIAL</entry>
<entry name='asset'>$CHASSIS_ASSET</entry>
</chassis>
</sysinfo>
<!-- Don't forget to add this to the <os> section: -->
<!-- <smbios mode='sysinfo'/> -->
EOF
}
# Output QEMU command line format
output_qemu_args() {
print_section "QEMU Command Line Arguments"
cat << EOF
<!-- Add these to your libvirt domain XML in qemu:commandline -->
<qemu:commandline>
<qemu:arg value='-smbios'/>
<qemu:arg value='type=0,vendor=$BIOS_VENDOR,version=$BIOS_VERSION,date=$BIOS_DATE'/>
<qemu:arg value='-smbios'/>
<qemu:arg value='type=1,manufacturer=$SYSTEM_MANUFACTURER,product=$SYSTEM_PRODUCT,version=$SYSTEM_VERSION,serial=$SYSTEM_SERIAL,uuid=$SYSTEM_UUID,sku=$SYSTEM_SKU,family=$SYSTEM_FAMILY'/>
<qemu:arg value='-smbios'/>
<qemu:arg value='type=2,manufacturer=$BOARD_MANUFACTURER,product=$BOARD_PRODUCT,version=$BOARD_VERSION,serial=$BOARD_SERIAL,asset=$BOARD_ASSET'/>
<qemu:arg value='-smbios'/>
<qemu:arg value='type=3,manufacturer=$CHASSIS_MANUFACTURER,version=$CHASSIS_VERSION,serial=$CHASSIS_SERIAL,asset=$CHASSIS_ASSET'/>
</qemu:commandline>
EOF
}
# Output JSON format
output_json() {
print_section "JSON Format"
cat << EOF
{
"smbios": {
"bios": {
"vendor": "$BIOS_VENDOR",
"version": "$BIOS_VERSION",
"date": "$BIOS_DATE"
},
"system": {
"manufacturer": "$SYSTEM_MANUFACTURER",
"product": "$SYSTEM_PRODUCT",
"version": "$SYSTEM_VERSION",
"serial": "$SYSTEM_SERIAL",
"uuid": "$SYSTEM_UUID",
"sku": "$SYSTEM_SKU",
"family": "$SYSTEM_FAMILY"
},
"baseboard": {
"manufacturer": "$BOARD_MANUFACTURER",
"product": "$BOARD_PRODUCT",
"version": "$BOARD_VERSION",
"serial": "$BOARD_SERIAL",
"asset": "$BOARD_ASSET"
},
"chassis": {
"manufacturer": "$CHASSIS_MANUFACTURER",
"version": "$CHASSIS_VERSION",
"serial": "$CHASSIS_SERIAL",
"asset": "$CHASSIS_ASSET",
"type": "$CHASSIS_TYPE"
}
}
}
EOF
}
# Main function
main() {
local output_format="all"
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-f|--format)
output_format="$2"
shift 2
;;
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -f, --format FORMAT Output format: all, raw, xml, qemu, json"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " $0 # Show all formats"
echo " $0 -f xml # Show only libvirt XML format"
echo " $0 -f json # Show only JSON format"
exit 0
;;
*)
print_error "Unknown option: $1"
echo "Use -h or --help for usage information"
exit 1
;;
esac
done
check_root
check_dmidecode
extract_smbios
case "$output_format" in
"all")
output_raw
echo
output_libvirt_xml
echo
output_qemu_args
echo
output_json
;;
"raw")
output_raw
;;
"xml")
output_libvirt_xml
;;
"qemu")
output_qemu_args
;;
"json")
output_json
;;
*)
print_error "Invalid format: $output_format"
echo "Valid formats: all, raw, xml, qemu, json"
exit 1
;;
esac
}
# Run main function with all arguments
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment