Public/02_System_Hardware/Get-VBSystemInfo.ps1
|
# ============================================================ # FUNCTION : Get-VBSystemInfo # VERSION : 1.0.3 # CHANGED : 16-04-2026 -- Added native API firmware type detection # AUTHOR : Vibhu Bhatnagar # PURPOSE : Retrieves comprehensive system information from local or remote computers # ENCODING : UTF-8 with BOM # ============================================================ <# .SYNOPSIS Retrieves comprehensive system information from local or remote computers. .DESCRIPTION The Get-VBSystemInfo function collects detailed system information including OS details, hardware specifications, network configuration, domain information, and BIOS/firmware type. It supports both local and remote computer queries with pipeline input and credential authentication. Uses native Windows API for accurate BIOS/firmware type detection (UEFI vs Legacy). .PARAMETER ComputerName Target computer(s). Defaults to local machine. Accepts pipeline input. Aliases: Name, Server, Host .PARAMETER Credential Alternate credentials for remote execution. .EXAMPLE Get-VBSystemInfo Retrieves system information from the local computer. .EXAMPLE Get-VBSystemInfo -ComputerName "SERVER01", "SERVER02" Retrieves system information from multiple remote servers. .EXAMPLE "DC01", "WEB01" | Get-VBSystemInfo -Credential (Get-Credential) Uses pipeline input to query multiple servers with alternate credentials. .OUTPUTS [PSCustomObject]: ComputerName, DNS Hostname, Primary IP, IP Assignment, OS Name, OS Version, OS Build, OS Display Version, OS Install Date, Windows Version, Hardware Abstraction Layer, BIOS Version, BIOS Manufacturer, BIOS Serial Number, BIOS Release Date, System Manufacturer, System Model, BIOS Type, Domain, Domain Role, Processor, Cores, Logical Processors, Total Memory (GB), Free Memory (GB), OS Server Level, Logon Server, Time Zone, Last Boot Time, Status, CollectionTime .NOTES Version : 1.0.3 Author : Vibhu Bhatnagar Modified : 16-04-2026 Category : System Hardware #> function Get-VBSystemInfo { [CmdletBinding()] param( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Name', 'Server', 'Host')] [string[]]$ComputerName = $env:COMPUTERNAME, [PSCredential]$Credential ) begin { if (-not ([System.Management.Automation.PSTypeName]'FirmwareType').Type) { Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class FirmwareType { [DllImport("kernel32.dll")] public static extern bool GetFirmwareType(out uint firmwareType); } "@ } } process { foreach ($computer in $ComputerName) { try { if ($computer -eq $env:COMPUTERNAME) { # Local collection $OS = Get-CimInstance -ClassName Win32_OperatingSystem $CS = Get-CimInstance -ClassName Win32_ComputerSystem $BIOS = Get-CimInstance -ClassName Win32_BIOS $Processor = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1 $TimeZone = Get-CimInstance -ClassName Win32_TimeZone $Registry = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -ErrorAction SilentlyContinue # Network info $NetAdapter = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notmatch 'Loopback|vEthernet' } | Select-Object -First 1 $IPAddress = $NetAdapter.IPAddress $NetConfig = Get-NetIPConfiguration -InterfaceIndex $NetAdapter.InterfaceIndex $DHCPStatus = if ($NetConfig.NetIPv4Interface.Dhcp -eq 'Enabled') { 'Enabled' } else { 'Disabled' } $DNSServers = ($NetConfig.DnsServer.ServerAddresses -join ', ') # Get DNS suffix from multiple sources $DNSSuffix = $NetConfig.DnsSuffix if (-not $DNSSuffix) { $DNSSuffixSearch = Get-DnsClientGlobalSetting -ErrorAction SilentlyContinue $DNSSuffix = $DNSSuffixSearch.SuffixSearchList[0] } # DHCP lease info from registry (more reliable) $DHCPLeaseInfo = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\Dhcp\Parameters\Interfaces" -ErrorAction SilentlyContinue | ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue | Select-Object -First 1 } $DHCPServer = $DHCPLeaseInfo.DhcpServer $DHCPLeaseObtained = if ($DHCPLeaseInfo.LeaseObtainedTime) { [DateTime]::FromFileTime($DHCPLeaseInfo.LeaseObtainedTime).ToString('g') } else { 'N/A' } $DHCPLeaseExpires = if ($DHCPLeaseInfo.T1) { [DateTime]::FromFileTime($DHCPLeaseInfo.T1).ToString('g') } else { 'N/A' } # Firmware type $fw = 0 [FirmwareType]::GetFirmwareType([ref]$fw) | Out-Null $BIOSType = switch ($fw) { 1 { "BIOS" } 2 { "UEFI" } default { "Unknown" } } $LogonServer = $env:LOGONSERVER } else { # Remote collection $CimParams = @{ ComputerName = $computer ErrorAction = 'Stop' } if ($Credential) { $CimParams.Credential = $Credential } $Session = New-CimSession @CimParams $OS = Get-CimInstance -CimSession $Session -ClassName Win32_OperatingSystem $CS = Get-CimInstance -CimSession $Session -ClassName Win32_ComputerSystem $BIOS = Get-CimInstance -CimSession $Session -ClassName Win32_BIOS $Processor = Get-CimInstance -CimSession $Session -ClassName Win32_Processor | Select-Object -First 1 $TimeZone = Get-CimInstance -CimSession $Session -ClassName Win32_TimeZone # Remote script block with registry-based DHCP info $InvokeParams = @{ ComputerName = $computer ScriptBlock = { $Registry = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -ErrorAction SilentlyContinue $NetAdapter = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notmatch 'Loopback|vEthernet' } | Select-Object -First 1 $IPAddress = $NetAdapter.IPAddress $NetConfig = Get-NetIPConfiguration -InterfaceIndex $NetAdapter.InterfaceIndex $DHCPStatus = if ($NetConfig.NetIPv4Interface.Dhcp -eq 'Enabled') { 'Enabled' } else { 'Disabled' } $DNSServers = ($NetConfig.DnsServer.ServerAddresses -join ', ') # DNS suffix $DNSSuffix = $NetConfig.DnsSuffix if (-not $DNSSuffix) { $DNSSuffixSearch = Get-DnsClientGlobalSetting -ErrorAction SilentlyContinue $DNSSuffix = $DNSSuffixSearch.SuffixSearchList[0] } # DHCP lease from registry $DHCPLeaseInfo = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\Dhcp\Parameters\Interfaces" -ErrorAction SilentlyContinue | ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue | Select-Object -First 1 } $DHCPServer = $DHCPLeaseInfo.DhcpServer $DHCPLeaseObtained = if ($DHCPLeaseInfo.LeaseObtainedTime) { [DateTime]::FromFileTime($DHCPLeaseInfo.LeaseObtainedTime).ToString('g') } else { 'N/A' } $DHCPLeaseExpires = if ($DHCPLeaseInfo.T1) { [DateTime]::FromFileTime($DHCPLeaseInfo.T1).ToString('g') } else { 'N/A' } # Firmware type if (-not ([System.Management.Automation.PSTypeName]'FirmwareType').Type) { Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class FirmwareType { [DllImport("kernel32.dll")] public static extern bool GetFirmwareType(out uint firmwareType); } "@ } $fw = 0 [FirmwareType]::GetFirmwareType([ref]$fw) | Out-Null $BIOSType = switch ($fw) { 1 { "BIOS" } 2 { "UEFI" } default { "Unknown" } } $LogonServer = $env:LOGONSERVER return @{ IPAddress = $IPAddress DHCPStatus = $DHCPStatus DNSServers = $DNSServers DNSSuffix = $DNSSuffix DHCPServer = $DHCPServer DHCPLeaseObtained = $DHCPLeaseObtained DHCPLeaseExpires = $DHCPLeaseExpires BIOSType = $BIOSType LogonServer = $LogonServer Registry = $Registry } } } if ($Credential) { $InvokeParams.Credential = $Credential } $RemoteData = Invoke-Command @InvokeParams $IPAddress = $RemoteData.IPAddress $DHCPStatus = $RemoteData.DHCPStatus $DNSServers = $RemoteData.DNSServers $DNSSuffix = $RemoteData.DNSSuffix $DHCPServer = $RemoteData.DHCPServer $DHCPLeaseObtained = $RemoteData.DHCPLeaseObtained $DHCPLeaseExpires = $RemoteData.DHCPLeaseExpires $BIOSType = $RemoteData.BIOSType $LogonServer = $RemoteData.LogonServer $Registry = $RemoteData.Registry Remove-CimSession -CimSession $Session } # Output object $SystemInfo = [PSCustomObject]@{ ComputerName = $computer DNSHostname = $CS.DNSHostName Domain = $CS.Domain DomainRole = switch ($CS.DomainRole) { 0 { 'Standalone Workstation' } 1 { 'Member Workstation' } 2 { 'Standalone Server' } 3 { 'Member Server' } 4 { 'Backup Domain Controller' } 5 { 'Primary Domain Controller' } default { $CS.DomainRole } } LogonServer = $LogonServer PrimaryIP = $IPAddress DHCPStatus = $DHCPStatus DHCPServer = $DHCPServer DHCPLeaseObtained = $DHCPLeaseObtained DHCPLeaseExpires = $DHCPLeaseExpires DNSServers = $DNSServers DNSSuffix = $DNSSuffix OSName = $OS.Caption OSVersion = $OS.Version OSBuild = $OS.BuildNumber OSDisplayVersion = if ($Registry.DisplayVersion) { $Registry.DisplayVersion } else { $OS.BuildNumber } OSInstallDate = $OS.InstallDate SystemManufacturer = $CS.Manufacturer SystemModel = $CS.Model Processor = $Processor.Name Cores = $Processor.NumberOfCores LogicalProcessors = $Processor.NumberOfLogicalProcessors TotalMemoryGB = [math]::Round($CS.TotalPhysicalMemory / 1GB, 2) FreeMemoryGB = [math]::Round($OS.FreePhysicalMemory / 1MB, 2) BIOSType = $BIOSType BIOSVersion = $BIOS.SMBIOSBIOSVersion BIOSManufacturer = $BIOS.Manufacturer BIOSSerialNumber = $BIOS.SerialNumber BIOSReleaseDate = $BIOS.ReleaseDate TimeZone = $TimeZone.StandardName LastBootTime = $OS.LastBootUpTime Status = 'Success' CollectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') } $SystemInfo } catch { [PSCustomObject]@{ ComputerName = $computer Error = $_.Exception.Message Status = 'Failed' CollectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') } } } } } |