SMBIOSLib.psm1
<# SMBIOSLib Copyright (C) 2020-2025 Vincent Anso This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. This program was inspired by DMI Decode. Copyright (C) 2000-2002 Alan Cox <alan@redhat.com> Copyright (C) 2002-2024 Jean Delvare <jdelvare@suse.de> https://www.nongnu.org/dmidecode/ #> using namespace System.Collections using namespace System.Collections.Generic using namespace System.Collections.Specialized using namespace System.Globalization using namespace System.Text using namespace System.Net using namespace System.Net.NetworkInformation # # Used for compatibility with Windows PowerShell 5.x # class OSPlatform { static [string]$PSPlatformName static [bool]$IsLinux = $false static [bool]$IsWindows = $false static [bool]$IsMacOS = $false } # # Global settings defined by the function parameters # class Settings { static [MemorySizeUnit]$MemorySizeUnit static [TemperatureUnit]$TemperatureUnit static [Boolean]$Verbose static [Boolean]$Expand static [Boolean]$HideHeader static [Boolean]$NoEmphasis } # # Utility class for localization. # class Localization { hidden static [HashTable]$LocalisedStrings static Localization() { $cultureName = (Get-Culture).Name if ( Test-Path -Path $(Join-Path -Path $PSScriptRoot -ChildPath $cultureName) ) { [Localization]::LocalisedStrings = Import-LocalizedData -UICulture $cultureName } else { [Localization]::LocalisedStrings = Import-LocalizedData -UICulture "en-US" } } static [String]LocalizedString([String]$string) { if ([Localization]::LocalisedStrings.$string) { return [Localization]::LocalisedStrings.$string } else { return "Localized string not found for $string." } } } function Get-LocalizedString { param( [String]$String ) [Localization]::LocalizedString($String) } # # Utility class to simplify the manipulation of bit fields. # class BitField { static [int]Get([Object]$bitField, [int]$offset) { return [BitField]::Extract([Object]$bitField, [int]$offset, 1) } static [int]Extract([Object]$bitField, [int]$offset, [int]$length) { return (($bitField -shr $offset) -band (1 -shl ($length)) -1) } static [UInt32]LowUInt64([UInt64]$int) { $bytes = [BitConverter]::GetBytes($int) return [BitConverter]::ToUInt32($bytes, 0) } static [UInt32]HighUInt64([UInt64]$int) { $bytes = [BitConverter]::GetBytes($int) return [BitConverter]::ToUInt32($bytes, 2) } } # # Utility class for converting a bit field into other types. # class BitFieldConverter { static [int]Length([Object]$bitField) { [int]$length = 0 switch ($bitField) { { $bitField -is [Byte] } { $length = 8 } { $bitField -is [UInt16] } { $length = 16 } { $bitField -is [UInt32] } { $length = 32 } { $bitField -is [UInt64] } { $length = 64 } } return $length } # # ToArray # static [Array]ToArray([Object]$bitField, [Array]$names) { return [BitFieldConverter]::ToArray($bitField, [BitFieldConverter]::Length($bitField), $names) } static [Array]ToArray([Object]$bitField, [int]$length, [Array]$names) { $list = [ArrayList]::new() for ($i = 0; $i -le $length - 1 ; $i++) { if ($bitField -band (1 -shl $i)) { $list.Add($names[$i]) | Out-Null } } return $list } static [StringValue]ToStringValue([Object]$bitField, [String]$dictionaryName, [ref]$classRef) { return [BitFieldConverter]::ToStringValue($bitField, [BitFieldConverter]::Length($bitField), $dictionaryName, $classRef) } static [StringValue]ToStringValue([Object]$bitField, [int]$length, [String]$dictionaryName, [ref]$classRef) { $class = $classRef.Value $names = $class::StringArrays[$dictionaryName] return [BitFieldConverter]::ToStringValue($bitField, $length, $names) } static [StringValue]ToStringValue([Object]$bitField, [Array]$names) { return [BitFieldConverter]::ToStringValue($bitField, [BitFieldConverter]::Length($bitField), $names) } static [StringValue]ToStringValue([Object]$bitField, [int]$length, [Array]$names) { if ($bitField -eq 0) { return [StringValue]::new(-1, $(Get-LocalizedString "NONE")) } for ($i = 0; $i -le $length - 1 ; $i++) { if ($bitField -band (1 -shl $i)) { return [StringValue]::new($i, $names[$i]) } } return $null } # # ToStringValueArray # static [StringValue[]]ToStringValueArray([Object]$bitField, [String]$dictionaryName, [ref]$classRef) { return [BitFieldConverter]::ToStringValueArray($bitField, [BitFieldConverter]::Length($bitField), $dictionaryName, 0, $classRef) } static [StringValue[]]ToStringValueArray([Object]$bitField, [int]$length, [String]$dictionaryName, [ref]$classRef) { return [BitFieldConverter]::ToStringValueArray($bitField, $length, $dictionaryName, 0, $classRef) } static [StringValue[]]ToStringValueArray([Object]$bitField, [int]$length, [String]$dictionaryName, [int]$offset, [ref]$classRef) { $class = $classRef.Value $names = $class::StringArrays[$dictionaryName] return [BitFieldConverter]::ToStringValueArray($bitField, $length, $names, $offset) } static [StringValue[]]ToStringValueArray([Object]$bitField, [Array]$names) { return [BitFieldConverter]::ToStringValueArray($bitField, [BitFieldConverter]::Length($bitField), $names, 0) } static [StringValue[]]ToStringValueArray([Object]$bitField, [int]$length, [Array]$names) { return [BitFieldConverter]::ToStringValueArray($bitField, $length, $names, 0) } static [StringValue[]]ToStringValueArray([Object]$bitField, [int]$length, [Array]$names, [int]$offset) { if ($bitField -eq 0) { return [StringValue]::new(-1, $(Get-LocalizedString "NONE")) } $list = [ArrayList]::new() $expand = $false for ($i = 0; $i -le $length - 1 ; $i++) { if ($expand) { if ($bitField -band (1 -shl $i)) { $list.Add( [StringValue]::new($i + $offset, $names[$i], $true) ) | Out-Null } else { $list.Add( [StringValue]::new($i + $offset, $names[$i], $false) ) | Out-Null } } else { if ($bitField -band (1 -shl $i)) { $list.Add( [StringValue]::new($i + $offset, $names[$i]) ) | Out-Null } } } return $list.ToArray() } # # ToBitArray # static [Collections.BitArray]ToBitArray([Object]$bitField) { return [BitFieldConverter]::ToBitArray($bitField, [BitFieldConverter]::Length($bitField)) } static [BitArray]ToBitArray([Object]$bitField, [int]$length) { $list = [List[Boolean]]::new() for ($i = 0; $i -le $length - 1 ; $i++) { if ($bitField -band (1 -shl $i)) { $list.Add($true) | Out-Null } else { $list.Add($false) | Out-Null } } return [BitArray]::new($list.ToArray()) } # # ToInt # static [int]ToInt([Byte]$bitField, [int]$offset, [int]$count) { return [BitFieldConverter]::ToInt([UInt32]$bitField, [int]$offset, [int]$count) } static [int]ToInt([UInt16]$bitField, [int]$offset, [int]$count) { return [BitFieldConverter]::ToInt([UInt32]$bitField, [int]$offset, [int]$count) } static [int]ToInt([UInt32]$bitField, [int]$offset, [int]$count) { $bitArray = [BitFieldConverter]::ToBitArray($bitField) [Boolean[]]$segment = [ArraySegment[Boolean]]::new($bitArray, $offset, $count) $bitArray = [BitArray]::new($segment) [int[]]$int = [Array]::CreateInstance([int], 1) $bitArray.CopyTo($int, 0) return $int[0] } static [int]ToInt([BitArray]$bitArray, [int]$offset, [int]$count) { [Boolean[]]$segment = [ArraySegment[Boolean]]::new($bitArray, $offset, $count) $bitArray = [BitArray]::new($segment) [int[]]$result = [Array]::CreateInstance([int], 1) $bitArray.CopyTo($result, 0) return $result[0] } } class SMBString : PSObject { SMBString([Object]$value, [Byte]$index) { if ( [String]::IsNullOrEmpty($value) ) { $this | Add-Member Value $null $this | Add-Member DisplayValue "$(Get-LocalizedString "N/A")" } else { $this | Add-Member Value $value.ToString() $this | Add-Member DisplayValue $value.ToString() } $this | Add-Member Index $index } SMBString([String]$string) { $this | Add-Member Value $string $this | Add-Member DisplayValue $string $this | Add-Member Index -1 } [String]ToString() { if ([Settings]::Expand) { if ([Settings]::NoEmphasis) { return [String]::Format("Strings[{0}] ({1})", $this.Index, $this.DisplayValue) } else { return [char]0x001b + "[1m" + [String]::Format("Strings[{0}] ({1})", $this.Index, $this.DisplayValue) + [char]0x001b + "[0m" } } else { $allWhiteSpace = [Linq.Enumerable]::All([char[]]$this.DisplayValue, [Func[char,bool]]{ [char]::IsWhiteSpace($args[0]) }) if ( ($allWhiteSpace) -or ($this.DisplayValue.StartsWith(" ")) -or ($this.DisplayValue.EndsWith(" ")) ) { if ([Settings]::NoEmphasis) { return "`"" + "$($this.DisplayValue)" + "`"" } else { return [char]0x001b + "[1m" + "`"" + "$($this.DisplayValue)" + "`"" + [char]0x001b + "[0m" } } else { if ([Settings]::NoEmphasis) { return $($this.DisplayValue) } else { return [char]0x001b + "[1m" + "$($this.DisplayValue)" + [char]0x001b + "[0m" } } } } } class SMBHandle { hidden [UInt16]$Value SMBHandle() { $this.Value = [UInt16]::MaxValue } SMBHandle([UInt16]$value) { $this.Value = $value } [String]ToString() { if ($this.Value -eq [UInt16]::MaxValue) { return Get-LocalizedString "N/A" } else { return [String]::Format("0x{0:X4}", $this.Value) } } static [UInt16]op_Implicit([SMBHandle]$value) { return $value.Value } } # # Class allowing to store each result in a uniform format. # class StringValue : IFormattable { [Object]$Value [String]$DisplayValue hidden [Boolean]$Resolved StringValue() { $this.Value = $null $this.DisplayValue = Get-LocalizedString "NOT_AVAILABLE" } StringValue([Object]$value) { if ($null -eq $value) { $this.Value = $value $this.DisplayValue = Get-LocalizedString "NOT_AVAILABLE" } else { $this.Value = $value $this.DisplayValue = $value } } StringValue([Object]$value, [String]$format) { if ($null -eq $value) { $this.DisplayValue = Get-LocalizedString "NOT_AVAILABLE" } else { $this.Value = $value $this.DisplayValue = [String]::Format($format, $this.Value) $this.Resolved = $true } } StringValue([Object]$value, [Object]$exceptionValue, [String]$format, [String]$exceptionString) { $this.Value = $value $exception = $false if ($exceptionValue -is [Array]) { if ($exceptionValue -contains $value) { $exception = $true } } else { if ($value -eq $exceptionValue) { $exception = $true } } if ($exception) { $this.Displayvalue = Get-LocalizedString $exceptionString } else { if ( [String]::IsNullOrEmpty($format) ) { $this.DisplayValue = $value } else { $this.DisplayValue = [String]::Format($format, $value) } } } StringValue([Object]$value, [Object]$exceptionValue, [String]$format, [Object]$effectiveValue, [String]$exceptionString) { $this.Value = $effectiveValue $exception = $false if ($value -eq $exceptionValue) { $exception = $true } if ($exception) { $this.Displayvalue = Get-LocalizedString $exceptionString } else { if ( [String]::IsNullOrEmpty($format) ) { $this.DisplayValue = $value } else { $this.DisplayValue = [String]::Format($format, $value) } } } StringValue([Object]$value, [Object]$exceptionValue, [String]$format, [String]$exceptionString, [Object]$extendedValue, [Object]$effectiveValue) { if ($value -eq $extendedValue) { $this.Value = $effectiveValue } else { $this.Value = $value } $exception = $false if ($value -eq $exceptionValue) { $exception = $true } if ($exception) { $this.Displayvalue = Get-LocalizedString $exceptionString } else { if ( [String]::IsNullOrEmpty($format) ) { $this.DisplayValue = $value } else { $this.DisplayValue = [String]::Format($format, $value) } } } StringValue([Object]$value, [OrderedDictionary]$names) { $this.Value = $value $result = $names.[int]$Value if ($result) { $this.Resolved = $true $this.DisplayValue = $result } else { $outOfSpecification = Get-LocalizedString "OUT_OF_SPEC" $this.DisplayValue = [String]::Format("{0} ($outOfSpecification)", $value) } } StringValue([Object]$value, [String]$dictionaryName, [ref]$classRef) { $this.Value = $value $class = $classRef.Value $names = $class::StringArrays["$dictionaryName"] $result = $names.[int]$value if ($result) { $this.Resolved = $true $this.DisplayValue = $result } else { $outOfSpecification = Get-LocalizedString "OUT_OF_SPEC" $this.DisplayValue = [String]::Format("{0} ($outOfSpecification)", $value) } if ((-not ($names.[int]0)) -and ($value -eq 0)) { $this.Resolved = $false $this.DisplayValue = Get-LocalizedString "NONE" } } [String]ToString() { return $this.ToString("G", [CultureInfo]::CurrentCulture); } [String]ToString([String]$format) { return $this.ToString($format, [CultureInfo]::CurrentCulture); } [String]ToString([String]$format, [IFormatProvider]$formatProvider) { if (-Not ($formatProvider)) { $formatProvider = [CultureInfo]::CurrentCulture } if (($format -eq "0") -or ($format -eq [String]::Empty)) { if ([Settings]::Expand) { $formattedValue = $this.Value if ($null -eq $this.Value) { $formattedValue = "`$null" } return [String]::Format("{0} ({1})", $formattedValue, $this.DisplayValue) } else { return $this.DisplayValue } } else { return [String]::Format($formatProvider, $format, $this.Value) } } [OrderedDictionary]Expand() { return [Ordered]@{ Value = $this.Value ; DisplayValue = $this.DisplayValue } } static [int]op_Implicit([StringValue]$stringValue) { return $stringValue.Value } } class StringValueArray : StringValue { [Boolean]$Supported StringValueArray([Object]$value, [String]$name, [Boolean]$supported) { if ([String]::IsNullOrEmpty($name)) { $outOfSpecification = Get-LocalizedString "OUT_OF_SPEC" $this.DisplayValue = [String]::Format("{0} ($outOfSpecification)", $value) $this.Value = $value } else { $this.Value = $value $this.DisplayValue = $name $this.Supported = $supported } } } # # Data storage size units. # enum MemorySizeUnit { B kB MB GB TB PB EB ZB YB Auto None Unknown } class StringValueMemorySize : StringValue { [Object]$SizeInBytes [MemorySizeUnit]$Unit static [MemorySizeUnit]AdjustSizeUnit([Object]$sizeInBytes) { # Useless therefore essential $1eb = 1.15292150460685E+18 $1zb = 1.18059162071741E+21 $1yb = 1.20892581961463E+24 if ($sizeInBytes -ge $1yb) { return [MemorySizeUnit]::YB } elseif ($sizeInBytes -ge $1zb) { return [MemorySizeUnit]::ZB } elseif ($sizeInBytes -ge $1eb) { return [MemorySizeUnit]::EB } elseif ($sizeInBytes -ge 1pb) { return [MemorySizeUnit]::PB } elseif ($sizeInBytes -ge 1tb) { return [MemorySizeUnit]::TB } elseif ($sizeInBytes -ge 1gb) { return [MemorySizeUnit]::GB } elseif ($sizeInBytes -ge 1mb) { return [MemorySizeUnit]::MB } elseif ($sizeInBytes -ge 1kb) { return [MemorySizeUnit]::kB } else { return [MemorySizeUnit]::B } } StringValueMemorySize([Object]$sizeInBytes, [MemorySizeUnit]$unit) : base() { $1eb = 1.15292150460685E+18 $1zb = 1.18059162071741E+21 $1yb = 1.20892581961463E+24 $dataSizes = @(1, 1kb, 1mb, 1gb, 1tb, 1pb, $1eb, $1zb, $1yb) if ([Settings]::MemorySizeUnit -eq [MemorySizeUnit]::Auto) { if ($unit -eq [MemorySizeUnit]::Auto) { $_unit = [StringValueMemorySize]::AdjustSizeUnit($sizeInBytes) $localizedUnit = Get-LocalizedString $_unit $dataSize = $dataSizes[[int]$_unit] } else { $_unit = $unit $localizedUnit = Get-LocalizedString $unit $dataSize = $dataSizes[[int]$unit] } } else { $customUnit = [Settings]::MemorySizeUnit $_unit = $customUnit $localizedUnit = Get-LocalizedString $customUnit $dataSize = $dataSizes[[int]$customUnit] } $this.Value = $sizeInBytes / $dataSize $this.SizeInBytes = $sizeInBytes $this.DisplayValue = [String]::Format("{0:N0} $localizedUnit", $this.Value) $this.Unit = $_unit } StringValueMemorySize([Object]$value, [String]$dictionaryName, [ref]$classRef, [Object]$SizeInBytes, [MemorySizeUnit]$unit) : base() { $this.Value = $value $this.SizeInBytes = $SizeInBytes $this.Unit = $unit $class = $classRef.Value $names = $class::StringArrays["$dictionaryName"] $result = $names.[int]$value if ($result) { $this.Resolved = $true $this.DisplayValue = $result } else { $outOfSpecification = Get-LocalizedString "OUT_OF_SPEC" $this.DisplayValue = [String]::Format("{0} ($outOfSpecification)", $value) } } } # # Temperature units. # enum TemperatureUnit { Auto Celsius Fahrenheit Unknown } class StringValueTemperature : StringValue { [Object]$Value [String]$DisplayValue [TemperatureUnit]$Unit hidden [Sbyte]$Precision StringValueTemperature([Object]$temperature, [String]$string) : base() { $this.Value = $temperature $this.DisplayValue = $string $this.Unit = [TemperatureUnit]::Unknown $this.Precision = -1 } StringValueTemperature([Object]$temperatureInCelsius, [TemperatureUnit]$unit, [Sbyte]$precision) : base() { $temperature = 0 $localizedUnit = "" if ([Settings]::TemperatureUnit -eq [TemperatureUnit]::Celsius) { $localizedUnit = Get-LocalizedString "CELSIUS" $temperature = $temperatureInCelsius } elseif ([Settings]::TemperatureUnit -eq [TemperatureUnit]::Fahrenheit) { $localizedUnit = Get-LocalizedString "FAHRENHEIT" $temperature = ($temperatureInCelsius * 9/5) + 32 } elseif ([Settings]::TemperatureUnit -eq [TemperatureUnit]::Auto) { $cultureName = (Get-Culture).Name $region = [RegionInfo]::new($cultureName) if ($region.IsMetric) { $localizedUnit = Get-LocalizedString "CELSIUS" $temperature = $temperatureInCelsius } else { $localizedUnit = Get-LocalizedString "FAHRENHEIT" $temperature = ($temperatureInCelsius * 9/5) + 32 } } $this.Value = $temperature $this.DisplayValue = [String]::Format("{0:F$($precision)} $localizedUnit", $this.Value) $this.Unit = $unit $this.Precision = $precision } [StringValue]ToFahrenheit() { $temperature = ($this.Value * 9/5) + 32 $localizedUnit = Get-LocalizedString "FAHRENHEIT" $string = [String]::Format("{0:F$($this.Precision)} $localizedUnit", $this.Value) return [StringValue]::new($temperature, $string) } } class StringValueVersion : StringValue { StringValueVersion([Object]$value, [String]$format) : base($value, $format) { } StringValueVersion([Object]$value, [Object]$exceptionValue, [String]$format, [String]$exceptionString) : base($value, $exceptionValue, $format, $exceptionString) { } static [Version]op_Implicit([StringValueVersion]$stringValueVersion) { return $stringValueVersion.Value } } class StringValueDateTime : StringValue { hidden [string]$Format StringValueDateTime() : base() { $notDefined = Get-LocalizedString "NOT_DEFINED" $this.DisplayValue = $notDefined } StringValueDateTime([Object]$value) : base($value) { $pattern = [CultureInfo]::CurrentCulture.DateTimeFormat.LongDatePattern $this.Format = "{0:$pattern}" if ($null -eq $value) { $this.DisplayValue = Get-LocalizedString "NOT_DEFINED" } } StringValueDateTime([Object]$value, [String]$format) : base($value, $format) { $this.Format = $format if ($null -eq $value) { $notDefined = [Localization]::LocalizedString("NOT_DEFINED") $this.DisplayValue = $notDefined } } [String]ToString() { return $this.ToString("G", [CultureInfo]::CurrentCulture); } [String]ToString([String]$format) { return $this.ToString($format, [CultureInfo]::CurrentCulture); } [String]ToString([String]$format, [IFormatProvider]$formatProvider) { if ($null -eq $this.value) { return $this.DisplayValue } if (-Not ($formatProvider)) { $formatProvider = [CultureInfo]::CurrentCulture } if (($format -eq "0") -or ($format -eq [String]::Empty)) { if ($this.Format) { $longDateString = [String]::Format($formatProvider, $this.Format, $this.Value) } else { $longDateString = $this.Value.ToLongDateString() } if ([Settings]::Expand) { return [String]::Format("{0} ({1})", $this.Value, $longDateString) } else { return $longDateString } } else { return [String]::Format($formatProvider, $format, $this.Value) } } static [DateTime]op_Implicit([StringValueDateTime]$stringValueDateTime) { return $stringValueDateTime.Value } } class StringValueOrderedDictionary : StringValue { StringValueOrderedDictionary() : base() { } StringValueOrderedDictionary([Object]$value) : base($value) { $this.DisplayValue = ( $value.GetEnumerator() | ForEach-Object { "$($_.Key) $($_.Value)" } ) -Join " " } StringValueOrderedDictionary([Object]$value, [String]$format) : base($value, $format) { } static [OrderedDictionary]op_Implicit([StringValueOrderedDictionary]$stringValueOrderedDictionary) { return $stringValueOrderedDictionary.Value } [String]toString() { return $this.DisplayValue } [String]ToString([String]$format, [IFormatProvider]$formatProvider) { return $this.DisplayValue if (-Not ($formatProvider)) { $formatProvider = [CultureInfo]::CurrentCulture } $string = ( $this.Value.GetEnumerator() | ForEach-Object { "$($_.Key) $($_.Value)" } ) -Join " " if (($format -eq "0") -or ($format -eq [String]::Empty)) { $ExpandedString = ( $this.Value.GetEnumerator() | ForEach-Object { "$($_.Key) = $($_.Value)" } ) -Join "; " $string = ( $this.Value.GetEnumerator() | ForEach-Object { "$($_.Key) $($_.Value)" } ) -Join " " if ([Settings]::Expand) { return [String]::Format("{0} ({1})", "{$ExpandedString}", $string) } else { return $this.DisplayValue } } else { return [String]::Format($formatProvider, $format, $this.Value) } } } class StringValueFormated : StringValue { StringValueFormated([Object]$value, [OrderedDictionary]$values, [Array]$formats) { $this.Value = $values $result = "" for ($index = 0; $index -lt $values.Count; $index++) { $item = $values[$index].Value $format = $formats[$index] $result = $result + [String]::Format($format, $item) } $this.DisplayValue = $result } [String]toString() { return $this.DisplayValue } } # # Defines a SMBIOSType # class SMBIOSType { [int]$Type [string]$Name hidden [string[]]$Keywords SMBIOSType([int]$type, [string]$name) { $this.Type = $type $this.Name = $name } SMBIOSType([int]$type, [string]$name, [string[]]$keywords) { $this.Type = $type $this.Name = $name $this.Keywords = $keywords } [String]ToString() { return $this.Name } } # # Defines a SMBIOSAvailableType # class SMBIOSAvailableType { [int]$Count [int]$Type [string]$Name [UInt16[]]$Handle SMBIOSAvailableType([int]$count, [int]$type, [string]$name, [UInt16[]]$handle) { $this.Count = $count $this.Type = $type $this.Name = $name $this.Handle = $handle } } # # Defines a SMBIOSTypeDescription # class SMBIOSTypeDescription { [int]$Type [string]$Description SMBIOSTypeDescription([int]$type, [string]$description) { $this.Type = $type $this.Description = $description } [String]ToString() { return $this.Description } } # # Reads, analyzes SMBIOS structures and stores them in a form of Hashtable. # class SMBIOS { static [Version]$SupportedVersion static [Version]$Version static [Encoding]$Encoding static [Array]$Types static [Array]$Descriptions static [Array]$AvailableTypes static [List[Hashtable]]$Structures static [Byte[]]$TableData static [UInt32]$TableDataSize static [Byte[]]$EntryPoint static [UInt64]$StructureTableAddress static [String]$Hash static SMBIOS() { # Define the supported vesion of SMBIOS [SMBIOS]::SupportedVersion = [Version]::new("3.8.0") # Generates SMBIOS types list $typesList = [ArrayList]::new() $SMBIOSTypes = [SMBIOSStructure]::StringArrays["SMBIOSType"] foreach ( $type in $SMBIOSTypes.GetEnumerator() ) { $typesList.Add( [SMBIOSType]::new( $type.Key, $type.Value ) ) } [SMBIOS]::Types = $typesList # Generates SMBIOS descriptions list $descriptionsList = [ArrayList]::new() $SMBIOSTypeDescriptions = [SMBIOSStructure]::StringArrays["SMBIOSTypeDescription"] foreach ( $description in $SMBIOSTypeDescriptions.GetEnumerator() ) { $descriptionsList.Add( [SMBIOSTypeDescription]::new( $description.Key, $description.Value ) ) } [SMBIOS]::Descriptions = $descriptionsList } # Using the ioreg tool to retrieve SMBIOS information on Mac. # The SMBIOS-EPS property contains the entry point of the SMBIOS. # The SMBIOS property contains the SMBIOS table. # SMBIOS is not longer used by Apple on Mac with Apple silicon. static [Byte[]] ReadAppleSMBIOSProperty([String]$property) { $tableDataList = [List[Byte]]::new() $AppleSMBIOSProperty = /usr/sbin/ioreg -c AppleSMBIOS -r | Select-String $property if ($AppleSMBIOSProperty) { $SMBIOSProperty = ($AppleSMBIOSProperty -Split "= ")[1].TrimStart("<").TrimEnd(">") $length = $SMBIOSProperty.Length / 2 for ($i = 0; $i -lt $length ; $i++) { $hex = $SMBIOSProperty.SubString($i * 2, 2) $byte = [Convert]::ToByte($hex, 16) $tableDataList.Add($byte) } } return $tableDataList.ToArray() } # Parse the entry point of the SMBIOS static [void]ParseEntryPoint([Byte[]]$entryPoint) { [SMBIOS]::EntryPoint = $entryPoint $anchor = [ArraySegment[Byte]]::new($entryPoint, 0, 4) [Byte[]]$_SM_ = 0x5F, 0x53, 0x4D, 0x5F $SMBIOSVersion = 0 $majorVersion = 0 $minorVersion = 0 $revisionVersion = 0 if ([Linq.Enumerable]::SequenceEqual($anchor, $_SM_)) { $SMBIOSVersion = 2 } $anchor = [ArraySegment[Byte]]::new($entryPoint, 0, 5) [Byte[]]$_SM3_ = 0x5F, 0x53, 0x4D, 0x33, 0x5F if ([Linq.Enumerable]::SequenceEqual($anchor, $_SM3_)) { $SMBIOSVersion = 3 } switch ($SMBIOSVersion) { 2 { [SMBIOS]::TableDataSize = [BitConverter]::ToUInt16($entryPoint, 0x16) $majorVersion = $entryPoint[0x06] $minorVersion = $entryPoint[0x07] $revisionVersion = $entryPoint[0x1E] [SMBIOS]::StructureTableAddress = [BitConverter]::ToUInt32($entryPoint, 0x18) } 3 { [SMBIOS]::TableDataSize = [BitConverter]::ToUInt32($entryPoint, 0x0C) $majorVersion = $entryPoint[0x07] $minorVersion = $entryPoint[0x08] $revisionVersion = $entryPoint[0x09] [SMBIOS]::StructureTableAddress = [BitConverter]::ToUInt64($entryPoint, 0x10) } } [SMBIOS]::Version = [Version]::new($majorVersion, $minorVersion, $revisionVersion) } # Parse the SMBIOS table static [Void]ParseTableData() { $tableDataHash = $(Get-FileHash -InputStream $([System.IO.MemoryStream]::new([SMBIOS]::TableData)) -Algorithm MD5).Hash if ($tableDataHash -ne [SMBIOS]::Hash) { [SMBIOS]::Hash = $tableDataHash $structuresList = [List[Hashtable]]::new() $tableDataLength = [SMBIOS]::TableData.Count $offset = 0 do { # Read the header (fixed size) $type = [SMBIOS]::TableData[$offset] $length = [SMBIOS]::TableData[$offset + 1] $handle = [BitConverter]::ToUInt16([SMBIOS]::TableData, $offset + 2) $data = [ArraySegment[Byte]]::new([SMBIOS]::TableData, $offset, $length) $variableLengthBegin = $offset + $length $location = $variableLengthBegin $variableLength = 0 # Read the strings (variable size) while ($location -lt $tableDataLength) { if (([SMBIOS]::TableData[$location] -eq 0x00) -and ([SMBIOS]::TableData[$location + 1] -eq 0x00)) { $variableData = [ArraySegment[Byte]]::new([SMBIOS]::TableData, $variableLengthBegin, $variableLength) [ArrayList]$strings = [SMBIOS]::Encoding.GetString($variableData) -Split ("`0") $structure = @{ "Type" = $type; "Length" = $length; "Handle" = $handle; "Data" = $data; "Strings" = $strings } $structuresList.Add($structure) | Out-Null $offset = $location + 2 break } else { $location = $location + 1 $variableLength = $variableLength + 1 } } } while ($offset -lt $tableDataLength) [SMBIOS]::Structures = $structuresList } } } ################################################################################################################################### # class SMBIOSStructureHeader # ################################################################################################################################### class SMBIOSStructureHeader { [Byte]$Type [String]$Description [Byte]$Length [UInt16]$Handle SMBIOSStructureHeader([Byte]$type, [String]$description, [Byte]$length, [UInt16]$handle) { $this.Type = $type $this.Description = $description $this.Length = $length $this.Handle = $handle } [String]ToString() { return [String]::Format($(Get-LocalizedString "SMBIOS_HEADER"), $this.Handle, $this.Type, $this.Description, $this.Length) } } ################################################################################################################################### # class SMBIOSStructure # ################################################################################################################################### class SMBIOSStructure { static [Hashtable]$StringArrays static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static SMBIOSStructure() { $stringTables = [SMBIOSStructure]::GetStringTables("Types") [SMBIOSStructure]::StringArrays = $stringTables.StringArrays [SMBIOSStructure]::StringArrayNameAlias = $stringTables.StringArrayNameAlias } hidden [Byte]$Type hidden [String]$Description hidden [Byte]$Length hidden [UInt16]$Handle hidden [OrderedDictionary]$Properties hidden [String[]]$Keywords hidden [Byte[]]$Data hidden [String[]]$Strings hidden [Boolean]$Obsolete # for compatibility with version 0.8 hidden [Byte]$_Type hidden [String]$_Description hidden [UInt16]$_Handle SMBIOSStructure([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) { $this.Type = $type $this.Description = $description $this.Length = $length $this.Keywords = $keywords $this.Handle = $handle $this.Data = $data $this.Strings = $strings $this.Properties = [Ordered]@{} # for compatibility with version 0.8 $this._Type = $this.Type $this._Description = $this.Description $this._Handle = $this.Handle } hidden [Byte]Get_Type() { return $this.Type } hidden [String]Get_Description() { return $this.Description } hidden [UInt16]Get_Handle() { return $this.Handle } hidden [SMBIOSStructureHeader]Get_Header() { return [SMBIOSStructureHeader]::new($this.Type, $this.Description, $this.Length, $this.Handle) } hidden [ArraySegment[Byte]]Get_Data() { return $this.Data } hidden [String[]]Get_Strings() { return $this.Strings } hidden [Array]GetPropertyNames() { $class = $this.GetType() return $class::PropertyNames } hidden [Byte]GetByteAtOffset([int]$offset) { try { return $this.data[$offset] } catch { return 0 } } hidden [UInt16]GetWordAtOffset([int]$offset) { try { return [BitConverter]::ToUInt16($this.data, $offset) } catch { return 0 } } hidden [UInt32]GetDoubleWordAtOffset([int]$offset) { try { return [BitConverter]::ToUInt32($this.data, $offset) } catch { return 0 } } hidden [UInt64]GetQuadWordAtOffset([int]$offset) { try { return [BitConverter]::ToUInt64($this.data, $offset) } catch { return 0 } } hidden [SMBString]GetStringAtOffset([Byte]$offset) { $index = $this.data[$offset] - 1 if ($index -ge 0) { if ( [String]::IsNullOrEmpty( $this.strings[$index] ) ) { return [SMBString]::new([String]::Empty, [Byte]::MaxValue) } else { return [SMBString]::new($this.strings[$index], $index) } } else { return [SMBString]::new([String]::Empty, [Byte]::MaxValue) } } hidden [ArraySegment[Byte]]GetData() { return $this.Data } hidden [String[]]GetStrings() { return $this.Strings } hidden [Byte]GetDMIType() { return $this.Type } hidden [int]GetLength() { return $this.Length } hidden [UInt16]GetHandle() { return $this.Handle } [Boolean]isObsolete() { return $this.Obsolete } hidden static [Hashtable]GetStringTables([String]$type) { $cultureName = (Get-Culture).Name if (Test-Path -Path $(Join-Path -Path $PSScriptRoot -ChildPath $cultureName)) { $xml = [xml](Get-Content -Path "$PSScriptRoot/$cultureName/$type.xml") } else { $xml = [xml](Get-Content -Path "$PSScriptRoot/en-US/$type.xml") } $_stringArrays = @{} $_stringArrayNameAlias = @{} $collection = $null foreach ( $table in $xml.strings.table ) { if ( $table.kind -eq "Ordered" ) { $collection = [OrderedDictionary]::new() foreach( $entry in $table.entry ) { $collection.Add( [int]$entry.key, $entry.value ) } } elseif ( $table.kind -eq "Array" ) { $collection = [Collections.ArrayList]::new() foreach( $entry in $table.entry ) { $collection.Add( $entry.value ) } } $_stringArrays.Add( $($table.name), $collection ) $aliases = $($table.alias).Split(",") foreach( $alias in $aliases ) { $_stringArrayNameAlias.Add( $alias, $table.name ) } } return @{"StringArrays" = $_stringArrays ; "StringArrayNameAlias" = $_stringArrayNameAlias } } hidden [void]SetProperties([array]$propertiesList) { $runtimeType = $this.GetType() if ($propertiesList -eq "*") { $propertiesList = $runtimeType::PropertyNames } if ($this.PropertyNamesEx) { $propertiesList = $propertiesList + $this.PropertyNamesEx } if (-Not [Settings]::HideHeader) { $propertiesList = @("_Header") + $propertiesList } foreach ($property in $propertiesList) { try { $methodInfo = $runtimeType.GetMethod("Get$property") if ($property.StartsWith("_")) { $propertyName = $property.Replace("_","") } else { $propertyName = $property } try { [System.Runtime.CompilerServices.RuntimeHelpers]::PrepareMethod($methodInfo.MethodHandle) $object = $methodInfo.Invoke($this, $null) $this.Properties.Add($propertyName, $object) | Out-Null } catch { Write-Warning "Property `"$propertyName`" Not Found For Type $($this.Type) ($( $this.Description ))" } } catch { Write-Warning ($error[0].Exception.Message) } } } hidden [OrderedDictionary]GetProperties() { return $this.Properties } # Used by types 9, 41 and 42 # Segment Group Number, Bus Number, Device/Function Number hidden [StringValue]Get_BusAddress([Byte]$offset) { $segmentGroupNumber = $this.GetWordAtOffset($offset) $busNumber = $this.GetByteAtOffset($offset + 0x02) $deviceAndFunctionNumber = $this.GetByteAtOffset($offset + 0x03) if (($segmentGroupNumber -ne 0xFFFF) -or ($busNumber -ne 0xFF) -or ($deviceAndFunctionNumber -ne 0xFF)) { $busAddress = "{0:x4}:{1:x2}:{2:x2}.{3}" -f $segmentGroupNumber, $busNumber, ($deviceAndFunctionNumber -shr 3), ($deviceAndFunctionNumber -band 0x7) return [StringValue]::new( [Ordered]@{ SegmentGroupNumber = $segmentGroupNumber; BusNumber = $busNumber; DeviceNumber = ($deviceAndFunctionNumber -shr 3); FunctionNumber = ($deviceAndFunctionNumber -band 0x7) }, $busAddress.ToUpper() ) } else { $notDefined = Get-LocalizedString "NOT_DEFINED" return [StringValue]::new(-1, $notDefined) } } } ################################################################################################################################### # Type 0 # ################################################################################################################################### class BIOSInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames static BIOSInformation() { $stringTables = [BIOSInformation]::GetStringTables("Type_0") [BIOSInformation]::StringArrays = $stringTables.StringArrays [BIOSInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Vendor" ) $labels.Add( "Version" ) $labels.Add( "ReleaseDate" ) $labels.Add( "AddressSegment" ) $labels.Add( "ROMSize" ) $labels.Add( "ImageSize" ) $labels.Add( "Characteristics" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 4) ) { $labels.Add( "Release" ) $labels.Add( "FirmwareRelease" ) } [BIOSInformation]::PropertyNames = $labels } BIOSInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base ($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Vendor hidden [SMBString]GetVendor() { return $this.GetStringAtOffset(0x04) } # Get Version hidden [SMBString]GetVersion() { return $this.GetStringAtOffset(0x05) } # Get AddressSegment hidden [StringValue]GetAddressSegment() { $address = $this.GetWordAtOffset(0x06) return [StringValue]::new($address, "0x{0:X4}0") } # Get ReleaseDate hidden [StringValueDateTime]GetReleaseDate() { $releaseDate = $($this.GetStringAtOffset(0x08)).DisplayValue if ([String]::IsNullOrEmpty($releaseDate)) { $notAvailable = Get-LocalizedString "NOT_AVAILABLE" return [StringValueDateTime]::new($null, $notAvailable) } else { $culture = [CultureInfo]::CreateSpecificCulture("en-US") [DateTime]$date = [DateTime]::new(0) if( [DateTime]::TryParse($releaseDate, $culture, [DateTimeStyles]::None, [ref]$date) ) { return [StringValueDateTime]::new($date) } else { return [StringValueDateTime]::new($releaseDate, $releaseDate) } } } # Get ROMSize hidden [StringValueMemorySize]GetROMSize() { $size = 0 $ROMSize = $this.GetByteAtOffset(0x09) $sizeInBytes = $ROMSize * 1kb $unit = [MemorySizeUnit]::kB if ( $ROMSize -eq 0xFF ) { if ( [SMBIOS]::Version -ge [Version]::new(3, 1) ) { $extendedSize = $this.GetExtendedROMSize() if ($extendedSize) { if ($extendedSize -shr 14) { $unit = [MemorySizeUnit]::GB $size = $extendedSize -band 0x3FFF $sizeInBytes = $size * 1gb } else { $unit = [MemorySizeUnit]::MB $size = $extendedSize -band 0x3FFF $sizeInBytes = $size * 1mb } } } else { $size = 64 * ($ROMSize + 1) $sizeInBytes = $size * 1kb } } else { $size = 64 * ($ROMSize + 1) $sizeInBytes = $size * 1kb } return [StringValueMemorySize]::new($sizeInBytes, $unit) } # Get ImageSize hidden [StringValueMemorySize]GetImageSize() { $address = $this.GetAddressSegment() $size = (0x10000 - $address) * 16 $sizeInBytes = $size if ($size % 1024) { $unit = [MemorySizeUnit]::B } else { $unit = [MemorySizeUnit]::kB } return [StringValueMemorySize]::new($sizeInBytes, $unit) } # Get Characteristics hidden [StringValue[]]GetCharacteristics() { $featuresList = [Collections.ArrayList]::new() $BIOSCharacteristics = $this.GetQuadWordAtOffset(0x0A) $characteristics = [BitField]::LowUInt64($BIOSCharacteristics) $reservedCharacteristics = [BitField]::HighUInt64($BIOSCharacteristics) $offset = 0 $featuresList = $featuresList + [BitFieldConverter]::ToStringValueArray($characteristics, 32, "Characteristics", [ref]$this) $offset = $offset + 32 if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $characteristicsByte1 = $this.GetByteAtOffset(0x12) if ($characteristicsByte1 -gt 0) { $featuresList = $featuresList + [BitFieldConverter]::ToStringValueArray($characteristicsByte1, 8, "CharacteristicsByte1", $offset, [ref]$this) } $offset = $offset + 8 } if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $characteristicsByte2 = $this.GetByteAtOffset(0x13) if ($characteristicsByte2 -gt 0) { $featuresList = $featuresList + [BitFieldConverter]::ToStringValueArray($characteristicsByte2, 8, "CharacteristicsByte2", $offset, [ref]$this) } $offset = $offset + 8 } $featuresList = $featuresList + [BitFieldConverter]::ToStringValueArray($reservedCharacteristics, 32, "ReservedCharacteristics", $offset, [ref]$this) return $featuresList } # Get Release hidden [StringValueVersion]GetRelease() { $majorRelease = $this.GetByteAtOffset(0x14) $minorRelease = $this.GetByteAtOffset(0x15) $version = [Version]::new($majorRelease, $minorRelease) return [StringValueVersion]::new($version, [Version]::new(255.255), "{0}", "NOT_AVAILABLE") } # Get FirmwareRelease hidden [StringValueVersion]GetFirmwareRelease() { $majorRelease = $this.GetByteAtOffset(0x16) $minorRelease = $this.GetByteAtOffset(0x17) $version = [Version]::new($majorRelease, $minorRelease) return [StringValueVersion]::new($version, [Version]::new(255.255), "{0}", "NOT_AVAILABLE") } # Get ExtendedROMSize hidden [UInt16]GetExtendedROMSize() { return $this.GetWordAtOffset(0x18) } } ################################################################################################################################### # Type 1 # ################################################################################################################################### class SystemInformation : SMBIOSStructure { static [Hashtable]$StringArrays static [Hashtable]$StringArrayNameAlias static [Hashtable]$LocalizedStrings static [Array]$PropertyNames static SystemInformation() { $stringTables = [SystemInformation]::GetStringTables("Type_1") [SystemInformation]::StringArrays = $stringTables.StringArrays [SystemInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Manufacturer" ) $labels.Add( "ProductName" ) $labels.Add( "Version" ) $labels.Add( "SerialNumber" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "UUID" ) $labels.Add( "WakeUpType" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 4) ) { $labels.Add( "SKUNumber" ) $labels.Add( "Family" ) } [SystemInformation]::PropertyNames = $labels } SystemInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Manufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x04) } # Get ProductName hidden [SMBString]GetProductName() { return $this.GetStringAtOffset(0x05) } # Get Version hidden [SMBString]GetVersion() { return $this.GetStringAtOffset(0x06) } # Get SerialNumber hidden [SMBString]GetSerialNumber() { return $this.GetStringAtOffset(0x07) } # Get UUID hidden [StringValue]GetUUID() { $UUID = $null $rawUUID = [Byte[]][ArraySegment[Byte]]::new($this.data, 0x08, 16) $only0x00 = [Linq.Enumerable]::All($rawUUID, [Func[byte,bool]]{ $args[0] -eq 0x00 }) $only0xFF = [Linq.Enumerable]::All($rawUUID, [Func[byte,bool]]{ $args[0] -eq 0xFF }) if ($only0x00) { $value = 0x00 $UUID = Get-LocalizedString "NOT_SETTABLE" } elseif ($only0xFF) { $value = 0xFF $UUID = Get-LocalizedString "NOT_PRESENT" } else { $value = [Guid]::new($rawUUID) $UUID = $value.ToString().ToUpper() } return [StringValue]::new($value, $UUID) } # Get WakeUpType hidden [StringValue]GetWakeUpType() { $wakeUpType = $this.GetByteAtOffset(0x18) return [StringValue]::new($wakeUpType, "WakeUpType", [ref]$this) } # Get SKUNumber hidden [SMBString]GetSKUNumber() { return $this.GetStringAtOffset(0x19) } # Get Family hidden [SMBString]GetFamily() { return $this.GetStringAtOffset(0x1A) } } ################################################################################################################################### # Type 2 # ################################################################################################################################### class BaseboardInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static BaseboardInformation() { $stringTables = [BaseboardInformation]::GetStringTables("Type_2") [BaseboardInformation]::StringArrays = $stringTables.StringArrays [BaseboardInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Manufacturer" ) $labels.Add( "Product" ) $labels.Add( "Version" ) $labels.Add( "SerialNumber" ) $labels.Add( "AssetTag" ) $labels.Add( "Features" ) $labels.Add( "LocationInChassis" ) $labels.Add( "ChassisHandle" ) $labels.Add( "BoardType" ) $labels.Add( "ContainedObjectHandles" ) } [BaseboardInformation]::PropertyNames = $labels } BaseboardInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Manufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x04) } # Get Product hidden [SMBString]GetProduct() { return $this.GetStringAtOffset(0x05) } # Get Version hidden [SMBString]GetVersion() { return $this.GetStringAtOffset(0x06) } # Get SerialNumber hidden [SMBString]GetSerialNumber() { return $this.GetStringAtOffset(0x07) } # Get AssetTag hidden [SMBString]GetAssetTag() { return $this.GetStringAtOffset(0x08) } # Get Features hidden [StringValue[]]GetFeatures() { $features = $this.GetByteAtOffset(0x09) return [BitFieldConverter]::ToStringValueArray($features, "Features", [ref]$this) } # Get LocationInChassis hidden [SMBString]GetLocationInChassis() { return $this.GetStringAtOffset(0x0A) } # Get ChassisHandle hidden [UInt16]GetChassisHandle() { return $this.GetWordAtOffset(0x0B) } # Get BoardType hidden [StringValue]GetBoardType() { $boardType = $this.GetByteAtOffset(0x0D) return [StringValue]::new($boardType, "BoardType", [ref]$this) } # Get ContainedObjectsHandles hidden [Array]GetContainedObjectHandles() { $numberOfContainedObjectHandles = $this.GetByteAtOffset(0x0E) $objectsHandles = [List[UInt16]]::new() if ($numberOfContainedObjectHandles -gt 0) { for ($objectHandle = 0 ; $objectHandle -lt $numberOfContainedObjectHandles ; $objectHandle++) { $handle = $this.GetWordAtOffset(0x0F + ($objectHandle * 2)) $objectsHandles.Add( $handle ) } return $objectsHandles } $objectsHandles.Add($numberOfContainedObjectHandles) return $objectsHandles } } ################################################################################################################################### # Type 3 # ################################################################################################################################### class SystemEnclosure : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames hidden [ArrayList]$PropertyNamesEx static SystemEnclosure() { $stringTables = [SystemEnclosure]::GetStringTables("Type_3") [SystemEnclosure]::StringArrays = $stringTables.StringArrays [SystemEnclosure]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Manufacturer" ) $labels.Add( "ChassisType" ) $labels.Add( "Lock" ) $labels.Add( "Version" ) $labels.Add( "SerialNumber" ) $labels.Add( "AssetTag" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "BootUpState" ) $labels.Add( "PowerSupplyState" ) $labels.Add( "ThermalState" ) $labels.Add( "SecurityStatus" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "OEMDefined" ) $labels.Add( "Heigth" ) $labels.Add( "NumberOfPowerCords" ) $labels.Add( "ContainedElements" ) } [SystemEnclosure]::PropertyNames = $labels } SystemEnclosure([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 7) ) { $labels.Add( "SKUNumber" ) } $this.PropertyNamesEx = $labels } # Get Manufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x4) } # Get ChassisType hidden [StringValue]GetChassisType() { $type = $this.GetByteAtOffset(0x05) $chassisType = [BitField]::Extract($type, 0, 7) return [StringValue]::new($chassisType, "ChassisType", [ref]$this) } # Get Lockable hidden [StringValue]GetLock() { $type = $this.GetByteAtOffset(0x05) $lock = [BitField]::Get($type, 7) return [StringValue]::new($lock, "Lock", [ref]$this) } # Get Version hidden [SMBString]GetVersion() { return $this.GetStringAtOffset(0x06) } # Get SerialNumber hidden [SMBString]GetSerialNumber() { return $this.GetStringAtOffset(0x07) } # Get AssetTag hidden [SMBString]GetAssetTag() { return $this.GetStringAtOffset(0x08) } # Get _State hidden [StringValue]_State([Byte]$state) { return [StringValue]::new($state, "_State", [ref]$this) } # Get BootUpState hidden [StringValue]GetBootUpState() { $bootUpState = $this.GetByteAtOffset(0x09) return $this._State($bootUpState) } # Get PowerSupplyState hidden [StringValue]GetPowerSupplyState() { $powerSupplyState = $this.GetByteAtOffset(0x0A) return $this._State($powerSupplyState) } # Get ThermalState hidden [StringValue]GetThermalState() { $thermalState = $this.GetByteAtOffset(0x0B) return $this._State($thermalState) } # Get SecurityStatus hidden [StringValue]GetSecurityStatus() { $securityStatus = $this.GetByteAtOffset(0x0C) return [StringValue]::new($securityStatus, "SecurityStatus", [ref]$this) } # Get OEMDefined hidden [UInt16]GetOEMDefined() { return $this.GetWordAtOffset(0x0D) } # Get Heigth hidden [StringValue]GetHeigth() { $heigth = $this.GetByteAtOffset(0x11) return [StringValue]::new($heigth, 0x00, "{0} U", "UNSPECIFIED") } # Get NumberOfPowerCords hidden [StringValue]GetNumberOfPowerCords() { $powerCords = $this.GetByteAtOffset(0x12) return [StringValue]::new($powerCords, 0x00, $null, "UNSPECIFIED") } # Get ContainedElements hidden [StringValue[]]GetContainedElements() { $containedElementCount = $this.GetByteAtOffset(0x13) $containedElementRecordLength = $this.GetByteAtOffset(0x14) $containedElementsList = [Collections.ArrayList]::new() if ($containedElementCount -gt 0) { $containedElements = [ArraySegment[Byte]]::new($this.data, 0x15, $containedElementCount * $containedElementRecordLength) for ($containedElement = 0 ; $containedElement -lt $containedElementCount * $containedElementRecordLength ; $containedElement = $containedElement + $containedElementRecordLength) { $containedElementType = $containedElements.Array[$containedElement] $type = [BitField]::Extract($containedElementType, 0, 7) $minValue = $containedElements.Array[$containedElement + 1] $maxValue = $containedElements.Array[$containedElement + 2] if ([BitField]::Get($containedElementType, 7)) { $element = [Ordered]@{ TypeSelect = 1 ; Type = $type ; NumberOfElements = @($minValue..$maxValue) } $containedElementsList.Add([StringValue]::new($element, "$([SMBIOS]::Types[$type].Name) ($minValue..$maxValue)")) } else { $boardTypes = [BaseboardInformation]::StringArrays["BoardType"] $element = [Ordered]@{ TypeSelect = 0 ; Type = $type ; NumberOfElements = @($minValue..$maxValue) } $containedElementsList.Add([StringValue]::new($element, "$($boardTypes.$type) ($minValue..$maxValue)")) } } return $containedElementsList } $none = Get-LocalizedString "NONE" return [StringValue]::new(-1, $none) } # Get SKUNumber hidden [SMBString]GetSKUNumber() { $containedElementCount = $this.GetByteAtOffset(0x13) $containedElementRecordLength = $this.GetByteAtOffset(0x14) return $this.GetStringAtOffset(0x15 + $containedElementCount * $containedElementRecordLength) } } ################################################################################################################################### # Type 4 # ################################################################################################################################### class ProcessorInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames hidden [ArrayList]$PropertyNamesEx static ProcessorInformation() { $stringTables = [ProcessorInformation]::GetStringTables("Type_4") [ProcessorInformation]::StringArrays = $stringTables.StringArrays [ProcessorInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "SocketDesignation" ) $labels.Add( "_Type" ) $labels.Add( "Family" ) $labels.Add( "Manufacturer" ) $labels.Add( "ID" ) $labels.Add( "Signature" ) $labels.Add( "Features" ) $labels.Add( "Version" ) $labels.Add( "Voltage" ) $labels.Add( "ExternalClock" ) $labels.Add( "MaxSpeed" ) $labels.Add( "CurrentSpeed" ) $labels.Add( "SocketPopulated" ) $labels.Add( "Status" ) $labels.Add( "Upgrade" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "L1CacheHandle" ) $labels.Add( "L2CacheHandle" ) $labels.Add( "L3CacheHandle" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "SerialNumber" ) $labels.Add( "AssetTag" ) $labels.Add( "PartNumber" ) } [ProcessorInformation]::PropertyNames = $labels } ProcessorInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 5) ) { $labels.Add( "CoreCount" ) $labels.Add( "CoreEnabled" ) $labels.Add( "ThreadCount" ) $labels.Add( "Characteristics" ) } if ( [SMBIOS]::Version -ge [Version]::new(3, 6) ) { $labels.Add( "ThreadEnabled" ) } $this.PropertyNamesEx = $labels } # Get VendorID hidden [String]GetVendorID() { $manufacturer = $this.GetManufacturer() $version = $this.GetVersion() # GenuineIntel if ( $manufacturer -like "*Intel*" ) { return "GenuineIntel" } # AuthenticAMD if ( ($manufacturer -like "*AMD*") -or ($version -like "*AMD*") ) { return "AuthenticAMD" } # Red Hat (Nutanix) if ( $manufacturer -like "*Red Hat*" ) { return "GenuineIntel" } # ARM $family = $this.GetFamily().Value if ($(@(0x100..0x103) + 0x118 + 0x119) -contains $family) { return "ARM" } return $null } # Get SocketDesignation hidden [SMBString]GetSocketDesignation() { return $this.GetStringAtOffset(0x04) } # Get Type hidden [StringValue]Get_Type() { $processorType = $this.GetByteAtOffset(0x05) return [StringValue]::new($processorType, "ProcessorType", [ref]$this) } # Get Family hidden [StringValue]GetFamily() { $family = $this.GetByteAtOffset(0x06) if ($family -eq 0xFE) { $family = $this.GetFamily2() } return [StringValue]::new($family, "Family", [ref]$this) } # Get Menufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x07) } # Get ID hidden [StringValue]GetID() { $id = $this.GetQuadWordAtOffset(0x08) [Byte[]]$array = [BitConverter]::GetBytes([UInt64]$id) [Byte[]]$reverseArray = [Linq.Enumerable]::Reverse($array) $processorId = [BitConverter]::ToString($reverseArray).Replace("-","") return [StringValue]::new($id, $processorId) } hidden [StringValueOrderedDictionary]GetSignatureGenuineIntel([UInt32]$signature) { $type = [BitField]::Extract($signature, 12, 2) $familyId = [BitField]::Extract($signature, 8, 4) if ($familyId -eq 0xF) { $familyIdExt = [BitField]::Extract($signature, 20, 8) $family = $familyId + $familyIdExt } else { $family = $familyId } $modelId = [BitField]::Extract($signature, 4, 4) if (($familyId -eq 0x6) -or ($familyId -eq 0xF)) { $modelIdExt = [BitField]::Extract($signature, 16, 4) -shl 4 $model = $modelId + $modelIdExt } else { $model = $modelId } $stepping = [BitField]::Extract($signature, 0, 4) $orderedSignature = [Ordered]@{ Type = $type ; Family = $family ; Model = $model ; Stepping = $stepping } return [StringValueOrderedDictionary]::new($orderedSignature) } hidden [StringValueOrderedDictionary]GetSignatureAuthenticAMD([UInt32]$signature) { $extFamily = [BitField]::Extract($signature, 20, 8) $extModel = [BitField]::Extract($signature, 16, 4) -shl 4 $baseFamily = [BitField]::Extract($signature, 8, 4) $baseModel = [BitField]::Extract($signature, 4, 4) $stepping = [BitField]::Extract($signature, 0, 4) if ($baseFamily -lt 0xF) { $family = $baseFamily } else { $family = $baseFamily + $extFamily } if ($baseModel -lt 0xF) { $model = $baseModel } else { $model = $baseModel + $extModel } $orderedSignature = [Ordered]@{ Family = $family ; Model = $model ; Stepping = $stepping } return [StringValueOrderedDictionary]::new($orderedSignature) } hidden [StringValueOrderedDictionary]GetSignatureArm([UInt32]$signature) { $value = $this.GetWordAtOffset(0x26) $arm64SocID = [BitField]::Get($value, 9) if ($arm64SocID) { $bank = [BitField]::Extract($signature, 24, 7) $manufacturer = [BitField]::Extract($signature, 16, 8) $id = [BitField]::Extract($signature, 0, 16) $processorID = $this.GetID().Value $highWord = [BitField]::HighUInt64($processorID) $revision = [BitField]::Extract($highWord, 0, 32) $orderedSignature = [Ordered]@{ JEP106Bank = $bank ; JEP106Manufacturer = $manufacturer ; ID = $id ; Revision = $revision } return [StringValueOrderedDictionary]::new($orderedSignature) } else { $implementer = [BitField]::Extract($signature, 24, 8) $variant = [BitField]::Extract($signature, 20, 4) $arch = [BitField]::Extract($signature, 16, 4) $part = [BitField]::Extract($signature, 4, 12) $revision = [BitField]::Extract($signature, 0, 4) $orderedSignature = [Ordered]@{ Implementer = $implementer ; Variant = $variant ; Architecture = $arch ; Part = $part ; Revision = $revision } return [StringValueOrderedDictionary]::new($orderedSignature) } return $null } # Get Signature hidden [StringValueOrderedDictionary]GetSignature() { $id = $this.GetQuadWordAtOffset(0x08) $signature = [BitField]::LowUInt64($id) $vendorID = $this.GetVendorID() switch ($vendorID) { "GenuineIntel" { return $this.GetSignatureGenuineIntel($signature) } "AuthenticAMD" { return $this.GetSignatureAuthenticAMD($signature) } "ARM" { return $this.GetSignatureArm($signature) } } return [StringValueOrderedDictionary]::new() } # Get Features hidden [StringValue[]]GetFeatures() { $id = $this.GetQuadWordAtOffset(0x08) $flags = [BitField]::HighUInt64($id) $vendorID = $this.GetVendorID() if ( ($vendorID -eq "GenuineIntel") -or ($vendorID -eq "AuthenticAMD") ) { return [BitFieldConverter]::ToStringValueArray($flags, $vendorID + "Features", [ref]$this) } else { return [StringValue]::new(0, 0x00, $null, $(Get-LocalizedString "UNKNOWN")) } return @() } # Get Version hidden [SMBString]GetVersion() { return $this.GetStringAtOffset(0x10) } # Get Voltage hidden [StringValue[]]GetVoltage() { $value = $this.GetByteAtOffset(0x11) $voltagesList = [Collections.ArrayList]::new() # Legacy voltage mode if ($value -band 0x80) { [Float]$voltage = ($value -band 0x7F) / 10 $voltagesList.Add( [StringValue]::new($voltage, "{0:F01} V") ) } elseif (($value -band 0x07) -eq 0x00) { $voltagesList.Add( [StringValue]::new($value, 0x00, $null, "UNKNOWN") ) } else { $voltageCapability = @( [Float]5.0, [Float]3.3, [Float]2.9 ) $voltages = [BitFieldConverter]::ToArray($value, 3, $voltageCapability) if ($voltages) { foreach($voltage in $voltages) { $voltagesList.Add( [StringValue]::new($voltage, "{0:F01} V") ) } } } return $voltagesList } # Get ExternalClock hidden [StringValue]GetExternalClock() { $externalClock = $this.GetWordAtOffset(0x12) if ($externalClock -eq 0) { return [StringValue]::new($externalClock, 0x00, $null, "UNKNOWN") } else { return [StringValue]::new($externalClock, "{0} MHz") } } # Get MaxSpeed hidden [StringValue]GetMaxSpeed() { $maxSpeed = $this.GetWordAtOffset(0x14) if ($maxSpeed -eq 0) { return [StringValue]::new($maxSpeed, 0x00, $null, "UNKNOWN") } else { return [StringValue]::new($maxSpeed, "{0} MHz") } } # Get CurrentSpeed hidden [StringValue]GetCurrentSpeed() { $currentSpeed = $this.GetWordAtOffset(0x16) if ($currentSpeed -eq 0) { return [StringValue]::new($currentSpeed, 0x00, $null, "UNKNOWN") } else { return [StringValue]::new($currentSpeed, "{0} MHz") } } # Get SocketPopulated hidden [bool]GetSocketPopulated() { $value = $this.GetByteAtOffset(0x18) return [BitField]::Get($value, 6) } # Get Status hidden [StringValue]GetStatus() { $value = $this.GetByteAtOffset(0x18) $status = [BitField]::Extract($value, 0, 3) return [StringValue]::new($status, "Status", [ref]$this) } # Get Upgradable hidden [StringValue]GetUpgrade() { $upgradable = $this.GetByteAtOffset(0x19) return [StringValue]::new($upgradable, "Upgrade", [ref]$this) } # Get CacheHandle hidden [StringValue]GetCacheHandle([int]$offset, [int]$level) { $handle = $this.GetWordAtOffset($offset) if ($handle -eq 0xFFFF) { if ([SMBIOS]::Version -lt [Version]::new(2, 3)) { $notLnCache = [String]::Format($(Get-LocalizedString "NOT_LN_CACHE"), $level) return [StringValue]::new($handle, $notLnCache) } else { return [StringValue]::new($handle, $(Get-LocalizedString "NOT_PROVIDED")) } } else { return [StringValue]::new($handle) } } # Get L1CacheHandle hidden [StringValue]GetL1CacheHandle() { return $this.GetCacheHandle(0x1A, 1) } # Get L2CacheHandle hidden [StringValue]GetL2CacheHandle() { return $this.GetCacheHandle(0x1C, 2) } # Get L3CacheHandle hidden [StringValue]GetL3CacheHandle() { return $this.GetCacheHandle(0x1E, 3) } # Get SerialNumber hidden [SMBString]GetSerialNumber() { return $this.GetStringAtOffset(0x20) } # Get AssetTag hidden [SMBString]GetAssetTag() { return $this.GetStringAtOffset(0x21) } # Get PartNumber hidden [SMBString]GetPartNumber() { return $this.GetStringAtOffset(0x22) } # Get CoreCount hidden [UInt16]GetCoreCount() { $coreCount = $this.GetByteAtOffset(0x23) if ( ( $coreCount -eq 0xFF) -and ( [SMBIOS]::Version -ge [Version]::new(3, 0) ) ) { $coreCount = $this.GetCoreCount2() } return $coreCount } # Get CoreEnabled hidden [UInt16]GetCoreEnabled() { $coreEnabled = $this.GetByteAtOffset(0x24) if ( ( $coreEnabled -eq 0xFF) -and ( [SMBIOS]::Version -ge [Version]::new(3, 0) ) ) { $coreEnabled = $this.GetCoreEnabled2() } return $coreEnabled } # Get ThreadCount hidden [UInt16]GetThreadCount() { $threadCount = $this.GetByteAtOffset(0x25) if ( ( $threadCount -eq 0xFF) -and ( [SMBIOS]::Version -ge [Version]::new(3, 0) ) ) { $threadCount = $this.GetThreadCount2() } return $threadCount } # Get Characteristics hidden [StringValue[]]GetCharacteristics() { $characteristics = $this.GetWordAtOffset(0x26) return [BitFieldConverter]::ToStringValueArray($characteristics, "Characteristics", [ref]$this) } # Get Family2 hidden [UInt16]GetFamily2() { return $this.GetWordAtOffset(0x28) } # Get GetCoreCount2 hidden [UInt16]GetCoreCount2() { return $this.GetWordAtOffset(0x2A) } # Get GetCoreCount2 hidden [UInt16]GetCoreEnabled2() { return $this.GetWordAtOffset(0x2C) } # Get GetCoreCount2 hidden [UInt16]GetThreadCount2() { return $this.GetWordAtOffset(0x2E) } # Get GetThreadEnabled hidden [UInt16]GetThreadEnabled() { return $this.GetWordAtOffset(0x30) } } ################################################################################################################################### # Type 5 # ################################################################################################################################### class MemoryControllerInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames static MemoryControllerInformation() { $stringTables = [MemoryControllerInformation]::GetStringTables("Type_5") [MemoryControllerInformation]::StringArrays = $stringTables.StringArrays [MemoryControllerInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "ErrorDetectingMethod" ) $labels.Add( "ErrorCorrectingCapabilities" ) $labels.Add( "SupportedInterleave" ) $labels.Add( "CurrentInterleave" ) $labels.Add( "MaximumMemoryModuleSize" ) $labels.Add( "MaximumTotalMemorySize" ) $labels.Add( "SupportedSpeeds" ) $labels.Add( "SupportedMemoryTypes" ) $labels.Add( "MemoryModuleVoltage" ) $labels.Add( "AssociatedMemorySlots" ) $labels.Add( "MemoryModuleConfigurationHandles" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "EnabledErrorCorrectingCapabilities" ) } [MemoryControllerInformation]::PropertyNames = $labels } MemoryControllerInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $this.Obsolete = $true } # Get ErrorDetectingMethod hidden [StringValue]GetErrorDetectingMethod() { $errorDetectingMethod = $this.GetByteAtOffset(0x4) return [StringValue]::new($errorDetectingMethod, "ErrorDetectingMethod", [ref]$this) } # Get ErrorCorrectingCapabilities hidden [StringValue[]]GetErrorCorrectingCapabilities() { $errorCorrectingCapabilities = $this.GetByteAtOffset(0x5) return [BitFieldConverter]::ToStringValueArray($errorCorrectingCapabilities, 6, "ErrorCorrectingCapabilities", [ref]$this) } # Get SupportedInterleave hidden [StringValue]GetSupportedInterleave() { $supportedInterleave = $this.GetByteAtOffset(0x6) return [StringValue]::new($supportedInterleave, "_Interleave", [ref]$this) } # Get CurrentInterleave hidden [StringValue]GetCurrentInterleave() { $currentInterleave = $this.GetByteAtOffset(0x7) return [StringValue]::new($currentInterleave, "_Interleave", [ref]$this) } # Get MaximumMemoryModuleSize hidden [StringValueMemorySize]GetMaximumMemoryModuleSize() { $size = $this.GetByteAtOffset(0x08) $maximumSizePerSlot = [Math]::Pow(2, $size) $unit = [MemorySizeUnit]::MB $sizeInBytes = $maximumSizePerSlot * 1mb return [StringValueMemorySize]::new($sizeInBytes, $unit) } # Get MaximumTotalMemorySize hidden [StringValueMemorySize]GetMaximumTotalMemorySize() { $maximumMemoryModuleSize = $this.GetMaximumMemoryModuleSize().Value $associatedMemorySlots = $this.GetAssociatedMemorySlots() $maximumTotalMemorySize = $maximumMemoryModuleSize * $associatedMemorySlots $unit = [MemorySizeUnit]::MB $sizeInBytes = $maximumTotalMemorySize * 1mb return [StringValueMemorySize]::new($sizeInBytes, $unit) } # Get SupportedSpeeds hidden [StringValue[]]GetSupportedSpeeds() { $supportedSpeeds = $this.GetWordAtOffset(0x09) return [BitFieldConverter]::ToStringValueArray($supportedSpeeds, 5, "SupportedSpeeds", [ref]$this) } # Get SupportedMemoryTypes hidden [StringValue[]]GetSupportedMemoryTypes() { $supportedTypes = $this.GetWordAtOffset(0x0B) return [BitFieldConverter]::ToStringValueArray($supportedTypes, 11, "SupportedMemoryTypes", [ref]$this) } # Get MemoryModuleVoltage hidden [StringValue[]]GetMemoryModuleVoltage() { $memoryModuleVoltage = $this.GetByteAtOffset(0x5) return [BitFieldConverter]::ToStringValueArray($memoryModuleVoltage, 3, "MemoryModuleVoltage", [ref]$this) } # Get AssociatedMemorySlots hidden [Byte]GetAssociatedMemorySlots() { return $this.GetByteAtOffset(0x0E) } # Get MemoryModuleConfigurationHandles hidden [Array]GetMemoryModuleConfigurationHandles() { $slots = $this.GetAssociatedMemorySlots() $handles = [Collections.ArrayList]::new() for ($offset = 0; $offset -lt $slots ; $offset++) { $handles.Add($this.GetWordAtOffset(0x0F + ( 2 * $offset ))) } return $handles } # Get EnabledErrorCorrectingCapabilities hidden [StringValue[]]GetEnabledErrorCorrectingCapabilities() { $slots = $this.GetAssociatedMemorySlots() $capabilities = $this.GetByteAtOffset(0x0F + ( 2 * $slots )) return [BitFieldConverter]::ToStringValueArray($capabilities, 6, "ErrorCorrectingCapabilities", [ref]$this) } } ################################################################################################################################### # Type 6 # ################################################################################################################################### class MemoryModuleInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames static MemoryModuleInformation() { $stringTables = [MemoryModuleInformation]::GetStringTables("Type_6") [MemoryModuleInformation]::StringArrays = $stringTables.StringArrays [MemoryModuleInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "SocketDesignation" ) $labels.Add( "BankConnections" ) $labels.Add( "CurrentSpeed" ) $labels.Add( "CurrentMemoryType" ) $labels.Add( "InstalledSize" ) $labels.Add( "InstalledSizeConnection" ) $labels.Add( "EnabledSize" ) $labels.Add( "EnabledSizeConnection" ) $labels.Add( "ErrorStatus" ) } [MemoryModuleInformation]::PropertyNames = $labels } MemoryModuleInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $this.Obsolete = $true } # Get SocketDesignation hidden [SMBString]GetSocketDesignation() { return $this.GetStringAtOffset(0x04) } # Get BankConnections hidden [StringValue[]]GetBankConnections() { $bankConnections = $this.GetByteAtOffset(0x05) $connections = [Collections.ArrayList]::new() if ($bankConnections -eq 0xFF) { $connections.Add( [StringValue]::new(-1, $(Get-LocalizedString "NONE")) ) } $bank = $bankConnections -shr 4 if ($bank -ne 0xF) { $connections.Add([StringValue]::new($bank, "RAS $bank")) } $bank = $bankConnections -band 0x0F if ($bank -ne 0xF) { $connections.Add([StringValue]::new($bank, "RAS $bank")) } return $connections } # Get CurrentSpeed hidden [StringValue]GetCurrentSpeed() { $currentSpeed = $this.GetByteAtOffset(0x06) return [StringValue]::new($currentSpeed, 0x00, "{0} ns", "UNKNOWN") } # Get CurrentMemoryType hidden [StringValue[]]GetCurrentMemoryType() { $currentMemoryType = $this.GetWordAtOffset(0x07) if (($currentMemoryType -band 0x07FF) -eq 0) { return [StringValue]::new(-1, $(Get-LocalizedString "NONE")) } else { return [BitFieldConverter]::ToStringValueArray($currentMemoryType, "CurrentMemoryType", [ref]$this) } } hidden [StringValueMemorySize]_Size($size) { $memorySize = [BitField]::Extract($size, 0, 7) if ($memorySize -eq 0x7D) { return [StringValueMemorySize]::new($size, "_Size", [ref]$this, -1, [MemorySizeUnit]::Unknown) } elseif ($memorySize -eq 0x7E) { return [StringValueMemorySize]::new($size, "_Size", [ref]$this, -1, [MemorySizeUnit]::None) } elseif ($memorySize -eq 0x7F) { return [StringValueMemorySize]::new($size, "_Size", [ref]$this, -1, [MemorySizeUnit]::None) } else { $effectiveSize = [Math]::Pow(2, $memorySize) $unit = [MemorySizeUnit]::MB $sizeInBytes = $effectiveSize * 1mb return [StringValueMemorySize]::new($sizeInBytes, $unit) } } hidden [StringValue]_SizeConnection($size) { $connection = [BitField]::Get($size, 8) if ($size -eq 0x7F) { return [StringValue]::new($connection, $(Get-LocalizedString "NOT_AVAILABLE")) } else { return [StringValue]::new($connection, "_Connection", [ref]$this) } } # Get InstalledSize hidden [StringValueMemorySize]GetInstalledSize() { $installedSize = $this.GetByteAtOffset(0x09) return $this._Size($installedSize) } # Get InstalledSizeConnection hidden [StringValue]GetInstalledSizeConnection() { $installedSize = $this.GetByteAtOffset(0x09) return $this._SizeConnection($installedSize) } # Get EnabledSize hidden [StringValueMemorySize]GetEnabledSize() { $enabledSize = $this.GetByteAtOffset(0x0A) return $this._Size($enabledSize) } # Get EnabledSizeConnection hidden [StringValue]GetEnabledSizeConnection() { $installedSize = $this.GetByteAtOffset(0x09) return $this._SizeConnection($installedSize) } # Get ErrorStatus hidden [StringValue]GetErrorStatus() { $errorStatus = $this.GetByteAtOffset(0x0B) if ($errorStatus -le 0x04) { return [StringValue]::new($errorStatus, "ErrorStatus", [ref]$this) } else { return [StringValue]::new($errorStatus -band 0x03) } } } ################################################################################################################################### # Type 7 # ################################################################################################################################### class CacheInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames static CacheInformation() { $stringTables = [CacheInformation]::GetStringTables("Type_7") [CacheInformation]::StringArrays = $stringTables.StringArrays [CacheInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "SocketDesignation" ) $labels.Add( "Enabled" ) $labels.Add( "Socketed" ) $labels.Add( "Level" ) $labels.Add( "OperationalMode" ) $labels.Add( "Location" ) $labels.Add( "MaximumCacheSize" ) $labels.Add( "InstalledSize" ) $labels.Add( "SupportedSRAMType" ) $labels.Add( "CurrentSRAMType" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "CacheSpeed" ) $labels.Add( "ErrorCorrectionType" ) $labels.Add( "SystemCacheType" ) $labels.Add( "Associativity" ) } [CacheInformation]::PropertyNames = $labels } CacheInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get SocketDesignation hidden [SMBString]GetSocketDesignation() { return $this.GetStringAtOffset(0x04) } # Get Enabled hidden [bool]GetEnabled() { $cacheConfiguration = $this.GetWordAtOffset(0x05) return [BitField]::Get($cacheConfiguration, 7) } # Get OperationalMode hidden [StringValue]GetOperationalMode() { $cacheConfiguration = $this.GetWordAtOffset(0x5) $operationalMode = [BitField]::Extract($cacheConfiguration, 8, 2) return [StringValue]::new($operationalMode, "OperationalMode", [ref]$this) } # Get Location hidden [StringValue]GetLocation() { $cacheConfiguration = $this.GetWordAtOffset(0x05) $location = [BitField]::Extract($cacheConfiguration, 5, 2) return [StringValue]::new($location,"Location", [ref]$this) } # Get Socketed hidden [bool]GetSocketed() { $cacheConfiguration = $this.GetWordAtOffset(0x05) return [BitField]::Get($cacheConfiguration, 3) } # Get Level hidden [Byte]GetLevel() { $cacheConfiguration = $this.GetWordAtOffset(0x05) return [BitField]::Extract($cacheConfiguration, 0, 3) + 1 } # Utility method for MaximumCacheSize, InstalledSize hidden [StringValueMemorySize]_GetSize($maximumSize, $maximumSize2) { if ($maximumSize -eq 0x00) { return [StringValueMemorySize]::new($maximumSize, "_Size", [ref]$this, -1, [MemorySizeUnit]::None) } $granularity = [BitField]::Get($maximumSize, 16) $maxSize = [BitField]::Extract($maximumSize, 0, 15) if ($maximumSize -eq 0xFFFF) { $granularity = [BitField]::Get($maximumSize2, 32) $maxSize = [BitField]::Extract($maximumSize, 0, 31) } $unit = [MemorySizeUnit]::kB if ($granularity) { $sizeInBytes = $maxSize * 64 * 1kb return [StringValueMemorySize]::new($sizeInBytes, $unit) } else { $sizeInBytes = $maxSize * 1kb return [StringValueMemorySize]::new($sizeInBytes, $unit) } } # Get MaximumCacheSize hidden [StringValueMemorySize]GetMaximumCacheSize() { $maximumCacheSize = $this.GetWordAtOffset(0x07) $maximumCacheSize2 = $this.GetWordAtOffset(0x13) return $this._GetSize($maximumCacheSize, $maximumCacheSize2) } # Get InstalledSize hidden [StringValueMemorySize]GetInstalledSize() { $installedSize = $this.GetWordAtOffset(0x09) $installedSize2 = $this.GetWordAtOffset(0x17) return $this._GetSize($installedSize, $installedSize2) } # Get SupportedSRAMType hidden [StringValue[]]GetSupportedSRAMType() { $supportedSRAMType = $this.GetWordAtOffset(0x0B) return [BitFieldConverter]::ToStringValueArray($supportedSRAMType, "_SRAMType", [ref]$this) } # Get CurrentSRAMType hidden [StringValue]GetCurrentSRAMType() { $currentSRAMType = $this.GetWordAtOffset(0x0D) return [BitFieldConverter]::ToStringValue($currentSRAMType, "_SRAMType", [ref]$this) } # Get CacheSpeed hidden [StringValue]GetCacheSpeed() { $cacheSpeed = $this.GetByteAtOffset(0x0F) return [StringValue]::new($cacheSpeed, 0x00, "{0} ns", "UNKNOWN") } # Get ErrorCorrectionType hidden [StringValue]GetErrorCorrectionType() { $errorCorrectionType = $this.GetByteAtOffset(0x10) return [StringValue]::new($errorCorrectionType, "ErrorCorrectionType", [ref]$this) } # Get SystemCacheType hidden [StringValue]GetSystemCacheType() { $systemCacheType = $this.GetByteAtOffset(0x11) return [StringValue]::new($systemCacheType, "SystemCacheType", [ref]$this) } # Get Associativity hidden [StringValue]GetAssociativity() { $associativity = $this.GetByteAtOffset(0x12) return [StringValue]::new($associativity, "Associativity", [ref]$this) } } ################################################################################################################################### # Type 8 # ################################################################################################################################### class PortConnectorInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames static PortConnectorInformation() { $stringTables = [PortConnectorInformation]::GetStringTables("Type_8") [PortConnectorInformation]::StringArrays = $stringTables.StringArrays [PortConnectorInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "InternalReferenceDesignator" ) $labels.Add( "InternalConnectorType" ) $labels.Add( "ExternalReferenceDesignator" ) $labels.Add( "ExternalConnectorType" ) $labels.Add( "PortType" ) } [PortConnectorInformation]::PropertyNames = $labels } PortConnectorInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get InternalReferenceDesignator hidden [SMBString]GetInternalReferenceDesignator() { return $this.GetStringAtOffset(0x04) } # Get InternalConnectorType hidden [StringValue]GetInternalConnectorType() { $internalConnectorType = $this.GetByteAtOffset(0x05) return [StringValue]::new($internalConnectorType, "_ConnectorType", [ref]$this) } # Get ExternalReferenceDesignator hidden [SMBString]GetExternalReferenceDesignator() { return $this.GetStringAtOffset(0x06) } # Get ExternalConnectorType hidden [StringValue]GetExternalConnectorType() { $externalConnectorType = $this.GetByteAtOffset(0x07) return [StringValue]::new($externalConnectorType, "_ConnectorType", [ref]$this) } # Get PortType hidden [StringValue]GetPortType() { $portType = $this.GetByteAtOffset(0x08) return [StringValue]::new($portType, "PortType", [ref]$this) } } ################################################################################################################################### # Type 9 # ################################################################################################################################### class SystemSlots : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames hidden [ArrayList]$PropertyNamesEx static SystemSlots() { $stringTables = [SystemSlots]::GetStringTables("Type_9") [SystemSlots]::StringArrays = $stringTables.StringArrays [SystemSlots]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Designation" ) $labels.Add( "SlotType" ) $labels.Add( "SlotDataBusWidth" ) $labels.Add( "CurrentUsage" ) $labels.Add( "SlotLength" ) $labels.Add( "ID" ) $labels.Add( "Characteristics" ) } [SystemSlots]::PropertyNames = $labels } SystemSlots([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 6) ) { $labels.Add( "BusAddress" ) } if ( [SMBIOS]::Version -ge [Version]::new(3, 2) ) { $labels.Add( "PeerDevices" ) } if ( [SMBIOS]::Version -ge [Version]::new(3, 4) ) { $labels.Add( "SlotInformation" ) $labels.Add( "SlotPhysicalWidth" ) $labels.Add( "SlotPitch" ) } if ( [SMBIOS]::Version -ge [Version]::new(3, 5) ) { $labels.Add( "SlotHeight" ) } $this.PropertyNamesEx = $labels } # Get Designation hidden [SMBString]GetDesignation() { return $this.GetStringAtOffset(0x04) } # Get SlotType hidden [StringValue]GetSlotType() { $slotType = $this.GetByteAtOffset(0x05) return [StringValue]::new($slotType, "SlotType", [ref]$this) } # Get SlotDataBusWidth hidden [StringValue]GetSlotDataBusWidth() { $slotDataBusWidth = $this.GetByteAtOffset(0x06) return [StringValue]::new($slotDataBusWidth, "_SlotWidth", [ref]$this) } # Get CurrentUsage hidden [StringValue]GetCurrentUsage() { $currentUsage = $this.GetByteAtOffset(0x07) return [StringValue]::new($currentUsage, "CurrentUsage", [ref]$this) } # Get SlotLength hidden [StringValue]GetSlotLength() { $length = $this.GetByteAtOffset(0x08) return [StringValue]::new($length, "SlotLength", [ref]$this) } # Get ID hidden [UInt16]GetID() { return $this.GetWordAtOffset(0x09) } # Get Characteristics hidden [StringValue[]]GetCharacteristics() { $characteristics = [Collections.ArrayList]::new() $characteristics1 = $this.GetByteAtOffset(0x0B) $characteristics2 = 0 if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $characteristics2 = $this.GetByteAtOffset(0x0C) } if (($characteristics1 -band (1 -shl 0))) { return [StringValue]::new(0xFE, $(Get-LocalizedString "UNKNOWN")) } elseif (($characteristics1 -band 0xFE) -eq 0 -and ($characteristics2 -band 7) -eq 0) { return [StringValue]::new(-1 , $(Get-LocalizedString "NONE")) } else { if ($characteristics1 -gt 0) { $characteristics = $characteristics + [BitFieldConverter]::ToStringValueArray($characteristics1, 8, "SlotCharacteristics1", [ref]$this) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) -and ($characteristics2 -gt 0) ) { $characteristics = $characteristics + [BitFieldConverter]::ToStringValueArray($characteristics2, 4, "SlotCharacteristics2", 8, [ref]$this) } } return $characteristics } # Get BusAddress hidden [StringValue]GetBusAddress() { return ([SMBIOSStructure]$this).Get_BusAddress(0x0D) } # Get PeerDevicesCount hidden [Byte]GetPeerDevicesCount() { return $this.GetByteAtOffset(0x12) } # Get PeerDevices hidden [StringValue[]]GetPeerDevices() { $peerDevicesCount = $this.GetPeerDevicesCount() if ($peerDevicesCount -eq 0) { return [StringValue]::new(-1, $(Get-LocalizedString "NONE")) } $peerDevices = [Collections.ArrayList]::new() for ($i = 0; $i -lt $peerDevicesCount; $i++) { $segmentGroupNumber = $this.GetWordAtOffset(0x13 + ($i * 5)) $busNumber = $this.GetByteAtOffset(0x13 + ($i * 5) + 0x02) $deviceAndFunctionNumber = $this.GetByteAtOffset(0x13 + ($i * 5) + 0x03) $width = $this.GetByteAtOffset(0x13 + ($i * 5) + 0x04) if (($segmentGroupNumber -ne 0xFFFF) -or ($busNumber -ne 0xFF) -or ($deviceAndFunctionNumber -ne 0xFF)) { $busAddress = "{0:x4}:{1:x2}:{2:x2}.{3}" -f $segmentGroupNumber, $busNumber, ($deviceAndFunctionNumber -shr 3), ($deviceAndFunctionNumber -band 0x7) $peerDevice = [StringValue]::new( [Ordered]@{ SegmentGroupNumber = $segmentGroupNumber; BusNumber = $busNumber; DeviceNumber = ($deviceAndFunctionNumber -shr 3); FunctionNumber = ($deviceAndFunctionNumber -band 0x7); Width = $width }, $busAddress.ToUpper() + $(" (Width {0})" -f $width) ) } else { return [StringValue]::new(-1, $(Get-LocalizedString "NOT_DEFINED")) } $peerDevices.Add( $peerDevice ) } return $peerDevices } # Get SlotInformation hidden [StringValue]GetSlotInformation() { $slotPhysicalWidth = $this.GetByteAtOffset(0x13 + $($this.GetPeerDevicesCount() * 5)) return [StringValue]::new($slotPhysicalWidth, "_SlotWidth", [ref]$this) } # Get SlotPhysicalWidth hidden [StringValue]GetSlotPhysicalWidth() { $slotPhysicalWidth = $this.GetByteAtOffset(0x14 + $($this.GetPeerDevicesCount() * 5)) return [StringValue]::new($slotPhysicalWidth, "_SlotWidth", [ref]$this) } # Get SlotPitch hidden [StringValue]GetSlotPitch() { $slotPitch = $this.GetWordAtOffset(0x15 + $($this.GetPeerDevicesCount() * 5)) return [StringValue]::new($slotPitch / 100, 0x00, "{0:N1} mm", $slotPitch, "UNKNOWN") } # Get SlotHeight hidden [StringValue]GetSlotHeight() { $height = $this.GetByteAtOffset(0x17 + $($this.GetPeerDevicesCount() * 5)) return [StringValue]::new($height, "SlotHeight", [ref]$this) } } ################################################################################################################################### # Type 10 # ################################################################################################################################### class OnBoardDevice { [StringValue]$DeviceType [StringValue]$Status [String]$Description OnBoardDevice([StringValue]$DeviceType, [StringValue]$Status, [String]$Description) { $this.DeviceType = $DeviceType $this.Status = $Status $this.Description = $Description } [String]ToString() { return $this.Description } } class OnBoardDevicesInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames static OnBoardDevicesInformation() { $stringTables = [OnBoardDevicesInformation]::GetStringTables("Type_10") [OnBoardDevicesInformation]::StringArrays = $stringTables.StringArrays [OnBoardDevicesInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Devices" ) } [OnBoardDevicesInformation]::PropertyNames = $labels } OnBoardDevicesInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $this.Obsolete = $true } # Get Devices hidden [OnBoardDevice[]]GetDevices() { $numberOfDevices = ($this.Length - 4) / 2 $deviceList = [System.Collections.ArrayList]::new() $types = [OnBoardDevicesInformation]::StringArrays["DeviceTypes"] $status = [OnBoardDevicesInformation]::StringArrays["DeviceStatus"] for ($i = 1; $i -le $numberOfDevices ; $i++) { [Byte]$deviceInformations = $this.data[4 + 2 * ($i - 1)] $deviceType = $([StringValue]::new($deviceInformations -band 127, $types)) $deviceStatus = $([StringValue]::new(($deviceInformations -shr 7), $status)) $description = $($this.strings[$this.data[5 + 2 * ($i - 1)] - 1]) if ([String]::IsNullOrEmpty($description)) { $description = Get-LocalizedString "NOT_SPECIFIED" } $deviceList.Add([OnBoardDevice]::new($deviceType, $deviceStatus, $description)) | Out-Null } return $deviceList.ToArray() } } ################################################################################################################################### # Type 11 # ################################################################################################################################### class OEMStrings : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [Array]$PropertyNames static OEMStrings() { [OEMStrings]::StringArrays = @{} [OEMStrings]::StringArrayNameAlias = @{} $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "OEMStrings" ) } [OEMStrings]::PropertyNames = $labels } OEMStrings([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Count hidden [Byte]GetCount() { return $this.GetByteAtOffset(0x04) } # Get OEMStrings hidden [String[]]GetOEMStrings() { return ([SMBIOSStructure]$this).Strings } } ################################################################################################################################### # Type 12 # ################################################################################################################################### class SystemConfigurationOptions : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static SystemConfigurationOptions() { [SystemConfigurationOptions]::StringArrays = @{} [SystemConfigurationOptions]::StringArrayNameAlias = @{} $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Options" ) } [SystemConfigurationOptions]::PropertyNames = $labels } SystemConfigurationOptions([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Count hidden [Byte]GetCount() { return $this.GetByteAtOffset(0x04) } # Get Options hidden [String[]]GetOptions() { return ([SMBIOSStructure]$this).Strings } } ################################################################################################################################### # Type 13 # ################################################################################################################################### class BIOSLanguageInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static BIOSLanguageInformation() { $stringTables = [BIOSLanguageInformation]::GetStringTables("Type_13") [BIOSLanguageInformation]::StringArrays = $stringTables.StringArrays [BIOSLanguageInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "InstallableLanguages" ) $labels.Add( "CurrentLanguage" ) $labels.Add( "Format" ) } [BIOSLanguageInformation]::PropertyNames = $labels } BIOSLanguageInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get InstallableLanguages hidden [String[]]GetInstallableLanguages() { $numberOfInstallableLanguages = $this.GetByteAtOffset(0x04) $installableLanguages = [ArrayList]::new() if ($this.Strings) { for ($i=0; $i -le $numberOfInstallableLanguages - 1; $i++) { $installableLanguages.Add( $this.strings[$i] ) } } else { return [StringValue]::new(-1, $(Get-LocalizedString "NONE")) } return $installableLanguages } # Get CurrentLanguage hidden [SMBString]GetCurrentLanguage() { return $this.GetStringAtOffset(0x15) } # Get Format hidden [StringValue]GetFormat() { [Byte]$format = $this.GetByteAtOffset(0x05) -band 0x01 return [StringValue]::new($format, "Format", [ref]$this) } } ################################################################################################################################### # Type 14 # ################################################################################################################################### class GroupAssociationsItem { [SMBIOSType]$Type [UInt16]$Handle GroupAssociationsItem([SMBIOSType]$type, [UInt16]$handle) { $this.Type = $type $this.Handle = $handle } [String]ToString() { return "$($this.Type)" } } class GroupAssociations : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static GroupAssociations() { [GroupAssociations]::StringArrays = @{} [GroupAssociations]::StringArrayNameAlias = @{} $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "Name" ) $labels.Add( "Items" ) } [GroupAssociations]::PropertyNames = $labels } GroupAssociations([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Name hidden [SMBString]GetName() { return $this.GetStringAtOffset(0x04) } # Get NumberOfItems hidden [Byte]GetNumberOfItems() { return ($this.data.length - 5) / 3 } # Get Items hidden [Array]GetItems() { $items = [Collections.ArrayList]::new() $length = $this.GetNumberOfItems() for ($i = 0; $i -lt $length ; $i++) { $type = $this.GetByteAtOffset(0x05 + 3 * $i) $SMBIOSType = [SMBIOS]::Types[$type] $handle = [BitConverter]::ToUInt16($this.data, 0x05 + 3 * $i + 1) $item = [GroupAssociationsItem]::new($SMBIOSType, $handle) $items.Add( $item ) | Out-Null } return $items.ToArray() } } ################################################################################################################################### # Type 15 # ################################################################################################################################### class SystemEventLog : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static SystemEventLog() { $stringTables = [SystemEventLog]::GetStringTables("Type_15") [SystemEventLog]::StringArrays = $stringTables.StringArrays [SystemEventLog]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 0) ) { $labels.Add( "AreaLength" ) $labels.Add( "HeaderStartOffset" ) $labels.Add( "HeaderLength" ) $labels.Add( "DataStartOffset" ) $labels.Add( "AccessMethod" ) $labels.Add( "Status" ) $labels.Add( "ChangeToken" ) $labels.Add( "AccessMethodAddress" ) $labels.Add( "HeaderFormat" ) $labels.Add( "SupportedEventLogTypeDescriptors" ) } [SystemEventLog]::PropertyNames = $labels } SystemEventLog([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get AreaLength hidden [StringValueMemorySize]GetAreaLength() { $areaLength = $this.GetWordAtOffset(0x04) $unit = [MemorySizeUnit]::B return [StringValueMemorySize]::new($areaLength, $unit) } # Get HeaderStartOffset hidden [UInt16]GetHeaderStartOffset() { return $this.GetWordAtOffset(0x06) } # Get HeaderLength hidden [StringValueMemorySize]GetHeaderLength() { $headerLength = $this.GetDataStartOffset() - $this.GetHeaderStartOffset() $unit = [MemorySizeUnit]::B return [StringValueMemorySize]::new($headerLength, $unit) } # Get DataStartOffset hidden [UInt16]GetDataStartOffset() { return $this.GetWordAtOffset(0x08) } # Get AccessMethod hidden [StringValue]GetAccessMethod() { $accessMethod = $this.GetByteAtOffset(0x0A) return [StringValue]::new($accessMethod, "AccessMethod", [ref]$this) } # Get Status hidden [StringVAlue[]]GetStatus() { $status = $this.GetByteAtOffset(0x0B) $logStatus = [Collections.ArrayList]::new() $statusValid = [BitField]::Get($status, 0) $logStatus.Add([StringValue]::new($statusValid, "StatusValid", [ref]$this)) | Out-Null $statusFull = [BitField]::Get($status, 1) $logStatus.Add([StringValue]::new($statusFull, "StatusFull", [ref]$this)) | Out-Null return $logStatus } # Get ChangeToken hidden [UInt16]GetChangeToken() { return $this.GetWordAtOffset(0x0C) } # Get AccessMethodAddress hidden [UInt16]GetAccessMethodAddress() { return $this.GetWordAtOffset(0x10) } # Get HeaderFormat hidden [StringValue]GetHeaderFormat() { $headerFormat = $this.GetByteAtOffset(0x14) return [StringValue]::new($headerFormat, "HeaderFormat", [ref]$this) } # Get NumberOfSupportedLogTypeDescriptors hidden [Byte]GetNumberOfSupportedLogTypeDescriptors() { return $this.GetByteAtOffset(0x15) } # Get LengthOfEeachLogTypeDescriptor hidden [Byte]GetLengthOfEeachLogTypeDescriptor() { return $this.GetByteAtOffset(0x16) } # Get SupportedEventLogTypeDescriptors hidden [Array]GetSupportedEventLogTypeDescriptors() { $numberOfDescriptors = $this.GetNumberOfSupportedLogTypeDescriptors() $lengthOfDescriptor = $this.GetLengthOfEeachLogTypeDescriptor() $descriptors = [Collections.ArrayList]::new() for ($i = 0; $i -lt $numberOfDescriptors ; $i++) { $descriptorSegment = ([ArraySegment[Byte]]::new($this.data, 0x17 + ($i * $lengthOfDescriptor), $lengthOfDescriptor)) [Byte[]]$descriptor = [Linq.Enumerable]::ToArray($descriptorSegment) $eventLogType = $descriptor[0] $type = [StringValue]::new($eventLogType, "EventLogType", [ref]$this) $dataFormatType = $descriptor[1] $format = [StringValue]::new($dataFormatType, "EventLogVariableDataFormatType", [ref]$this) $orderedDescriptor = [Ordered]@{ EventLogType = $type ; DataFormatType = $format } $descriptors.Add([StringValue]::new($orderedDescriptor, "$type")) | Out-Null } return $descriptors } } ################################################################################################################################### # Type 16 # ################################################################################################################################### class PhysicalMemoryArray : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static PhysicalMemoryArray() { $stringTables = [PhysicalMemoryArray]::GetStringTables("Type_16") [PhysicalMemoryArray]::StringArrays = $stringTables.StringArrays [PhysicalMemoryArray]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "Location" ) $labels.Add( "Use" ) $labels.Add( "MemoryErrorCorrection" ) $labels.Add( "MaximumCapacity" ) $labels.Add( "MemoryErrorInformationHandle" ) $labels.Add( "NumberOfMemoryDevices" ) } [PhysicalMemoryArray]::PropertyNames = $labels } PhysicalMemoryArray([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Location hidden [StringValue]GetLocation() { $location = $this.GetByteAtOffset(0x04) $stringArray = [PhysicalMemoryArray]::StringArrays["Location"] return [StringValue]::new($location, $stringArray) } # Get Use hidden [StringValue]GetUse() { $use = $this.GetByteAtOffset(0x05) $stringArray = [PhysicalMemoryArray]::StringArrays["Use"] return [StringValue]::new($use, $stringArray) } # Get MemoryErrorCorrection hidden [StringValue]GetMemoryErrorCorrection() { $correction = $this.GetByteAtOffset(0x06) return [StringValue]::new($correction, "MemoryErrorCorrection", [ref]$this) } # Get MaximumCapacity hidden [StringValueMemorySize]GetMaximumCapacity() { $maximumCapacity = $this.GetDoubleWordAtOffset(0x07) $sizeInBytes = $maximumCapacity * 1kb if ($maximumCapacity -eq 0x80000000) { $sizeInBytes = $this.GetDoubleWordAtOffset(0x0F) } $unit = [MemorySizeUnit]::Auto return [StringValueMemorySize]::new($sizeInBytes, $unit) } # Get MemoryErrorInformationHandle hidden [StringValue]GetMemoryErrorInformationHandle() { $handle = $this.GetWordAtOffset(0x0B) if ( @(0xFFFE, 0xFFFF) -contains $handle ) { return [StringValue]::new($handle, "MemoryErrorInformationHandle", [ref]$this) } return [StringValue]::new($handle) } # Get NumberOfMemoryDevices hidden [UInt16]GetNumberOfMemoryDevices() { return $this.GetWordAtOffset(0x0D) } } ################################################################################################################################### # Type 17 # ################################################################################################################################### class MemoryDevice : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames hidden [ArrayList]$PropertyNamesEx static MemoryDevice() { $stringTables = [MemoryDevice]::GetStringTables("Type_17") [MemoryDevice]::StringArrays = $stringTables.StringArrays [MemoryDevice]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "PhysicalMemoryArrayHandle" ) $labels.Add( "MemoryErrorInformationHandle" ) $labels.Add( "TotalWidth" ) $labels.Add( "DataWidth" ) $labels.Add( "Size" ) $labels.Add( "FormFactor" ) $labels.Add( "DeviceSet" ) $labels.Add( "DeviceLocator" ) $labels.Add( "BankLocator" ) $labels.Add( "MemoryType" ) $labels.Add( "TypeDetail" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "Speed" ) $labels.Add( "Manufacturer" ) $labels.Add( "SerialNumber" ) $labels.Add( "AssetTag" ) $labels.Add( "PartNumber" ) } [MemoryDevice]::PropertyNames = $labels } MemoryDevice([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 6) ) { $labels.Add( "Rank" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 7) ) { $labels.Add( "ConfiguredMemorySpeed" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 8) ) { $labels.Add( "MinimumVoltage" ) $labels.Add( "MaximumVoltage" ) $labels.Add( "ConfiguredVoltage" ) } if ( [SMBIOS]::Version -ge [Version]::new(3, 2) ) { $labels.Add( "MemoryTechnology" ) $labels.Add( "MemoryOperatingModeCapability" ) $labels.Add( "FirmwareVersion" ) $labels.Add( "ModuleManufacturerID" ) $labels.Add( "ModuleProductID" ) $labels.Add( "MemorySubsystemControllerManufacturerID" ) $labels.Add( "MemorySubsystemControllerProductID" ) $labels.Add( "NonVolatileSize" ) $labels.Add( "VolatileSize" ) $labels.Add( "CacheSize" ) $labels.Add( "LogicalSize" ) } if ( [SMBIOS]::Version -ge [Version]::new(3, 7) ) { $labels.Add( "PMIC0ManufacturerID" ) $labels.Add( "PMIC0RevisionNumber" ) $labels.Add( "RCDManufacturerID" ) $labels.Add( "RCDRevisionNumber" ) } $this.PropertyNamesEx = $labels } # Get PhysicalMemoryArrayHandle hidden [UInt16]GetPhysicalMemoryArrayHandle() { return $this.GetWordAtOffset(0x04) } # Get MemoryErrorInformationHandle hidden [StringValue]GetMemoryErrorInformationHandle() { $handle = $this.GetWordAtOffset(0x06) if ( @(0xFFFE, 0xFFFF) -contains $handle ) { return [StringValue]::new($handle, "MemoryErrorInformationHandle", [ref]$this) } return [StringValue]::new($handle) } # Get TotalWidth hidden [StringValue]GetTotalWidth() { $totalWidth = $this.GetWordAtOffset(0x08) return [StringValue]::new($totalWidth, @(0x00, 0xFFFF), "{0} bits", "UNKNOWN") } # Get DataWidth hidden [StringValue]GetDataWidth() { $dataWidth = $this.GetWordAtOffset(0x0A) return [StringValue]::new($dataWidth, @(0x00, 0xFFFF), "{0} bits", "UNKNOWN") } # Get Size hidden [StringValueMemorySize]GetSize() { $size = $this.GetWordAtOffset(0x0C) $sizeInBytes = 0 if ($size -eq 0x0000) { return [StringValueMemorySize]::new($size, "Size", [ref]$this, -1, [MemorySizeUnit]::None) } if ($size -eq 0xFFFE) { return [StringValueMemorySize]::new($size, "Size", [ref]$this, -1, [MemorySizeUnit]::Unknown) } if ($size -eq 0x7FFF) { $size = $this.ExtendedSize() $effectiveSize = [BitFieldConverter]::ToInt($size, 0, 30) $sizeInBytes = $effectiveSize * 1mb } else { $effectiveSize = $size -band 0x7FFF if ($size -band (1 -shl 15)) { $sizeInBytes = $effectiveSize * 1kb } else { $sizeInBytes = $effectiveSize * 1mb } } $unit = [MemorySizeUnit]::Auto return [StringValueMemorySize]::new($sizeInBytes, $unit) } # Get FormFactor hidden [StringValue]GetFormFactor() { $formFactor = $this.GetByteAtOffset(0x0E) return [StringValue]::new($formFactor, "FormFactor", [ref]$this) } # Get DeviceSet hidden [StringValue]GetDeviceSet() { $deviceSet = $this.GetByteAtOffset(0x0F) if ( @(0xFF, 0x00) -contains $deviceSet ) { return [StringValue]::new($deviceSet, "DeviceSet", [ref]$this) } return [StringValue]::new($deviceSet, "{0}") } # Get DeviceLocator hidden [SMBString]GetDeviceLocator() { return $this.GetStringAtOffset(0x10) } # Get BankLocator hidden [SMBString]GetBankLocator() { return $this.GetStringAtOffset(0x11) } # Get MemoryType hidden [StringValue]GetMemoryType() { $memoryType = $this.GetByteAtOffset(0x12) return [StringValue]::new($memoryType, "MemoryType", [ref]$this) } # Get TypeDetail hidden [StringValue[]]GetTypeDetail() { $typeDetail = $this.GetWordAtOffset(0x13) return [BitFieldConverter]::ToStringValueArray($typeDetail, "TypeDetail", [ref]$this) } # Get Speed hidden [StringValue]GetSpeed() { $speed = $this.GetWordAtOffset(0x15) $extendedSpeed = 0 if ($speed -eq 0xFFFF) { $extendedSpeed = $this.ExtendedSpeed() } return [StringValue]::new($speed, 0x00, "{0} MT/s", "UNKNOWN", 0xFFFF, $extendedSpeed) } # Get Manufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x17) } # Get SerialNumber hidden [SMBString]GetSerialNumber() { return $this.GetStringAtOffset(0x18) } # Get AssetTag hidden [SMBString]GetAssetTag() { return $this.GetStringAtOffset(0x19) } # Get PartNumber hidden [SMBString]GetPartNumber() { return $this.GetStringAtOffset(0x1A) } # Get Rank hidden [StringValue]GetRank() { $attributes = $this.GetByteAtOffset(0x1B) $rank = [BitField]::Extract($attributes, 0, 4) return [StringValue]::new($rank, 0x00, $null, "UNKNOWN") } hidden [UInt32]ExtendedSize() { return $this.GetDoubleWordAtOffset(0x1C) } # Get ConfiguredMemorySpeed hidden [StringValue]GetConfiguredMemorySpeed() { $configuredMemorySpeed = $this.GetWordAtOffset(0x20) $extendedConfiguredMemorySpeed = 0 if ($configuredMemorySpeed -eq 0xFFFF) { $extendedConfiguredMemorySpeed = $this.ExtendedConfiguredMemorySpeed() } return [StringValue]::new($configuredMemorySpeed, 0x00, "{0} MT/s", "UNKNOWN", 0xFFFF, $extendedConfiguredMemorySpeed) } # Get MinimumVoltage hidden [StringValue]GetMinimumVoltage() { $minimumVoltage = $this.GetWordAtOffset(0x22) return [StringValue]::new($minimumVoltage, 0x00, "{0} mV", "UNKNOWN") } # Get MaximumVolatge hidden [StringValue]GetMaximumVoltage() { $maximumVoltage = $this.GetWordAtOffset(0x24) return [StringValue]::new($maximumVoltage, 0x00, "{0} mV", "UNKNOWN") } # Get ConfiguredVoltage hidden [StringValue]GetConfiguredVoltage() { $configuredVoltage = $this.GetWordAtOffset(0x26) return [StringValue]::new($configuredVoltage, 0x00, "{0} mV", "UNKNOWN") } # Get MemoryTechnology hidden [StringValue]GetMemoryTechnology() { $memoryTechnology = $this.GetByteAtOffset(0x28) return [StringValue]::new($memoryTechnology, "MemoryTechnology", [ref]$this) } # Get MemoryOperatingModeCapability hidden [StringValue[]]GetMemoryOperatingModeCapability() { $memoryOperatingModeCapability = $this.GetByteAtOffset(0x29) return [BitFieldConverter]::ToStringValueArray($memoryOperatingModeCapability, 6, "MemoryOperatingModeCapability", [ref]$this) } # Get FirmwareVersion hidden [SMBString]GetFirmwareVersion() { return $this.GetStringAtOffset(0x2B) } # Get ModuleManufacturerID hidden [StringValue]GetModuleManufacturerID() { $moduleManufacturerID = $this.GetWordAtOffset(0x2C) return [StringValue]::new($moduleManufacturerID, 0x00, $null, "UNKNOWN") } # Get ModuleProductID hidden [StringValue]GetModuleProductID() { $moduleProductID = $this.GetWordAtOffset(0x2E) return [StringValue]::new($moduleProductID, 0x00, $null, "UNKNOWN") } # Get MemorySubsystemControllerManufacturerID hidden [StringValue]GetMemorySubsystemControllerManufacturerID() { $memorySubsystemControllerManufacturerID = $this.GetWordAtOffset(0x30) return [StringValue]::new($memorySubsystemControllerManufacturerID, 0x00, $null, "UNKNOWN") } # Get MemorySubsystemControllerProductID hidden [StringValue]GetMemorySubsystemControllerProductID() { $memorySubsystemControllerProductID = $this.GetWordAtOffset(0x32) return [StringValue]::new($memorySubsystemControllerProductID, 0x00, $null, "UNKNOWN") } # Utility method for NonVolatileSize, VolatileSize, CacheSize, LogicalSize methods hidden [StringValueMemorySize]_GetSize($size) { if (([BitField]::LowUInt64($size) -eq 0xFFFFFFFF) -and ([BitField]::HighUInt64($size) -eq 0xFFFFFFFF)) { return [StringValueMemorySize]::new(0xFFFF, "OtherSize", [ref]$this, -1, [MemorySizeUnit]::Unknown) } elseif (([BitField]::LowUInt64($size) -eq 0x00) -and ([BitField]::HighUInt64($size) -eq 0x00)) { return [StringValueMemorySize]::new($size, "OtherSize", [ref]$this, -1, [MemorySizeUnit]::None) } else { $unit = [MemorySizeUnit]::Auto return [StringValueMemorySize]::new($size, $unit) } } # Get NonVolatileSize hidden [StringValueMemorySize]GetNonVolatileSize() { $nonVolatileSize = $this.GetQuadWordAtOffset(0x34) return $this._GetSize($nonVolatileSize) } # Get VolatileSize hidden [StringValueMemorySize]GetVolatileSize() { $volatileSize = $this.GetQuadWordAtOffset(0x3C) return $this._GetSize($volatileSize) } # Get CacheSize hidden [StringValueMemorySize]GetCacheSize() { $cacheSize = $this.GetQuadWordAtOffset(0x44) return $this._GetSize($cacheSize) } # Get LogicalSize hidden [StringValueMemorySize]GetLogicalSize() { $logicalSize = $this.GetQuadWordAtOffset(0x4C) return $this._GetSize($logicalSize) } # Get ExtendedSpeed hidden [UInt32]ExtendedSpeed() { return $this.GetDoubleWordAtOffset(0x54) -band [UInt32]0x7FFFFFFF } # Get ExtendedConfiguredMemorySpeed hidden [UInt32]ExtendedConfiguredMemorySpeed() { return $this.GetDoubleWordAtOffset(0x58) -band [UInt32]0x7FFFFFFF } # Get PMIC0ManufacturerID hidden [UInt16]PMIC0ManufacturerID() { return $this.GetWordAtOffset(0x5C) } # Get PMIC0RevisionNumber hidden [UInt16]PMIC0RevisionNumber() { return $this.GetWordAtOffset(0x5E) } # Get RCDManufacturerID hidden [UInt16]RCDManufacturerID() { return $this.GetWordAtOffset(0x60) } # Get RCDRevisionNumber hidden [UInt16]RCDRevisionNumber() { return $this.GetWordAtOffset(0x62) } } ################################################################################################################################### # Type 18 # ################################################################################################################################### class _32BitMemoryErrorInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static _32BitMemoryErrorInformation() { $stringTables = [_32BitMemoryErrorInformation]::GetStringTables("Type_18") [_32BitMemoryErrorInformation]::StringArrays = $stringTables.StringArrays [_32BitMemoryErrorInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "ErrorType" ) $labels.Add( "ErrorGranularity" ) $labels.Add( "ErrorOperation" ) $labels.Add( "VendorSyndrome" ) $labels.Add( "MemoryArrayErrorAddress" ) $labels.Add( "DeviceErrorAddress" ) $labels.Add( "ErrorResolution" ) } [_32BitMemoryErrorInformation]::PropertyNames = $labels } _32BitMemoryErrorInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get ErrorType hidden [StringValue]GetErrorType() { $errorType = $this.GetByteAtOffset(0x04) return [StringValue]::new($errorType, "ErrorType", [ref]$this) } # Get ErrorGranularity hidden [StringValue]GetErrorGranularity() { $errorGranularity = $this.GetByteAtOffset(0x05) return [StringValue]::new($errorGranularity, "ErrorGranularity", [ref]$this) } # Get ErrorOperation hidden [StringValue]GetErrorOperation() { $errorOperation = $this.GetByteAtOffset(0x06) return [StringValue]::new($errorOperation, "ErrorOperation", [ref]$this) } # GetVendorSyndrome hidden [StringValue]GetVendorSyndrome() { $vendorSyndrome = $this.GetDoubleWordAtOffset(0x07) return [StringValue]::new($vendorSyndrome, 0x00, "0x{0:X8}", "UNKNOWN") } # Get MemoryArrayErrorAddress hidden [StringValue]GetMemoryArrayErrorAddress() { $memoryArrayErrorAddress = $this.GetDoubleWordAtOffset(0x0B) return [StringValue]::new($memoryArrayErrorAddress, 0x00, "0x{0:X8}", "UNKNOWN") } # Get DeviceErrorAddress hidden [StringValue]GetDeviceErrorAddress() { $deviceErrorAddress = $this.GetDoubleWordAtOffset(0x0F) return [StringValue]::new($deviceErrorAddress, -0x80000000, "0x{0:X8}", "UNKNOWN") } # Get ErrorResolution hidden [StringValue]GetErrorResolution() { $errorResolution = $this.GetDoubleWordAtOffset(0x13) return [StringValue]::new($errorResolution, -0x80000000, "0x{0:X8}", "UNKNOWN") } } ################################################################################################################################### # Type 19 # ################################################################################################################################### class MemoryArrayMappedAddress : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static MemoryArrayMappedAddress() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "StartingAddress" ) $labels.Add( "EndingAddress" ) $labels.Add( "RangeSize" ) $labels.Add( "MemoryArrayHandle" ) $labels.Add( "PartitionWidth" ) } [MemoryArrayMappedAddress]::PropertyNames = $labels } MemoryArrayMappedAddress([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get StartingAddress hidden [StringValue]GetStartingAddress() { $startingAddress = $this.GetDoubleWordAtOffset(0x04) if ($startingAddress -eq 0xFFFFFFFF) { $extendedStartingAddress = $this.GetExtendedStartingAddress() return [StringValue]::new($extendedStartingAddress, "0x{0:X16}") } return [StringValue]::new([UInt64]$startingAddress * 1kb, "0x{0:X16}") } # Get EndingAddress hidden [StringValue]GetEndingAddress() { $endingAddress = $this.GetDoubleWordAtOffset(0x08) if ($endingAddress -eq 0xFFFFFFFF) { $extendedEndingAddress = $this.GetExtendedEndingAddress() return [StringValue]::new($extendedEndingAddress, "0x{0:X16}") } return [StringValue]::new([UInt64]$endingAddress * 1kb + 1023, "0x{0:X16}") } # Get RangeSize hidden [StringValueMemorySize]GetRangeSize() { $startingAddress = $this.GetStartingAddress().Value $endingAddress = $this.GetEndingAddress().Value if ($startingAddress -eq $endingAddress) { return [StringValueMemorySize]::new(0, [MemorySizeUnit]::B) } $size = $endingAddress - $startingAddress + 1 $unit = [MemorySizeUnit]::Auto return [StringValueMemorySize]::new($size, $unit) } # Get MemoryArrayHandle hidden [UInt16]GetMemoryArrayHandle() { return $this.GetWordAtOffset(0x0C) } # Get PartitionWidth hidden [Byte]GetPartitionWidth() { return $this.GetByteAtOffset(0x0E) } # Get ExtendedStartingAddress hidden [UInt64]GetExtendedStartingAddress() { return $this.GetQuadWordAtOffset(0x0F) } # Get ExtendedEndingAddress hidden [UInt64]GetExtendedEndingAddress() { return $this.GetQuadWordAtOffset(0x17) } } ################################################################################################################################### # Type 20 # ################################################################################################################################### class MemoryDeviceMappedAddress : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static MemoryDeviceMappedAddress() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "StartingAddress" ) $labels.Add( "EndingAddress" ) $labels.Add( "RangeSize" ) $labels.Add( "MemoryDeviceHandle" ) $labels.Add( "MemoryArrayMappedAddressHandle" ) $labels.Add( "PartitionRowPosition" ) $labels.Add( "InterleavePosition" ) $labels.Add( "InterleavedDataDepth" ) } [MemoryDeviceMappedAddress]::PropertyNames = $labels } MemoryDeviceMappedAddress([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get StartingAddress hidden [StringValue]GetStartingAddress() { $startingAddress = $this.GetDoubleWordAtOffset(0x04) if ($startingAddress -eq 0xFFFFFFFF) { $extendedStartingAddress = $this.GetExtendedStartingAddress() return [StringValue]::new($extendedStartingAddress, "0x{0:X16}") } return [StringValue]::new([UInt64]$startingAddress * 1kb, "0x{0:X16}") } # Get EndingAddress hidden [StringValue]GetEndingAddress() { $endingAddress = $this.GetDoubleWordAtOffset(0x08) if ($endingAddress -eq 0xFFFFFFFF) { $extendedEndingAddress = $this.GetExtendedEndingAddress() return [StringValue]::new($extendedEndingAddress, "0x{0:X16}") } return [StringValue]::new([UInt64]$endingAddress * 1kb + 1023, "0x{0:X16}") } # Get RangeSize hidden [StringValueMemorySize]GetRangeSize() { $startingAddress = $this.GetStartingAddress().Value $endingAddress = $this.GetEndingAddress().Value if ($startingAddress -eq $endingAddress) { return [StringValueMemorySize]::new(0, [MemorySizeUnit]::B) } $size = $endingAddress - $startingAddress + 1 $unit = [MemorySizeUnit]::Auto return [StringValueMemorySize]::new($size, $unit) } # Get MemoryDeviceHandle hidden [UInt16]GetMemoryDeviceHandle() { return $this.GetWordAtOffset(0x0C) } # Get MemoryArrayMappedAddressHandle hidden [UInt16]GetMemoryArrayMappedAddressHandle() { return $this.GetWordAtOffset(0x0E) } # Get PartitionRowPosition hidden [StringValue]GetPartitionRowPosition() { $partitionRowPosition = $this.GetByteAtOffset(0x10) return [StringValue]::new($partitionRowPosition, 0xFF, $null, "UNKNOWN") } # Get InterleavePosition hidden [StringValue]GetInterleavePosition() { $interleavePosition = $this.GetByteAtOffset(0x11) return [StringValue]::new($interleavePosition, 0xFF, $null, "UNKNOWN") } # Get InterleavedDataDepth hidden [StringValue]GetInterleavedDataDepth() { $interleavedDataDepth = $this.GetByteAtOffset(0x12) return [StringValue]::new($interleavedDataDepth, 0xFF, $null, "UNKNOWN") } # Get ExtendedStartingAddress hidden [UInt64]GetExtendedStartingAddress() { return $this.GetQuadWordAtOffset(0x13) } # Get ExtendedEndingAddress hidden [UInt64]GetExtendedEndingAddress() { return $this.GetQuadWordAtOffset(0x1B) } } ################################################################################################################################### # Type 21 # ################################################################################################################################### class BuiltInPointingDevice : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static BuiltInPointingDevice() { $stringTables = [BuiltInPointingDevice]::GetStringTables("Type_21") [BuiltInPointingDevice]::StringArrays = $stringTables.StringArrays [BuiltInPointingDevice]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "PointingDeviceType" ) $labels.Add( "Interface" ) $labels.Add( "NumberOfButtons" ) } [BuiltInPointingDevice]::PropertyNames = $labels } BuiltInPointingDevice([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get PointingDeviceType hidden [StringValue]GetPointingDeviceType() { $type = $this.GetByteAtOffset(0x04) return [StringValue]::new($type, "Type", [ref]$this) } # Get Interface hidden [StringValue]GetInterface() { $interface = $this.GetByteAtOffset(0x05) return [StringValue]::new($interface, "Interface", [ref]$this) } # Get NumberOfButtons hidden [Byte]GetNumberOfButtons() { return $this.GetByteAtOffset(0x06) } } ################################################################################################################################### # Type 22 # ################################################################################################################################### class PortableBattery : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static PortableBattery() { $stringTables = [PortableBattery]::GetStringTables("Type_22") [PortableBattery]::StringArrays = $stringTables.StringArrays [PortableBattery]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "Location" ) $labels.Add( "Manufacturer" ) } if ( ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) -and ( [SMBIOS]::Version -lt [Version]::new(2, 2) ) ) { $labels.Add( "ManufactureDate" ) $labels.Add( "SerialNumber" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "DeviceName" ) } if ( ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) -and ( [SMBIOS]::Version -lt [Version]::new(2, 2) ) ) { $labels.Add( "DeviceChemistry" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 1) ) { $labels.Add( "DesignCapacity" ) $labels.Add( "DesignVoltage" ) $labels.Add( "SBDSVersionNumber" ) $labels.Add( "MaximumErrorInBatteryData" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "SBDSSerialNumber" ) $labels.Add( "SBDSManufactureDate" ) $labels.Add( "SBDSDeviceChemistry" ) $labels.Add( "OEMSpecificInformation" ) } [PortableBattery]::PropertyNames = $labels } PortableBattery([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Location hidden [SMBString]GetLocation() { return $this.GetStringAtOffset(0x04) } # Get Manufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x05) } # Get ManufactureDate hidden [SMBString]GetManufactureDate() { return $this.GetStringAtOffset(0x06) } # Get SerialNumber hidden [SMBString]GetSerialNumber() { return $this.GetStringAtOffset(0x07) } # Get DeviceName hidden [SMBString]GetDeviceName() { return $this.GetStringAtOffset(0x08) } # Get DeviceChemistry hidden [StringValue]GetDeviceChemistry() { $chemistry = $this.GetByteAtOffset(0x09) return [StringValue]::new($chemistry, "DeviceChemistry", [ref]$this) } # Get DesignCapacity hidden [StringValue]GetDesignCapacity() { $designCapacity = $this.GetWordAtOffset(0x0A) $capacity = $designCapacity if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $multiplier = $this.GetDesignCapacityMultiplier() $capacity = $designCapacity * $multiplier } return [StringValue]::new($capacity, 0x00, "{0} mWh", "UNKNOWN") } # Get DesignVoltage hidden [StringValue]GetDesignVoltage() { $designVoltage = $this.GetWordAtOffset(0x0C) return [StringValue]::new($designVoltage, 0x00, "{0} mV", "UNKNOWN") } # Get SBDSVersionNumber hidden [SMBString]GetSBDSVersionNumber() { return $this.GetStringAtOffset(0x0E) } # Get MaximumErrorInBatteryData hidden [StringValue]GetMaximumErrorInBatteryData() { $maximumErrorInBatteryData = $this.GetByteAtOffset(0x0F) return [StringValue]::new($maximumErrorInBatteryData, 0xFF, "{0:P}", $maximumErrorInBatteryData / 100, "UNKNOWN") } # Get SBDSSerialNumber hidden [StringValue]GetSBDSSerialNumber() { $SBDSSerialNumber = $this.GetWordAtOffset(0x10) return [StringValue]::new($SBDSSerialNumber, 0x00, "{0}", "UNKNOWN") } # Get SBDSManufactureDate hidden [StringValueDateTime]GetSBDSManufactureDate() { $BDSManufactureDate = $this.GetWordAtOffset(0x12) if ($BDSManufactureDate -eq 0x00) { return [StringValueDateTime]::new($null, $(Get-LocalizedString "UNKNOWN")) } $year = 1980 + [BitField]::Extract($BDSManufactureDate, 9, 7) $month = [BitField]::Extract($BDSManufactureDate, 5, 4) $day = [BitField]::Extract($BDSManufactureDate, 0, 5) $date = [DateTime]::new($year, $month, $day) return [StringValueDateTime]::new($date) } # Get SBDSDeviceChemistry hidden [SMBString]GetSBDSDeviceChemistry() { return $this.GetStringAtOffset(0x14) } # Get DesignCapacityMultiplier hidden [Byte]GetDesignCapacityMultiplier() { return $this.GetByteAtOffset(0x15) } # Get OEMSpecificInformation hidden [UInt32]GetOEMSpecificInformation() { return $this.GetDoubleWordAtOffset(0x16) } } ################################################################################################################################### # Type 23 # ################################################################################################################################### class SystemReset : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static SystemReset() { $stringTables = [SystemReset]::GetStringTables("Type_23") [SystemReset]::StringArrays = $stringTables.StringArrays [SystemReset]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "Status" ) $labels.Add( "WatchdogTimer" ) $labels.Add( "BootOption" ) $labels.Add( "BootOptionOnLimit" ) $labels.Add( "ResetCount" ) $labels.Add( "ResetLimit" ) $labels.Add( "TimerInterval" ) $labels.Add( "Timeout" ) } [SystemReset]::PropertyNames = $labels } SystemReset([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Status hidden [StringValue]GetStatus() { $capabilities = $this.GetByteAtOffset(0x04) $status = [BitField]::Get($capabilities, 0) return [StringValue]::new($status, "Status", [ref]$this) } # Get WatchdogTimer hidden [StringValue]GetWatchdogTimer() { $capabilities = $this.GetByteAtOffset(0x04) $watchdogTimer = [BitField]::Get($capabilities, 5) return [StringValue]::new($watchdogTimer, "WatchdogTimer", [ref]$this) } # Get BootOption hidden [StringValue]GetBootOption() { $capabilities = $this.GetByteAtOffset(0x04) $bootOption = [BitField]::Extract($capabilities, 1, 2) return [StringValue]::new($bootOption, "BootOption", [ref]$this) } # Get BootOptionOnLimit hidden [StringValue]GetBootOptionOnLimit() { $capabilities = $this.GetByteAtOffset(0x04) $bootOptionOnLimit = [BitField]::Extract($capabilities, 3, 2) return [StringValue]::new($bootOptionOnLimit, "BootOption", [ref]$this) } # Get ResetCount hidden [StringValue]GetResetCount() { $resetCount = $this.GetWordAtOffset(0x05) return [StringValue]::new($resetCount, 0xFFFF, $null, "UNKNOWN") } # Get ResetLimit hidden [StringValue]GetResetLimit() { $resetLimit = $this.GetWordAtOffset(0x07) return [StringValue]::new($resetLimit, 0xFFFF, $null, "UNKNOWN") } # Get TimerInterval hidden [StringValue]GetTimerInterval() { $timerInterval = $this.GetWordAtOffset(0x09) return [StringValue]::new($timerInterval, 0xFFFF, "{0} minutes", "UNKNOWN") } # Get Timeout hidden [StringValue]GetTimeout() { $timeout = $this.GetWordAtOffset(0x09) return [StringValue]::new($timeout, 0xFFFF, "{0} minutes", "UNKNOWN") } } ################################################################################################################################### # Type 24 # ################################################################################################################################### class HardwareSecurity : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static HardwareSecurity() { $stringTables = [HardwareSecurity]::GetStringTables("Type_24") [HardwareSecurity]::StringArrays = $stringTables.StringArrays [HardwareSecurity]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "PowerOnPasswordStatus" ) $labels.Add( "KeyboardPasswordStatus" ) $labels.Add( "AdministratorPasswordStatus" ) $labels.Add( "FrontPanelResetStatus" ) } [HardwareSecurity]::PropertyNames = $labels } HardwareSecurity([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Utility method for PowerOnPasswordStatus, KeyboardPasswordStatus, AdministratorPasswordStatus, FrontPanelResetStatus hidden [StringValue]_GetStatus([int]$offset, [int]$length) { $settings = $this.GetByteAtOffset(0x04) $status = [BitField]::Extract($settings, $offset, $length) return [StringValue]::new($status, "Status", [ref]$this) } # Get PowerOnPasswordStatus hidden [StringValue]GetPowerOnPasswordStatus() { return $this._GetStatus(0, 2) } # Get KeyboardPasswordStatus hidden [StringValue]GetKeyboardPasswordStatus() { return $this._GetStatus(2, 2) } # Get AdministratorPasswordStatus hidden [StringValue]GetAdministratorPasswordStatus() { return $this._GetStatus(4, 2) } # Get FrontPanelResetStatus hidden [StringValue]GetFrontPanelResetStatus() { return $this._GetStatus(6, 2) } } ################################################################################################################################### # Type 25 # ################################################################################################################################### class SystemPowerControls : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static SystemPowerControls() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "NextScheduledPowerOn" ) } [SystemPowerControls]::PropertyNames = $labels } SystemPowerControls([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } hidden [StringValueDateTime]GetNextScheduledPowerOn() { $schedule = [ArraySegment[Byte]]::new($this.Data, 4, 5) if ([Linq.Enumerable]::Sum([Int[]]$schedule) -eq 0) { return [StringValueDateTime]::new($null, $(Get-LocalizedString "NOT_DEFINED")) } else { $currentDate = Get-Date $year = $currentDate.Year $month = $this.ValidateData(4, @(1..12), $currentDate.Month) $day = $this.ValidateData(5, @(1..31), $currentDate.Day) $hour = $this.ValidateData(6, @(0..23), $currentDate.Hour) $minute = $this.ValidateData(7, @(0..59), $currentDate.Minute) $second = $this.ValidateData(8, @(0..59), $currentDate.Second) $nextScheduledPowerOn = [DateTime]::new($year, $month, $day, $hour, $minute, $second) if ($nextScheduledPowerOn -lt $currentDate) { $nextScheduledPowerOn = $nextScheduledPowerOn.AddYears(1) } $format = [CultureInfo]::CurrentCulture.DateTimeFormat.FullDateTimePattern return [StringValueDateTime]::new($nextScheduledPowerOn, "{0:$format}") } } hidden [Int]ValidateData([Int]$offset, [Array]$range, [Int]$defaultResult) { $unitOftime = [Int][BitConverter]::ToString($this.Data, $offset, 1) if (-Not ($unitOftime -in $range) ) { $unitOftime = $defaultResult } return $unitOftime } } ################################################################################################################################### # Type 26 # ################################################################################################################################### class VoltageProbe : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static VoltageProbe() { $stringTables = [VoltageProbe]::GetStringTables("Type_26") [VoltageProbe]::StringArrays = $stringTables.StringArrays [VoltageProbe]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "Description" ) $labels.Add( "Location" ) $labels.Add( "Status" ) $labels.Add( "MaximumValue" ) $labels.Add( "MinimumValue" ) $labels.Add( "Resolution" ) $labels.Add( "Tolerance" ) $labels.Add( "Accuracy" ) $labels.Add( "OEMDefinedInformation" ) $labels.Add( "NominalValue" ) } [VoltageProbe]::PropertyNames = $labels } VoltageProbe([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Description hidden [SMBString]GetDescription() { return $this.GetStringAtOffset(0x04) } # Get Location hidden [StringValue]GetLocation() { $locationAndStatus = $this.GetByteAtOffset(0x05) $location = [BitField]::Extract($locationAndStatus, 0, 5) return [StringValue]::new($location, "Location", [ref]$this) } # Get Status hidden [StringValue]GetStatus() { $locationAndStatus = $this.GetByteAtOffset(0x05) $status = [BitField]::Extract($locationAndStatus, 5, 3) return [StringValue]::new($status, "Status", [ref]$this) } # Get VoltageValue hidden [StringValue]GetVoltageValue($voltage) { return [StringValue]::new($voltage, 0x8000, "{0:F03} V", $voltage / 1000, "UNKNOWN") } # Get MaximumValue hidden [StringValue]GetMaximumValue() { $maximumValue = $this.GetWordAtOffset(0x06) return $this.GetVoltageValue($maximumValue) } # Get MinimumValue hidden [StringValue]GetMinimumValue() { $minimumValue = $this.GetWordAtOffset(0x08) return $this.GetVoltageValue($minimumValue) } # Get Resolution hidden [StringValue]GetResolution() { $resolution = $this.GetWordAtOffset(0x0A) return [StringValue]::new($resolution, 0x8000, "{0:F01} mV", $resolution / 10, "UNKNOWN") } # Get Tolerance hidden [StringValue]GetTolerance() { $tolerance = $this.GetWordAtOffset(0x0C) return $this.GetVoltageValue($tolerance) } # Get Accuracy hidden [StringValue]GetAccuracy() { $accuracy = $this.GetWordAtOffset(0x0E) return [StringValue]::new($accuracy, 0x8000, "{0:F02}", $accuracy / 100, "UNKNOWN") } # Get OEMDefinedInformation hidden [UInt32]GetOEMDefinedInformation() { return $this.GetDoubleWordAtOffset(0x10) } # Get NominalValue hidden [StringValue]GetNominalValue() { $nominalValue = $this.GetWordAtOffset(0x14) return $this.GetVoltageValue($nominalValue) } } ################################################################################################################################### # Type 27 # ################################################################################################################################### class CoolingDevice : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static CoolingDevice() { $stringTables = [CoolingDevice]::GetStringTables("Type_27") [CoolingDevice]::StringArrays = $stringTables.StringArrays [CoolingDevice]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "TemperatureProbeHandle" ) $labels.Add( "DeviceType" ) $labels.Add( "Status" ) $labels.Add( "CoolingUnitGroup" ) $labels.Add( "OEMDefinedInformation" ) $labels.Add( "NominalSpeed" ) } if ( [SMBIOS]::Version -ge [Version]::new(2, 7) ) { $labels.Add( "Description" ) } [CoolingDevice]::PropertyNames = $labels } CoolingDevice([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get TemperatureProbeHandle hidden [UInt16]GetTemperatureProbeHandle() { return $this.GetWordAtOffset(0x04) } # Get DeviceType hidden [StringValue]GetDeviceType() { $deviceTypeAndStatus = 103 #$this.GetByteAtOffset(0x06) $deviceType = [BitField]::Extract($deviceTypeAndStatus, 0, 5) return [StringValue]::new($deviceType, "DeviceType", [ref]$this) } # Get Status hidden [StringValue]GetStatus() { $deviceTypeAndStatus = 103 #$this.GetByteAtOffset(0x06) $status = [BitField]::Extract($deviceTypeAndStatus, 5, 3) return [StringValue]::new($status, "Status", [ref]$this) } # Get CoolingUnitGroup hidden [Byte]GetCoolingUnitGroup() { return $this.GetByteAtOffset(0x07) } # Get OEMDefinedInformation hidden [UInt32]GetOEMDefinedInformation() { return $this.GetDoubleWordAtOffset(0x08) } # Get NominalSpeed hidden [StringValue]GetNominalSpeed() { $nominalSpeed = $this.GetWordAtOffset(0x0C) return [StringValue]::new($nominalSpeed, 0x8000, "{0} rpm", "UNKNOWN") } # Get Description hidden [SMBString]GetDescription() { return $this.GetStringAtOffset(0x0E) } } ################################################################################################################################### # Type 28 # ################################################################################################################################### class TemperatureProbe : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static TemperatureProbe() { $stringTables = [TemperatureProbe]::GetStringTables("Type_28") [TemperatureProbe]::StringArrays = $stringTables.StringArrays [TemperatureProbe]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "Description" ) $labels.Add( "Location" ) $labels.Add( "Status" ) $labels.Add( "MaximumValue" ) $labels.Add( "MinimumValue" ) $labels.Add( "Resolution" ) $labels.Add( "Tolerance" ) $labels.Add( "Accuracy" ) $labels.Add( "OEMDefinedInformation" ) $labels.Add( "NominalValue" ) } [TemperatureProbe]::PropertyNames = $labels } TemperatureProbe([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Description hidden [SMBString]GetDescription() { return $this.GetStringAtOffset(0x04) } # Get Location hidden [StringValue]GetLocation() { $locationAndStatus = $this.GetByteAtOffset(0x05) $location = [BitField]::Extract($locationAndStatus, 0, 5) return [StringValue]::new($location, "Location", [ref]$this) } # Get Status hidden [StringValue]GetStatus() { $locationAndStatus = $this.GetByteAtOffset(0x05) $status = [BitField]::Extract($locationAndStatus, 5, 3) return [StringValue]::new($status, "Status", [ref]$this) } # Get TemperatureValue hidden [StringValueTemperature]GetTemperatureValue($temperature) { if ($temperature -eq 0x8000) { return [StringValueTemperature]::new($temperature, $(Get-LocalizedString "UNKNOWN")) } else { return [StringValueTemperature]::new($temperature / 10, [TemperatureUnit]::Celsius, 1) } } # Get MaximumValue hidden [StringValueTemperature]GetMaximumValue() { $maximumValue = $this.GetWordAtOffset(0x06) return $this.GetTemperatureValue($maximumValue) } # Get MinimumValue hidden [StringValueTemperature]GetMinimumValue() { $minimumValue = $this.GetWordAtOffset(0x08) return $this.GetTemperatureValue($minimumValue) } # Get Resolution hidden [StringValueTemperature]GetResolution() { $resolution = $this.GetWordAtOffset(0x0A) if ($resolution -eq 0x8000) { return [StringValueTemperature]::new($resolution, $(Get-LocalizedString "UNKNOWN")) } else { return [StringValueTemperature]::new($resolution / 1000, [TemperatureUnit]::Celsius, 3) } } # Get Tolerance hidden [StringValueTemperature]GetTolerance() { $tolerance = $this.GetWordAtOffset(0x0C) return $this.GetTemperatureValue($tolerance) } # Get Accuracy hidden [StringValue]GetAccuracy() { $accuracy = $this.GetWordAtOffset(0x0E) return [StringValue]::new($accuracy, 0x8000, "{0:F02}", $accuracy / 100, "UNKNOWN") } # Get OEMDefinedInformation hidden [UInt32]GetOEMDefinedInformation() { return $this.GetDoubleWordAtOffset(0x10) } # Get NominalValue hidden [StringValueTemperature]GetNominalValue() { $nominalValue = $this.GetWordAtOffset(0x14) return $this.GetTemperatureValue($nominalValue) } } ################################################################################################################################### # Type 29 # ################################################################################################################################### class ElectricalCurrentProbe : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static ElectricalCurrentProbe() { $stringTables = [ElectricalCurrentProbe]::GetStringTables("Type_29") [ElectricalCurrentProbe]::StringArrays = $stringTables.StringArrays [ElectricalCurrentProbe]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "Description" ) $labels.Add( "Location" ) $labels.Add( "Status" ) $labels.Add( "MaximumValue" ) $labels.Add( "MinimumValue" ) $labels.Add( "Resolution" ) $labels.Add( "Tolerance" ) $labels.Add( "Accuracy" ) $labels.Add( "OEMDefinedInformation" ) $labels.Add( "NominalValue" ) } [ElectricalCurrentProbe]::PropertyNames = $labels } ElectricalCurrentProbe([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Description hidden [SMBString]GetDescription() { return $this.GetStringAtOffset(0x04) } # Get Location hidden [StringValue]GetLocation() { $locationAndStatus = $this.GetByteAtOffset(0x05) $location = [BitField]::Extract($locationAndStatus, 0, 5) return [StringValue]::new($location, "Location", [ref]$this) } # Get Status hidden [StringValue]GetStatus() { $locationAndStatus = $this.GetByteAtOffset(0x05) $status = [BitField]::Extract($locationAndStatus, 5, 3) return [StringValue]::new($status, "Status", [ref]$this) } # Get ElectricalCurrentValue hidden [StringValue]GetElectricalCurrentValue($electricalValue) { return [StringValue]::new($electricalValue, 0x8000, "{0:F03} A", $electricalValue / 1000, "UNKNOWN") } # Get MaximumValue hidden [StringValue]GetMaximumValue() { $maximumValue = $this.GetWordAtOffset(0x06) return $this.GetElectricalCurrentValue($maximumValue) } # Get MinimumValue hidden [StringValue]GetMinimumValue() { $minimumValue = $this.GetWordAtOffset(0x08) return $this.GetElectricalCurrentValue($minimumValue) } # Get Resolution hidden [StringValue]GetResolution() { $resolution = $this.GetWordAtOffset(0x0A) return [StringValue]::new($resolution, 0x8000, "{0:F01} mA", $resolution / 10, "UNKNOWN") } # Get Tolerance hidden [StringValue]GetTolerance() { $tolerance = $this.GetWordAtOffset(0x0C) return $this.GetElectricalCurrentValue($tolerance) } # Get Accuracy hidden [StringValue]GetAccuracy() { $accuracy = $this.GetWordAtOffset(0x0E) return [StringValue]::new($accuracy, 0x8000, "{0:F02}", $accuracy / 100, "UNKNOWN") } # Get OEMDefinedInformation hidden [UInt32]GetOEMDefinedInformation() { return $this.GetDoubleWordAtOffset(0x10) } # Get NominalValue hidden [StringValue]GetNominalValue() { $nominalValue = $this.GetWordAtOffset(0x14) return $this.GetElectricalCurrentValue($nominalValue) } } ################################################################################################################################### # Type 30 # ################################################################################################################################### class OutOfBandRemoteAccess : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static OutOfBandRemoteAccess() { $stringTables = [OutOfBandRemoteAccess]::GetStringTables("Type_30") [OutOfBandRemoteAccess]::StringArrays = $stringTables.StringArrays [OutOfBandRemoteAccess]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 2) ) { $labels.Add( "ManufacturerName" ) $labels.Add( "InboundConnectionEnabled" ) $labels.Add( "OutboundConnectionEnabled" ) } [OutOfBandRemoteAccess]::PropertyNames = $labels } OutOfBandRemoteAccess([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get ManufacturerName hidden [SMBString]GetManufacturerName() { return $this.GetStringAtOffset(0x04) } # Get InboundConnectionEnabled hidden [Boolean]GetInboundConnectionEnabled() { $connections = $this.GetByteAtOffset(0x05) return [BitField]::Get($connections, 0) } # Get OutboundConnectionEnabled hidden [Boolean]GetOutboundConnectionEnabled() { $connections = $this.GetByteAtOffset(0x05) return [BitField]::Get($connections, 1) } } ################################################################################################################################### # Type 31 # ################################################################################################################################### class BootIntegrityServicesEntryPoint : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static BootIntegrityServicesEntryPoint() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "Checksum" ) $labels.Add( "16bitEntryPointAddress" ) $labels.Add( "32bitEntryPointAddress" ) } [BootIntegrityServicesEntryPoint]::PropertyNames = $labels } BootIntegrityServicesEntryPoint([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Calculate Checksum hidden [bool]CalculateChecksum([byte[]]$data) { $checksum = 0 for ($i = 0; $i -lt $data.Length; $i++) { $checksum = $checksum -bxor $data[$i] } return $checksum } # Get Checksum hidden [StringValue]GetChecksum() { if ($this.Checksum($this.Data)) { return [StringValue]::new($true, $(Get-LocalizedString "OK")) } else { return [StringValue]::new($false, $(Get-LocalizedString "INVALID")) } } # Get 16bitEntryPointAddress hidden [StringValue]Get16bitEntryPointAddress() { $bisEntry16 = $this.GetDoubleWordAtOffset(0x08) $segment = $bisEntry16 -shr 16 $offset = $bisEntry16 -band 0xFFFF $string = [String]::Format("{0:X4}:{1:X4}", $segment, $offset) $value = [Ordered]@{ Segment = $([StringValue]::new($segment, [String]::Format("{0:X4}", $segment))); Offset = $([StringValue]::new($offset, [String]::Format("{0:X4}", $offset ))) } return [StringValue]::new($value, $string) } # Get 32bitEntryPointAddress hidden [StringValue]Get32bitEntryPointAddress() { $bisEntry32 = $this.GetDoubleWordAtOffset(0x0C) return [StringValue]::new($bisEntry32, "0x{0:X8}") } } ################################################################################################################################### # Type 32 # ################################################################################################################################### class SystemBootInformation : SMBIOSStructure { static [Array]$PropertyNames static SystemBootInformation() { $stringTables = [SystemBootInformation]::GetStringTables("Type_32") [SystemBootInformation]::StringArrays = $stringTables.StringArrays [SystemBootInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "BootStatus" ) } [SystemBootInformation]::PropertyNames = $labels } SystemBootInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get BootStatus hidden [StringValue]GetBootStatus() { $bootStatus = $this.GetByteAtOffset(0x0A) $status = [SystemBootInformation]::StringArrays["Status"] if ($bootStatus -lt 0x08) { return [StringValue]::new($bootStatus, $status) } elseif ($bootStatus -ge 0x80 -and $bootStatus -lt 0xC0) { return [StringValue]::new($bootStatus, $status.0x80) } else { return [StringValue]::new($bootStatus, $status.0xC0) } } } ################################################################################################################################### # Type 33 # ################################################################################################################################### class _64BitMemoryErrorInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static _64BitMemoryErrorInformation() { # _32BitMemoryErrorInformation and _64BitMemoryErrorInformation strings are the same. $stringTables = [_64BitMemoryErrorInformation]::GetStringTables("Type_18") [_64BitMemoryErrorInformation]::StringArrays = $stringTables.StringArrays [_64BitMemoryErrorInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "ErrorType" ) $labels.Add( "ErrorGranularity" ) $labels.Add( "ErrorOperation" ) $labels.Add( "VendorSyndrome" ) $labels.Add( "MemoryArrayErrorAddress" ) $labels.Add( "DeviceErrorAddress" ) $labels.Add( "ErrorResolution" ) } [_64BitMemoryErrorInformation]::PropertyNames = $labels } _64BitMemoryErrorInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get ErrorType hidden [StringValue]GetErrorType() { $errorType = $this.GetByteAtOffset(0x04) return [StringValue]::new($errorType, "ErrorType", [ref]$this) } # Get ErrorGranularity hidden [StringValue]GetErrorGranularity() { $errorGranularity = $this.GetByteAtOffset(0x05) return [StringValue]::new($errorGranularity, "ErrorGranularity", [ref]$this) } # Get ErrorOperation hidden [StringValue]GetErrorOperation() { $errorOperation = $this.GetByteAtOffset(0x06) return [StringValue]::new($errorOperation, "ErrorOperation", [ref]$this) } # GetVendorSyndrome hidden [StringValue]GetVendorSyndrome() { $vendorSyndrome = $this.GetDoubleWordAtOffset(0x07) return [StringValue]::new($vendorSyndrome, 0x00000000, "0x{0:X8}", "UNKNOWN") } # Get MemoryArrayErrorAddress hidden [StringValue]GetMemoryArrayErrorAddress() { $memoryArrayErrorAddress = $this.GetQuadWordAtOffset(0x0B) if (([BitField]::HighUInt64($memoryArrayErrorAddress) -eq -0x80000000) -and ([BitField]::LowUInt64($memoryArrayErrorAddress) -eq 0x00)) { return [StringValue]::new($memoryArrayErrorAddress, $(Get-LocalizedString "UNKNOWN")) } return [StringValue]::new($memoryArrayErrorAddress, "0x{0:X16}") } # Get DeviceErrorAddress hidden [StringValue]GetDeviceErrorAddress() { $deviceErrorAddress = $this.GetQuadWordAtOffset(0x13) if (([BitField]::HighUInt64($deviceErrorAddress) -eq -0x80000000) -and ([BitField]::LowUInt64($deviceErrorAddress) -eq 0x00)) { return [StringValue]::new($deviceErrorAddress, $(Get-LocalizedString "UNKNOWN")) } return [StringValue]::new($deviceErrorAddress, "0x{0:X16}") } # Get ErrorResolution hidden [StringValue]GetErrorResolution() { $errorResolution = $this.GetDoubleWordAtOffset(0x1B) return [StringValue]::new($errorResolution, -0x80000000, "0x{0:X16}", $(Get-LocalizedString "UNKNOWN")) } } ################################################################################################################################### # Type 34 # ################################################################################################################################### class ManagementDevice : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static ManagementDevice() { $stringTables = [ManagementDevice]::GetStringTables("Type_34") [ManagementDevice]::StringArrays = $stringTables.StringArrays [ManagementDevice]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "Description" ) $labels.Add( "DeviceType" ) $labels.Add( "Address" ) $labels.Add( "AddressType" ) } [ManagementDevice]::PropertyNames = $labels } ManagementDevice([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Description hidden [SMBString]GetDescription() { return $this.GetStringAtOffset(0x04) } # Get DeviceType hidden [StringValue]GetDeviceType() { $deviceType = $this.GetByteAtOffset(0x05) return [StringValue]::new($deviceType, "DeviceType", [ref]$this) } # Get Address hidden [StringValue]GetAddress() { $address = $this.GetDoubleWordAtOffset(0x06) return [StringValue]::new($address, "0x{0:X8}") } # Get AddressType hidden [StringValue]GetAddressType() { $addressType = $this.GetByteAtOffset(0x0A) return [StringValue]::new($addressType, "AddressType", [ref]$this) } } ################################################################################################################################### # Type 35 # ################################################################################################################################### class ManagementDeviceComponent : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static ManagementDeviceComponent() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "Description" ) $labels.Add( "ManagementDeviceHandle" ) $labels.Add( "ComponentHandle" ) $labels.Add( "ThresholdHandle" ) } [ManagementDeviceComponent]::PropertyNames = $labels } ManagementDeviceComponent([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Description hidden [SMBString]GetDescription() { return $this.GetStringAtOffset(0x04) } # Get ManagementDeviceHandle hidden [UInt16]GetManagementDeviceHandle() { return $this.GetWordAtOffset(0x05) } # Get ComponentHandle hidden [UInt16]GetComponentHandle() { return $this.GetWordAtOffset(0x07) } # Get ThresholdHandle hidden [UInt16]GetThresholdHandle() { return $this.GetWordAtOffset(0x09) } } ################################################################################################################################### # Type 36 # ################################################################################################################################### class ManagementDeviceThresholdData : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static ManagementDeviceThresholdData() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3) ) { $labels.Add( "LowerThresholdNonCritical" ) $labels.Add( "UpperThresholdNonCritical" ) $labels.Add( "LowerThresholdCritical" ) $labels.Add( "UpperThresholdCritical" ) $labels.Add( "LowerThresholdNonRecoverable" ) $labels.Add( "UpperThresholdNonRecoverable" ) } [ManagementDeviceThresholdData]::PropertyNames = $labels } ManagementDeviceThresholdData([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get ThresholdData hidden [StringValue]GetThresholdData($value) { return [StringValue]::new($value, 0x8000, $null, "NOT_AVAILABLE") } # Get LowerThresholdNonCritical hidden [StringValue]GetLowerThresholdNonCritical() { $lowerThresholdNonCritical = $this.GetWordAtOffset(0x04) return $this.GetThresholdData($lowerThresholdNonCritical) } # Get UpperThresholdNonCritical hidden [StringValue]GetUpperThresholdNonCritical() { $upperThresholdNonCritical = $this.GetWordAtOffset(0x06) return $this.GetThresholdData($upperThresholdNonCritical) } # Get LowerThresholdCritical hidden [StringValue]GetLowerThresholdCritical() { $lowerThresholdCritical = $this.GetWordAtOffset(0x08) return $this.GetThresholdData($lowerThresholdCritical) } # Get UpperThresholdCritical hidden [StringValue]GetUpperThresholdCritical() { $upperThresholdCritical = $this.GetWordAtOffset(0x0A) return $this.GetThresholdData($upperThresholdCritical) } # Get LowerThresholdNonRecoverable hidden [StringValue]GetLowerThresholdNonRecoverable() { $lowerThresholdNonRecoverable = $this.GetWordAtOffset(0x0C) return $this.GetThresholdData($lowerThresholdNonRecoverable) } # Get UpperThresholdNonRecoverable hidden [StringValue]GetUpperThresholdNonRecoverable() { $upperThresholdNonRecoverable = $this.GetWordAtOffset(0x0D) return $this.GetThresholdData($upperThresholdNonRecoverable) } } ################################################################################################################################### # Type 37 # ################################################################################################################################### class MemoryChannelDevice { [String]$Load [UInt16]$Handle MemoryChannelDevice([String]$load, [UInt16]$handle) { $this.Load = $load $this.Handle = $handle } [String]ToString() { return [String]::Format("Load {0} Handle 0x{1:X4}", $($this.Load),$($this.Handle)) } } class MemoryChannel : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static MemoryChannel() { $stringTables = [MemoryChannel]::GetStringTables("Type_37") [MemoryChannel]::StringArrays = $stringTables.StringArrays [MemoryChannel]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3, 1) ) { $labels.Add( "_Type" ) $labels.Add( "MaximumLoad" ) $labels.Add( "Devices" ) } [MemoryChannel]::PropertyNames = $labels } MemoryChannel([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get ChannelType hidden [StringValue]Get_Type() { $channelType = $this.GetByteAtOffset(0x04) return [StringValue]::new($channelType, "ChannelType", [ref]$this) } # Get MaximumLoad hidden [Int]GetMaximumLoad() { $maximumLoad = $this.GetByteAtOffset(0x05) return $maximumLoad } # Get Devices hidden [Array]GetDevices() { $deviceCount = $this.GetByteAtOffset(0x06) $devices = [Collections.ArrayList]::new() for ($i = 0; $i -lt $deviceCount; $i++) { $load = $this.GetByteAtOffset(0x07 + 3 * $i) $handle = [BitConverter]::ToUInt16($this.data, 0x07 + 3 * $i + 1) $devices.Add( [MemoryChannelDevice]::new($load, $handle) ) } return $devices } } ################################################################################################################################### # Type 38 # ################################################################################################################################### class IPMIDeviceInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static IPMIDeviceInformation() { $stringTables = [IPMIDeviceInformation]::GetStringTables("Type_38") [IPMIDeviceInformation]::StringArrays = $stringTables.StringArrays [IPMIDeviceInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3, 1) ) { $labels.Add( "InterfaceType" ) $labels.Add( "SpecificationRevision" ) $labels.Add( "I2CTargetAddress" ) $labels.Add( "I2CSlaveAddress" ) $labels.Add( "NVStorageDeviceAddress" ) $labels.Add( "BaseAddress" ) $labels.Add( "Bus" ) $labels.Add( "RegisterSpacing" ) $labels.Add( "InterruptPolarity" ) $labels.Add( "InterruptTriggerMode" ) $labels.Add( "InterruptNumber" ) } [IPMIDeviceInformation]::PropertyNames = $labels } IPMIDeviceInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get InterfaceType hidden [StringValue]GetInterfaceType() { $interfaceType = $this.GetByteAtOffset(0x04) return [StringValue]::new($interfaceType, "InterfaceType", [ref]$this) } # Get SpecificationRevision hidden [Version]GetSpecificationRevision() { $revision = $this.GetByteAtOffset(0x05) $major = [BitField]::Extract($revision, 4, 4) $minor = [BitField]::Extract($revision, 0, 4) return [Version]::new($major, $minor) } # Get I2CTargetAddress hidden [StringValue]GetI2CTargetAddress() { $I2CTargetAddress = $this.GetByteAtOffset(0x06) return [StringValue]::new($I2CTargetAddress, "0x{0:X2}") } # Get I2CSlaveAddress hidden [StringValue]GetI2CSlaveAddress() { $I2CTargetAddress = $this.GetByteAtOffset(0x06) return [StringValue]::new($I2CTargetAddress -shr 1, "0x{0:X2}") } # Get NVStorageDeviceAddress hidden [StringValue]GetNVStorageDeviceAddress() { $NVStorageDeviceAddress = $this.GetByteAtOffset(0x07) return [StringValue]::new($NVStorageDeviceAddress, 0xFF, "0x{0:X}", "NOT_PRESENT") } # Get BaseAddress hidden [StringValue]GetBaseAddress() { $interfaceType = $this.GetByteAtOffset(0x04) $baseAddress = $this.GetQuadWordAtOffset(0x08) if ($interfaceType -eq 0x04) { $format = "0x{0:X2}" $baseAddress = [BitField]::Extract($baseAddress, 0, 7) } else { [UInt32]$baseAddressHigh = [BitField]::HighUInt64($baseAddress) [UInt32]$baseAddressLow = [BitField]::LowUInt64($baseAddress) -shr 1 $format = "0x{0:X8}{1:X8}" $string = [String]::Format($format, $baseAddressLow, $baseAddressHigh) return [StringValue]::new($baseAddress, $string) } return [StringValue]::new() } # Get Bus hidden [StringValue]GetBus() { $interfaceType = $this.GetByteAtOffset(0x04) if ($interfaceType -eq 0x04) { $bus = 0x04 } else { $baseAddress = $this.GetQuadWordAtOffset(0x08) $lowPart = [BitField]::LowUInt64($baseAddress) $bus = [BitField]::Get($lowPart, 0) } return [StringValue]::new($bus, "Bus", [ref]$this) } # Get BaseAddressModifier hidden [StringValue]BaseAddressModifier() { $baseAddressModifier = $this.GetByteAtOffset(0x10) return [StringValue]::new($baseAddressModifier, 0x00, "{0:G}", "UNUSED") } # Get RegisterSpacing hidden [StringValue]GetRegisterSpacing() { $interfaceType = $this.GetByteAtOffset(0x04) if ($interfaceType -eq 0x04) { return [StringValue]::new(-1, $(Get-LocalizedString "NOT_APPLICABLE")) } else { $baseAddressModifier = $this.GetByteAtOffset(0x10) $registerSpacing = [BitField]::Extract($baseAddressModifier, 6, 2) return [StringValue]::new($registerSpacing, "RegisterSpacing", [ref]$this) } } # Get InterruptPolarity hidden [StringValue]GetInterruptPolarity() { $interfaceType = $this.GetByteAtOffset(0x04) if ($interfaceType -eq 0x04) { return [StringValue]::new(-1, $(Get-LocalizedString "NOT_APPLICABLE")) } else { $baseAddressModifier = $this.GetByteAtOffset(0x10) $interruptInfo = [BitField]::Get($baseAddressModifier, 4) if ($interruptInfo) { $interruptPolarity = [BitField]::Get($baseAddressModifier, 1) return [StringValue]::new($interruptPolarity, "InterruptPolarity", [ref]$this) } else { return [StringValue]::new(-1, $(Get-LocalizedString "NOT_APPLICABLE")) } } } # Get InterruptTriggerMode hidden [StringValue]GetInterruptTriggerMode() { $interfaceType = $this.GetByteAtOffset(0x04) if ($interfaceType -eq 0x04) { return [StringValue]::new(-1, $(Get-LocalizedString "NOT_APPLICABLE")) } else { $baseAddressModifier = $this.GetByteAtOffset(0x10) $interruptInfo = [BitField]::Get($baseAddressModifier, 4) if ($interruptInfo) { $interruptTriggerMode = [BitField]::Get($baseAddressModifier, 0) return [StringValue]::new($interruptTriggerMode, "InterruptTriggerMode", [ref]$this) } else { return [StringValue]::new(-1, $(Get-LocalizedString "NOT_APPLICABLE")) } } } # Get InterruptNumber hidden [StringValue]GetInterruptNumber() { $interruptNumber = $this.GetByteAtOffset(0x11) return [StringValue]::new($interruptNumber, 0x00, "{0:G}", $(Get-LocalizedString "UNSPECIFIED")) } } ################################################################################################################################### # Type 39 # ################################################################################################################################### class SystemPowerSupply : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static SystemPowerSupply() { $stringTables = [SystemPowerSupply]::GetStringTables("Type_39") [SystemPowerSupply]::StringArrays = $stringTables.StringArrays [SystemPowerSupply]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 3, 1) ) { $labels.Add( "PowerUnitGroup" ) $labels.Add( "Location" ) $labels.Add( "DeviceName" ) $labels.Add( "Manufacturer" ) $labels.Add( "SerialNumber" ) $labels.Add( "AssetTagNumber" ) $labels.Add( "ModelPartNumber" ) $labels.Add( "RevisionLevel" ) $labels.Add( "MaxPowerCapacity" ) $labels.Add( "PowerSupplyType" ) $labels.Add( "PowerSupplyStatus" ) $labels.Add( "InputVoltageRangeSwitching" ) $labels.Add( "Characteristics" ) $labels.Add( "InputVoltageProbeHandle" ) $labels.Add( "CoolingDeviceHandle" ) $labels.Add( "InputCurrentProbeHandle" ) } [SystemPowerSupply]::PropertyNames = $labels } SystemPowerSupply([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get PowerUnitGroup hidden [Byte]GetPowerUnitGroup() { return $this.GetByteAtOffset(0x04) } # Get Location hidden [SMBString]GetLocation() { return $this.GetStringAtOffset(0x05) } # Get DeviceName hidden [SMBString]GetDeviceName() { return $this.GetStringAtOffset(0x06) } # Get Manufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x07) } # Get SerialNumber hidden [SMBString]GetSerialNumber() { return $this.GetStringAtOffset(0x08) } # Get AssetTagNumber hidden [SMBString]GetAssetTagNumber() { return $this.GetStringAtOffset(0x09) } # Get ModelPartNumber hidden [SMBString]GetModelPartNumber() { return $this.GetStringAtOffset(0x0A) } # Get RevisionLevel hidden [SMBString]GetRevisionLevel() { return $this.GetStringAtOffset(0x0B) } # Get MaxPowerCapacity hidden [StringValue]GetMaxPowerCapacity() { $maxPowerCapacity = $this.GetWordAtOffset(0x0C) return [StringValue]::new($maxPowerCapacity, 0x8000, "{0} W", "UNKNOWN") } # Get PowerSupplyType hidden [StringValue]GetPowerSupplyType() { $characteristics = $this.GetWordAtOffset(0x0E) $type = [BitField]::Extract($characteristics, 0 , 4) return [StringValue]::new($type, "PowerSupplyType", [ref]$this) } # Get PowerSupplyStatus hidden [StringValue]GetPowerSupplyStatus() { $characteristics = $this.GetWordAtOffset(0x0E) $status = [BitField]::Extract($characteristics, 7 , 3) return [StringValue]::new($status, "PowerSupplyStatus", [ref]$this) } # Get InputVoltageRangeSwitching hidden [StringValue]GetInputVoltageRangeSwitching() { $characteristics = $this.GetWordAtOffset(0x0E) $IVRS = [BitField]::Extract($characteristics, 3 , 4) return [StringValue]::new($IVRS, "InputVoltageRangeSwitching", [ref]$this) } # Get Characteristics hidden [StringValue[]]GetCharacteristics() { $characteristics = $this.GetWordAtOffset(0x0E) $powerSupply = [BitField]::Extract($characteristics, 0 , 3) return [BitFieldConverter]::ToStringValueArray($powerSupply, 3, "Characteristics", [ref]$this) } # Get ProbeHandle hidden [StringValue]GetProbeHandle($handle) { return [StringValue]::new($handle, 0xFFFF, $null, "NOT_PROVIDED") } # Get InputVoltageProbeHandle hidden [StringValue]GetInputVoltageProbeHandle() { $handle = $this.GetWordAtOffset(0x10) return $this.GetProbeHandle($handle) } # Get CoolingDeviceHandle hidden [StringValue]GetCoolingDeviceHandle() { $handle = $this.GetWordAtOffset(0x12) return $this.GetProbeHandle($handle) } # Get InputCurrentProbeHandle hidden [StringValue]GetInputCurrentProbeHandle() { $handle = $this.GetWordAtOffset(0x14) return $this.GetProbeHandle($handle) } } ################################################################################################################################### # Type 40 # ################################################################################################################################### class AdditionalInformationEntry { [UInt16]$ReferencedHandle [Byte]$ReferencedOffset [SMBString]$String [ArraySegment[Byte]]$Value AdditionalInformationEntry([UInt16]$referencedHandle, [Byte]$referencedOffset, [SMBString]$string, [ArraySegment[Byte]]$value) { $this.ReferencedHandle = $referencedHandle $this.ReferencedOffset = $referencedOffset $this.String = $string $this.Value = $value } [String]ToString() { return $this.String } } class AdditionalInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static AdditionalInformation() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 6) ) { $labels.Add( "AdditionalInformations" ) } [AdditionalInformation]::PropertyNames = $labels } AdditionalInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get NumberOfAdditionalInformationEntries hidden [Byte]GetNumberOfAdditionalInformationEntries() { return $this.GetByteAtOffset(0x04) } # Get AdditionalInformationEntries hidden [Array]GetAdditionalInformations() { $entries = $this.GetNumberOfAdditionalInformationEntries() $additionalInformations = [ArrayList]::new() $offset = 0x05 $length = 0 for ($i = 0; $i -lt $entries; $i++) { $offset = $offset + $length $length = $this.GetByteAtOffset($offset) $refHandle = $this.GetWordAtOffset($offset + 0x01) $refOffset = $this.GetByteAtOffset($offset + 0x03) $string = $this.GetStringAtOffset($offset + 0x04) $value = [ArraySegment[Byte]]::new($this.data, $offset + 0x05, $length - 0x05) $entry = [AdditionalInformationEntry]::new($refHandle, $refOffset, $string, $value) $additionalInformations.Add($entry) } return $additionalInformations } } ################################################################################################################################### # Type 41 # ################################################################################################################################### class OnboardDevicesExtendedInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static OnboardDevicesExtendedInformation() { $stringTables = [OnboardDevicesExtendedInformation]::GetStringTables("Type_41") [OnboardDevicesExtendedInformation]::StringArrays = $stringTables.StringArrays [OnboardDevicesExtendedInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(2, 6) ) { $labels.Add( "ReferenceDesignation" ) $labels.Add( "DeviceType" ) $labels.Add( "DeviceStatus" ) $labels.Add( "DeviceTypeInstance" ) $labels.Add( "BusAddress" ) } [OnboardDevicesExtendedInformation]::PropertyNames = $labels } OnboardDevicesExtendedInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get ReferenceDesignation hidden [SMBString]GetReferenceDesignation() { return $this.GetStringAtOffset(0x4) } # Get DeviceType hidden [StringValue]GetDeviceType() { $deviceType = $this.GetWordAtOffset(0x05) $type = [BitField]::Extract($deviceType, 0, 7) return [StringValue]::new($type, "DeviceType", [ref]$this) } # Get DeviceStatus hidden [StringValue]GetDeviceStatus() { $deviceType = $this.GetWordAtOffset(0x05) $status = [BitField]::Get($deviceType, 7) return [StringValue]::new($status, "DeviceStatus", [ref]$this) } # Get DeviceTypeInstance hidden [Byte]GetDeviceTypeInstance() { return $this.GetByteAtOffset(0x06) } # Get BusAddress hidden [StringValue]GetBusAddress() { return ([SMBIOSStructure]$this).Get_BusAddress(0x07) } } ################################################################################################################################### # Type 42 # ################################################################################################################################### enum IPAddressFormat { Unknown = 0x00 IPv4 = 0x01 IPv6 = 0x02 } enum AssignmentOrDiscovery { Unknown = 0x00 Static = 0x01 DHCP = 0x02 AutoConfigure = 0x03 HostSelected = 0x04 } class ManagementControllerHostInterface : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias hidden static [ArrayList]$PropertyNames hidden [ArrayList]$PropertyNamesEx static ManagementControllerHostInterface() { $stringTables = [ManagementControllerHostInterface]::GetStringTables("Type_42") [ManagementControllerHostInterface]::StringArrays = $stringTables.StringArrays [ManagementControllerHostInterface]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() [ManagementControllerHostInterface]::PropertyNames = $labels } ManagementControllerHostInterface([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -lt [Version]::new(3, 2) ) { $labels.Add( "InterfaceType" ) $interfaceType = $this.GetByteAtOffset(0x04) # OEM if ( ( $interfaceType -eq 0xF0 ) -and ( $this.Data.Length -ge 0x09 ) ) { $labels.Add( "VendorID") } } if ( [SMBIOS]::Version -ge [Version]::new(3, 2) ) { $labels.Add( "HostInterfaceType" ) $labels.Add( "DeviceType" ) $interfaceSpecificDataLength = $this.GetByteAtOffset(0x05) if ($interfaceSpecificDataLength -gt 0) { $deviceType = $this.GetByteAtOffset(0x06) switch ($deviceType) { 0x02 { # USB Network Interface $labels.Add( "VendorID" ) $labels.Add( "ProductID" ) $labels.Add( "SerialNumber" ) } 0x03 { # PCI/PCIe Network Interface $labels.Add( "VendorID" ) $labels.Add( "ProductID" ) $labels.Add( "SubsystemVendorID" ) $labels.Add( "SubsystemID" ) } 0x04 { # USB Network Interface v2 $labels.Add( "VendorID" ) $labels.Add( "ProductID" ) $labels.Add( "SerialNumber" ) $labels.Add( "MACAddress" ) if ( $interfaceSpecificDataLength -eq 0x11 ) # v1.3 { $labels.Add( "Characteristics" ) $labels.Add( "CredentialBootstrappingHandle" ) } } 0x05 { # PCI/PCIe Network Interface v2 $labels.Add( "VendorID" ) $labels.Add( "ProductID" ) $labels.Add( "SubsystemVendorID" ) $labels.Add( "SubsystemID" ) $labels.Add( "MACAddress" ) $labels.Add( "BusAddress" ) if ( $interfaceSpecificDataLength -eq 0x18 ) # v1.3 { $labels.Add( "Characteristics" ) $labels.Add( "CredentialBootstrappingHandle" ) } } {$_ -ge 0x80 -and $_ -le 0xFF} { # OEM $labels.Add( "VendorIANA" ) $labels.Add( "VendorData" ) } } } $interfaceTypeDataLength = $this.GetByteAtOffset(0x05) $protocolsCount = $this.GetByteAtOffset(0x06 + $interfaceTypeDataLength) if ($protocolsCount -gt 0) { $labels.Add( "ProtocolType" ) $base = 0x08 + $interfaceTypeDataLength $protocolType = $this.GetByteAtOffset($base + 0x00) switch ($protocolType) { 0x04 { # RedfishOverIP $labels.Add( "ServiceUUID" ) $labels.Add( "HostIPAssignmentType" ) $labels.Add( "HostIPAddress" ) $labels.Add( "HostIPMask" ) $labels.Add( "RedfishServiceIPDiscoveryType" ) $labels.Add( "RedfishServiceIPAddress" ) $labels.Add( "RedfishServiceIPMask" ) $labels.Add( "RedfishServiceIPPort" ) $labels.Add( "RedfishServiceVlanId" ) $labels.Add( "RedfishServiceHostname" ) break } Default { $labels.Add( "Protocols" ) } } } } $this.PropertyNamesEx = $labels } # Get InterfaceType hidden [StringValue]GetInterfaceType() { $interfaceType = $this.GetByteAtOffset(0x04) return [StringValue]::new($interfaceType, "InterfaceType", [ref]$this) } # Get HostInterfaceType hidden [StringValue]GetHostInterfaceType() { return $this.GetInterfaceType() } hidden [StringValue]GetDeviceType() { $deviceType = $this.GetByteAtOffset(0x06) return [StringValue]::new($deviceType, "DeviceType", [ref]$this) } hidden [StringValue]GetVendorID() { if ( [SMBIOS]::Version -lt [Version]::new(3, 2) ) { $vendorId = [Byte[]][ArraySegment[Byte]]::new($this.data, 0x05, 4) return [StringValue]::new($vendorId, [String]::Format("0x{0:X2}{1:X2}{2:X2}{3:X2}", $vendorId[0x00], $vendorId[0x01], $vendorId[0x02], $vendorId[0x03] ) ) } else { $deviceType = $this.GetByteAtOffset(0x06) $offset = 0 switch ($deviceType) { 0x04 { $offset = 0x01 } # USB Network Interface v2 0x05 { $offset = 0x01 } # PCI/PCIe Network Interface v2 } $vendorId = $this.GetWordAtOffset(0x07 + $offset) } return [StringValue]::new($vendorId, "0x{0:X4}") } hidden [StringValue]GetProductID() { $deviceType = $this.GetByteAtOffset(0x06) $offset = 0 switch ($deviceType) { 0x04 { $offset = 0x01 } # USB Network Interface v2 0x05 { $offset = 0x01 } # PCI/PCIe Network Interface v2 } $productId = $this.GetWordAtOffset(0x07 + $offset + 0x02) return [StringValue]::new($productId, "0x{0:X4}") } hidden [SMBString]GetSerialNumber() { $deviceType = $this.GetByteAtOffset(0x06) switch ($deviceType) { 0x02 { # USB Network Interface $serialNumberLength = $this.GetByteAtOffset(0x07 + 0x04) - 2 $rawSerialNumber = [ArraySegment[Byte]]::new($this.data, 0x07 + 0x06, $serialNumberLength) $serialNumber = [UnicodeEncoding]::Unicode.GetString($rawSerialNumber) if ($serialNumberLength -eq 0) { return $this.GetStringAtOffset(0xFF) } else { return [SMBString]::new($serialNumber) } } 0x04 { # USB Network Interface v2 return $this.GetStringAtOffset(0x07 + 0x05) } } return [StringValue]::new() } # Get SubsystemVendorID hidden [StringValue]GetSubsystemVendorID() { $deviceType = $this.GetByteAtOffset(0x06) $offset = 0 switch ($deviceType) { 0x05 { $offset = 0x01 } } $subsystemVendorID = $this.GetWordAtOffset(0x07 + $offset + 0x04) return [StringValue]::new($subsystemVendorID, "0x{0:X4}") } # Get SubsystemID hidden [StringValue]GetSubsystemID() { $deviceType = $this.GetByteAtOffset(0x06) $offset = 0 switch ($deviceType) { 0x05 { $offset = 0x01 } } $subsystemID = $this.GetWordAtOffset(0x07 + $offset + 0x06) return [StringValue]::new($subsystemID, "0x{0:X4}") } # Get MACAddress hidden [StringValue]GetMACAddress() { $deviceType = $this.GetByteAtOffset(0x06) $offset = 0 switch ($deviceType) { 0x04 { $offset = 0x06 } # USB Network Interface v2 0x05 { $offset = 0x09 } # PCI/PCIe Network Interface v2 } $MACAddress = [Byte[]][Linq.Enumerable]::Reverse( [ArraySegment[Byte]]::new($this.data, 0x07 + $offset, 6) ) return [StringValue]::new( [PhysicalAddress]::new($MACAddress), [BitConverter]::ToString($MACAddress) ) } # Get Address hidden [StringValue]GetBusAddress() { return ([SMBIOSStructure]$this).Get_BusAddress(0x0F) } # Get Characteristics hidden [StringValue[]]GetCharacteristics() { $deviceType = $this.GetByteAtOffset(0x06) $offset = 0 switch ($deviceType) { 0x04 { $offset = 0x0C } # USB Network Interface v2 0x05 { $offset = 0x13 } # PCI/PCIe Network Interface v2 } $characteristics = $this.GetWordAtOffset(0x07 + $offset) return [BitFieldConverter]::ToStringValueArray($characteristics, 1, "Characteristics", [ref]$this) } # Get CredentialBootstrappingHandle hidden [StringValue]GetCredentialBootstrappingHandle() { $deviceType = $this.GetByteAtOffset(0x06) $offset = 0 switch ($deviceType) { 0x04 { $offset = 0x0E } # USB Network Interface v2 0x05 { $offset = 0x15 } # PCI/PCIe Network Interface v2 } $handle = $this.GetWordAtOffset(0x07 + $offset) if ($handle -eq [UInt16]::MaxValue) { return [StringValue]::new($handle, $(Get-LocalizedString "NOT_SUPPORTED")) } else { return [StringValue]::new($handle, "0x{0:X4}") } } # Get VendorIANA hidden [StringValue]GetVendorIANA() { $vendorIANA = [Byte[]][ArraySegment[Byte]]::new($this.data, 0x07, 4) return [StringValue]::new($vendorIANA, [String]::Format("0x{0:X2}{1:X2}{2:X2}{3:X2}", $vendorIANA[0x00], $vendorIANA[0x01], $vendorIANA[0x02], $vendorIANA[0x03] ) ) } # Get VendorData hidden [StringValue]GetVendorData() { $vendorData = [Byte[]][ArraySegment[Byte]]::new($this.data, 0x07 + 0x04, $this.Data.Length - 0x07 - 0x04) if ($vendorData.Length -eq 0) { return [StringValue]::new(-1, $(Get-LocalizedString "NONE")) } else { return [StringValue]::new($vendorData, [BitConverter]::ToString($vendorData).Replace("-", "") ) } } # Get GetProtocolBaseAddress hidden [Int]GetProtocolBaseAddress() { $interfaceTypeDataLength = $this.GetByteAtOffset(0x05) $base = 0x08 + $interfaceTypeDataLength + 0x02 return $base } # Get GetProtocolType hidden [StringValue]GetProtocolType() { $interfaceTypeDataLength = $this.GetByteAtOffset(0x05) $base = 0x08 + $interfaceTypeDataLength $protocolType = $this.GetByteAtOffset($base + 0x00) return [StringValue]::new($protocolType, "ProtocolType", [ref]$this) } # Get ServiceUUID hidden [StringValue]GetServiceUUID() { $base = $this.GetProtocolBaseAddress() $serviceUUID = [Byte[]][ArraySegment[Byte]]::new($this.data, $base + 0x00, 16) $guid = [Guid]::new($serviceUUID).Guid.ToUpper() return [StringValue]::new([Guid]::new($serviceUUID), $guid) } # Get IPAssignmentOrDiscoveryType hidden [StringValue]GetIPAssignmentOrDiscoveryType([int]$offset) { $base = $this.GetProtocolBaseAddress() $hostIPAssignmentType = $this.GetByteAtOffset($base + $offset) return [StringValue]::new($hostIPAssignmentType, "AssignmentType", [ref]$this) } # Get IPAddressFormat hidden [StringValue]GetIPAddressFormat([int]$offset) { $base = $this.GetProtocolBaseAddress() $IPAddressFormat = $this.GetByteAtOffset($base + $offset) return [StringValue]::new($IPAddressFormat, "IPAddressFormat", [ref]$this) } # Get IsStaticOrAutoConfigure hidden [bool]IsStaticOrAutoConfigure([int]$offset) { $assignmentOrDiscoveryType = $this.GetIPAssignmentOrDiscoveryType($offset) if ( ($assignmentOrDiscoveryType.Value -eq [AssignmentOrDiscovery]::Static ) -or ($assignmentOrDiscoveryType.Value -eq [AssignmentOrDiscovery]::AutoConfigure) ) { return $true } return $false } # Get IPAddress hidden [StringValue]GetIPAddress([int]$offset, [StringValue]$IPAddressFormat, [bool]$IsStaticOrAutoConfigure) { if ($IsStaticOrAutoConfigure) { $base = $this.GetProtocolBaseAddress() $IPAddress = 0 $IPAddressLength = 0 if ($IPAddressFormat.Value -eq [IPAddressFormat]::IPv4) { $IPAddressLength = 4 } elseif ($IPAddressFormat.Value -eq [IPAddressFormat]::IPv6) { $IPAddressLength = 16 } else { $IPAddressLength = 0 } $IPAddress = [Byte[]][ArraySegment[Byte]]::new($this.data, $base + $offset, $IPAddressLength) return [StringValue]::new([IPAddress]::new($IPAddress)) } return [StringValue]::new(-1, $(Get-LocalizedString "NOT_DEFINED")) } # Get HostIPAssignmentType hidden [StringValue]GetHostIPAssignmentType() { return $this.GetIPAssignmentOrDiscoveryType(0x10) } # Get HostIPAddress hidden [StringValue]GetHostIPAddress() { return $this.GetIPAddress(0x12, $this.GetIPAddressFormat(0x11), $this.IsStaticOrAutoConfigure(0x10)) } hidden [StringValue]GetHostIPMask() { return $this.GetIPAddress(0x22, $this.GetIPAddressFormat(0x11), $this.IsStaticOrAutoConfigure(0x10)) } # Get RedfishServiceIPDiscoveryType hidden [StringValue]GetRedfishServiceIPDiscoveryType() { return $this.GetIPAssignmentOrDiscoveryType(0x32) } # Get RedfishServiceIPAddress hidden [StringValue]GetRedfishServiceIPAddress() { return $this.GetIPAddress(0x34, $this.GetIPAddressFormat(0x33), $this.IsStaticOrAutoConfigure(0x32)) } # Get RedfishServiceIPMask hidden [StringValue]GetRedfishServiceIPMask() { return $this.GetIPAddress(0x44, $this.GetIPAddressFormat(0x33), $this.IsStaticOrAutoConfigure(0x32)) } # Get RedfishServiceIPPort hidden [StringValue]GetRedfishServiceIPPort() { if ($this.IsStaticOrAutoConfigure(0x32)) { $base = $this.GetProtocolBaseAddress() $redfishServiceIPPort = $this.GetWordAtOffset($base + 0x54) return [StringValue]::new($redfishServiceIPPort) } return [StringValue]::new(-1, $(Get-LocalizedString "NOT_DEFINED")) } # Get RedfishServiceVlanId hidden [StringValue]GetRedfishServiceVlanId() { if ($this.IsStaticOrAutoConfigure(0x32)) { $base = $this.GetProtocolBaseAddress() $redfishServiceVlanId = $this.GetDoubleWordAtOffset($base + 0x56) return [StringValue]::new($redfishServiceVlanId) } return [StringValue]::new(-1, $(Get-LocalizedString "NOT_DEFINED")) } # Get RedfishServiceHostname hidden [SMBString]GetRedfishServiceHostname() { $base = $this.GetProtocolBaseAddress() $redfishServiceHostnameLength = $this.GetByteAtOffset($base + 0x5A) $rawRedfishServiceHostname = [Byte[]][ArraySegment[Byte]]::new($this.data, $base + 0x5B, $redfishServiceHostnameLength) $redfishServiceHostname = [UnicodeEncoding]::ASCII.GetString($rawRedfishServiceHostname) if ($redfishServiceHostnameLength -eq 0) { return $this.GetStringAtOffset(0xFF) } else { return [SMBString]::new($redfishServiceHostname) } } # Get Protocols hidden [StringValue]GetProtocols() { $base = $this.GetProtocolBaseAddress() $protocols = [Byte[]][ArraySegment[Byte]]::new($this.data, $base, $this.data.Length - $base) if ($protocols) { return [StringValue]::new($protocols, [BitConverter]::ToString($protocols).Replace("-","")) } return [StringValue]::new(-1, $(Get-LocalizedString "NOT_DEFINED")) } } ################################################################################################################################### # Type 43 # ################################################################################################################################### class TPMDevice : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static TPMDevice() { $stringTables = [TPMDevice]::GetStringTables("Type_43") [TPMDevice]::StringArrays = $stringTables.StringArrays [TPMDevice]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(3, 1) ) { $labels.Add( "VendorID" ) $labels.Add( "SpecificationVersion" ) $labels.Add( "FirmwareVersion" ) $labels.Add( "Description" ) $labels.Add( "Characteristics" ) $labels.Add( "OEMDefinedInformation" ) } [TPMDevice]::PropertyNames = $labels } TPMDevice([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get VendorID hidden [StringValue]GetVendorID() { $vendor = [ArraySegment[Byte]]::new($this.data, 0x04, 4) $vendorID = "'" foreach ($char in $vendor) { if (($char -eq 0x00) -or ($char -eq 0x20)) { $vendorID = $vendorID + " " } else { $vendorID = $vendorID + $([Text.Encoding]::ASCII.GetChars($char)) } } $vendorID = $vendorID + "'" return [StringValue]::new($vendor, $vendorID) } # Get SpecVersion hidden [Version]GetSpecificationVersion() { $majorSpecVersion = $this.GetByteAtOffset(0x08) $minorSpecVersion = $this.GetByteAtOffset(0x09) return [Version]::new($majorSpecVersion, $minorSpecVersion) } # Get FirmwareVersion hidden [Version]GetFirmwareVersion() { $major = 0 $minor = 0 switch ($this.GetSpecificationVersion().Major) { 0x01 { $major = $this.GetByteAtOffset(0x0C) $minor = $this.GetByteAtOffset(0x0D) } 0x02 { $major = [BitField]::Extract($this.GetDoubleWordAtOffset(0x0A), 16, 16) $minor = [BitField]::Extract($this.GetDoubleWordAtOffset(0x0A), 0, 16) } } return [version]::new($major, $minor) } # Get Description hidden [SMBString]GetDescription() { return $this.GetStringAtOffset(0x12) } # Get Characteristics hidden [StringValue[]]GetCharacteristics() { $characteristics = $this.GetQuadWordAtOffset(0x13) return [BitFieldConverter]::ToStringValueArray($characteristics, 5, "Characteristics", [ref]$this) } # Get OEMDefinedInformation hidden [UInt32]GetOEMDefinedInformation() { return $this.GetDoubleWordAtOffset(0x1B) } } ################################################################################################################################### # Type 44 # ################################################################################################################################### class ProcessorAdditionalInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static ProcessorAdditionalInformation() { $stringTables = [ProcessorAdditionalInformation]::GetStringTables("Type_44") [ProcessorAdditionalInformation]::StringArrays = $stringTables.StringArrays [ProcessorAdditionalInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(3, 3) ) { $labels.Add( "ReferencedHandle" ) $labels.Add( "ProcessorType" ) } [ProcessorAdditionalInformation]::PropertyNames = $labels } ProcessorAdditionalInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } hidden [UInt16]GetReferencedHandle() { return $this.GetWordAtOffset(0x04) } hidden [StringValue]GetProcessorType() { $processorType = $this.GetByteAtOffset(0x07) return [StringValue]::new($processorType, "ProcessorType", [ref]$this) } } ################################################################################################################################### # Type 45 # ################################################################################################################################### class FirmwareInventoryInformation : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static FirmwareInventoryInformation() { $stringTables = [FirmwareInventoryInformation]::GetStringTables("Type_45") [FirmwareInventoryInformation]::StringArrays = $stringTables.StringArrays [FirmwareInventoryInformation]::StringArrayNameAlias = $stringTables.StringArrayNameAlias $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(3, 5) ) { $labels.Add( "FirmwareComponentName" ) $labels.Add( "FirmwareVersion" ) $labels.Add( "FirmwareId" ) $labels.Add( "ReleaseDate" ) $labels.Add( "Manufacturer" ) $labels.Add( "LowestSupportedVersion" ) $labels.Add( "ImageSize" ) $labels.Add( "Characteristics" ) $labels.Add( "State" ) $labels.Add( "AssociatedComponents" ) } [FirmwareInventoryInformation]::PropertyNames = $labels } FirmwareInventoryInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get Version hidden [StringValue]GetVersion([String]$version) { $versionFormat = $this.GetByteAtOffset(0x06) return [StringValue]::new($versionFormat, $version) } # Get FirmwareComponentName hidden [SMBString]GetFirmwareComponentName() { return $this.GetStringAtOffset(0x04) } # Get FirmwareVersion hidden [StringValue]GetFirmwareVersion() { $firmwareVersion = $($this.GetStringAtOffset(0x05)).DisplayValue return $this.GetVersion($firmwareVersion) } # Get FirmwareId hidden [StringValue]GetFirmwareId() { $firmwareIdFormat = $this.GetByteAtOffset(0x08) $firmwareId = $($this.GetStringAtOffset(0x07)).DisplayValue return [StringValue]::new($firmwareIdFormat, $firmwareId) } # Get ReleaseDate hidden [StringValueDateTime]GetReleaseDate() { $releaseDate = $($this.GetStringAtOffset(0x09)).DisplayValue if ([String]::IsNullOrEmpty($releaseDate)) { return [StringValueDateTime]::new($null, $(Get-LocalizedString "NOT_AVAILABLE")) } else { $culture = [CultureInfo]::CreateSpecificCulture("en-US") [DateTime]$date = [DateTime]::new(0) if( [DateTime]::TryParse($releaseDate, $culture, [DateTimeStyles]::None, [ref]$date) ) { if ($date -eq $([DateTime]"2021-05-15T00:00:00Z") ) { return [StringValueDateTime]::new($date, $(Get-LocalizedString "UNKNOWN")) } else { return [StringValueDateTime]::new($date) } } else { return [StringValueDateTime]::new($releaseDate, $releaseDate) } } } # Get Manufacturer hidden [SMBString]GetManufacturer() { return $this.GetStringAtOffset(0x0A) } # Get LowestSupportedVersion hidden [StringValue]GetLowestSupportedVersion() { $lowestSupportedVersion = $($this.GetStringAtOffset(0x0B)).DisplayValue return $this.GetVersion($lowestSupportedVersion) } # Get ImageSize hidden [StringValueMemorySize]GetImageSize() { $sizeInBytes = $this.GetQuadWordAtOffset(0x0C) if ($sizeInBytes -eq [UInt64]::MaxValue) { return [StringValueMemorySize]::new(0xFFFFFFFF, "Size", [ref]$this, -1, [MemorySizeUnit]::Unknown) } else { $unit = [MemorySizeUnit]::B } return [StringValueMemorySize]::new($sizeInBytes, $unit) } # Get Characteristics hidden [StringValue[]]GetCharacteristics() { $characteristics = $this.GetWordAtOffset(0x14) return [BitFieldConverter]::ToStringValueArray($characteristics, 2, "Characteristics", [ref]$this) } # Get State hidden [StringValue]GetState() { $state = $this.GetByteAtOffset(0x16) return [StringValue]::new($state, "State", [ref]$this) } # Get AssociatedComponents hidden [UInt16[]]GetAssociatedComponents() { $components = $this.GetByteAtOffset(0x17) $associatedComponents = [Collections.ArrayList]::new() if ($components.Count -ge 1) { for ($component=0; $component -lt $components; $component++) { $handle = $this.GetWordAtOffset(0x18 + $component * 2) $associatedComponents.Add($handle) } } return $associatedComponents } } ################################################################################################################################### # Type 46 # ################################################################################################################################### class StringProperty : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static StringProperty() { $labels = [Collections.ArrayList]::new() if ( [SMBIOS]::Version -ge [Version]::new(3, 5) ) { $labels.Add( "StringPropertyID" ) $labels.Add( "StringPropertyValue" ) $labels.Add( "ParentHandle" ) } [StringProperty]::PropertyNames = $labels } StringProperty([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } # Get StringPropertyID hidden [UInt16]GetStringPropertyID() { return $this.GetWordAtOffset(0x04) } # Get StringPropertyValue hidden [Byte]GetStringPropertyValue() { return $this.GetByteAtOffset(0x6) } # Get ParentHandle hidden [UInt16]GetParentHandle() { return $this.GetWordAtOffset(0x07) } } ################################################################################################################################### # Type 47..125 # ################################################################################################################################### class Reserved : SMBIOSStructure { static [Array]$PropertyNames static Reserved() { $labels = [Collections.ArrayList]::new() $labels.Add( "Data" ) $labels.Add( "Strings" ) [Reserved]::PropertyNames = $labels } Reserved([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } hidden [Byte[]]GetData() { return $this.Data } hidden [String[]]GetStrings() { return $this.Strings } } ################################################################################################################################### # Type 126 # ################################################################################################################################### class Inactive : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static Inactive() { $labels = [Collections.ArrayList]::new() [Inactive]::PropertyNames = $labels } Inactive([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } } ################################################################################################################################### # Type 127 # ################################################################################################################################### class EndOfTable : SMBIOSStructure { hidden static [Hashtable]$StringArrays hidden static [Hashtable]$StringArrayNameAlias static [Array]$PropertyNames static EndOfTable() { $labels = [Collections.ArrayList]::new() [EndOfTable]::PropertyNames = $labels } EndOfTable([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } } ################################################################################################################################### # Type 128..255 # ################################################################################################################################### class OEMSpecificInformation : SMBIOSStructure { static [Array]$PropertyNames static OEMSpecificInformation() { $labels = [Collections.ArrayList]::new() $labels.Add( "Data" ) $labels.Add( "Strings" ) [OEMSpecificInformation]::PropertyNames = $labels } OEMSpecificInformation([Byte]$type, [String]$description, [String[]]$keywords, [Byte]$length, [UInt16]$handle, [Byte[]]$data, [String[]]$strings) : base($type, $description, $keywords, $length, $handle, $data, $strings) { } hidden [Byte[]]GetData() { return $this.Data } hidden [String[]]GetStrings() { return $this.Strings } } |