Created
September 24, 2025 18:25
-
-
Save jsmcnair/17008cf1a294b3d7006a637ba6a74ec0 to your computer and use it in GitHub Desktop.
smbios-extractor.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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