public/Get-ComputerInfo.ps1
function Get-ComputerInfo { <# .SYNOPSIS Gathers detailed system information from a Linux system. .DESCRIPTION Collects and returns comprehensive system information including: - BIOS details (date, vendor, version) - CPU information (model, architecture, threads, cores, sockets) - Distribution details (name, version, support URL) - System disk metrics (total, free, used space in GB) - Graphics card information - Memory information - Kernel and OS details - System information (manufacturer, product name, version, serial) The function uses various Linux system commands and files: - lscpu: CPU information - uname: System and kernel information - lspci: Graphics card details - lsmem: Memory information - /etc/os-release: Distribution details - /sys/class/dmi/id/*: BIOS information (non-WSL) - WMI queries: BIOS information (WSL) - dmidecode: System information (requires sudo) .OUTPUTS PSCustomObject with the following properties: - BiosDate: DateTime of BIOS release - BiosVendor: Manufacturer of BIOS - BiosVersion: BIOS version string - CPU: Processor model name - CPUArchitecture: Processor architecture - CPUThreads: Total number of CPU threads - CPUCores: Total number of CPU cores - CPUSockets: Number of CPU sockets - DistName: Linux distribution name - DistSupportURL: Distribution's support URL - SystemDiskSize: Total system disk size - SystemDiskFree: Available disk space - SystemDiskUsed: Used disk space - GPU: Graphics card information - DistVersion: Distribution version - KernelRelease: Linux kernel version - OS: Operating system name - RAM: Total system memory - Manufacturer: System manufacturer - ProductName: System product name - SystemVersion: System version - SerialNumber: System serial number .NOTES Author: Emil Larsson Date: 2023-03-27 The script handles both native Linux and Windows Subsystem for Linux (WSL) environments, using different methods to gather BIOS information in each case. .EXAMPLE Get-ComputerInfo Returns a detailed object containing system information. #> [CmdletBinding()] param ( ) # Verifies required binary if (-not (Resolve-BinDep -Bins "lscpu", "awk", "lspci", "grep", "lsmem", "uname")) { return } $script:CPUData = lscpu | awk '/^Model name:/ || /^Socket\(s\):/ || /^Core\(s\) per socket:/ || /^Thread\(s\) per core:/ {print $0}' | Sort-Object $script:OSData = (Get-Content /etc/os-release) | Select-String -Pattern '(?<=NAME=|VERSION=|PRETTY_NAME=|HOME_URL=|SUPPORT_END=)[^,\n]+' -Raw # DisplayData $DisplayData = (lspci | grep -i vga) -split ":" | Select-Object -Last 1 if ($DisplayData -like " *") { $DisplayData = $DisplayData.TrimStart(" ") } # Ram $RAM = (lsmem | Select-String 'Total online memory:' -Raw ).Split(': ')[1] if ($RAM -like "* *") { $RAM = $RAM.Replace(" ", "") } # Convert RAM to rounded GB if it ends with 'G' if ($RAM -match '(\d+\.?\d*)G$') { $ramValue = [decimal]$Matches[1] $RAM = "{0}GB" -f [Math]::Ceiling($ramValue) } # CPU Regex $CorePerSocket = $CPUData[0].Substring($CPUData[0].Length - 2) if ($CorePerSocket -like "* *") { $CorePerSocket = $CorePerSocket.Trim(" ") } $Sockets = $CPUData[2].Substring($CPUData[2].Length - 2) if ($Sockets -like "* *") { $Sockets = $Sockets.Trim(" ") } $ThreadsPerCore = $CPUData[3].Substring($CPUData[3].Length - 2) if ($ThreadsPerCore -like "* *") { $ThreadsPerCore = $ThreadsPerCore.Trim(" ") } # Get CPU architecture with fallbacks if uname -p returns unknown $CPUArc = uname -p if ((-not $CPUArc) -or ($CPUArc -eq 'unknown')) { # Try uname -m as first fallback $CPUArc = uname -m if ((-not $CPUArc) -or ($CPUArc -eq 'unknown')) { # Try lscpu as second fallback $CPUArc = (lscpu | Select-String -Pattern '^Architecture:').ToString().Split(':')[1].Trim() if ((-not $CPUArc) -or ($CPUArc -eq 'unknown')) { $CPUArc = "Unknown" } } } # Make CPU Thread count more robust, if parser failed, output unknown instead of error try { $CPUThreads = ([int]$ThreadsPerCore * [int]$CorePerSocket) } catch { $CPUThreads = 'Unknown' } try { $CPUCores = ([int]$CorePerSocket * [int]$Sockets) } catch { $CPUCores = 'Unknown' } # Dist Name & version $regex = '"([^"]*)"' $DistName = ([regex]::Match($OSData[0], $regex)).Value $DistNameData = $script:OSData | Where-Object { $_ -like "VERSION=*" } $DistVersion = ([regex]::Match($DistNameData, $regex)).Value # Debug disk values $diskInfo = Get-PSDrive -Name "/" Write-Verbose "Raw disk values:" Write-Verbose ("Used bytes: {0}" -f $diskInfo.Used) Write-Verbose ("Used GB raw: {0}" -f ($diskInfo.Used/1GB)) # Fix disk display: $DiskSizeNice = "{0:N2}GB" -f (((Get-PSDrive -Name "/").Used + (Get-PSDrive -Name "/").Free) / 1GB) $DiskFreeNice = "{0:N2}GB" -f ((Get-PSDrive -Name "/").Free / 1GB) $DiskUsedNice = "{0:N2}GB" -f ((Get-PSDrive -Name "/").Used / 1GB) # Get BIOS information directly from DMI $BiosDate = Get-Content "/sys/class/dmi/id/bios_date" $BiosVendor = Get-Content "/sys/class/dmi/id/bios_vendor" $BiosVersion = Get-Content "/sys/class/dmi/id/bios_version" if ($CPUData[1].Replace(" ", "").Split(":")[1] -like " *") { $CPUData = $CPUData[1].Replace(" ", "").Split(":")[1].TrimStart(" ") } else { $CPUData = $CPUData[1].Replace(" ", "").Split(":")[1] } # Get system information using dmidecode $SystemInfo = @{ Manufacturer = "Unknown" ProductName = "Unknown" Version = "Unknown" SerialNumber = "Unknown" } try { # Check if sudo is available if (Get-Command sudo -ErrorAction SilentlyContinue) { Write-Verbose "Attempting to get system information using dmidecode" $DmiOutput = sudo dmidecode -t system 2>$null if ($DmiOutput) { $SystemInfo.Manufacturer = ($DmiOutput | Select-String "Manufacturer:" -Raw).Split(":")[1].Trim() $SystemInfo.ProductName = ($DmiOutput | Select-String "Product Name:" -Raw).Split(":")[1].Trim() $SystemInfo.Version = ($DmiOutput | Select-String "Version:" -Raw).Split(":")[1].Trim() $SystemInfo.SerialNumber = ($DmiOutput | Select-String "Serial Number:" -Raw).Split(":")[1].Trim() } } else { Write-Verbose "sudo not available - system information will be limited" } } catch { Write-Verbose "Unable to get system information using dmidecode: $_" } # Modify the return object to include system information $Return = [PSCustomObject][ordered]@{ BiosDate = [DateTime]$BiosDate BiosVendor = $BiosVendor BiosVersion = $BiosVersion CPU = $CPUData CPUArchitecture = $CPUArc CPUThreads = $CPUThreads CPUCores = $CPUCores CPUSockets = $Sockets DistName = $DistName.Replace('"', '') DistSupportURL = ($OSData | Where-Object { $_ -like "HOME_URL=*" }).TrimStart("HOME_URL=").Trim('"') SystemDiskSize = $DiskSizeNice SystemDiskFree = $DiskFreeNice SystemDiskUsed = $DiskUsedNice GPU = $DisplayData DistVersion = $DistVersion.Replace('"', '') KernelRelease = uname -r OS = uname -o RAM = $RAM Manufacturer = $SystemInfo.Manufacturer ProductName = $SystemInfo.ProductName SystemVersion = $SystemInfo.Version SerialNumber = $SystemInfo.SerialNumber } # Display results to user $Return } |