Lenovo BIOS Manipulation: Get-LenovoBIOSSetting

First An Apology

I owe you an apology because I forgot to follow up: A year ago I posted about getting ‘pretty’ BIOS data via PowerShell+WMI but never followed up with a function/script; which I’ve been using for sometime now.  I lost sight of this so sorry about that.

Explanation

There really isn’t much to this: Execute Get-BIOSSetting without any parameters to pull ALL the BIOS settings from the current machine.

If you’re on a ThinkPad Laptop (T440 through T470, X240 through X270) it’ll output data like this


ComputerName    Setting                             CurrentValue                          OptionalValue
------------    -------                             ------------                          -------------
Leno-T470s AdaptiveThermalManagementAC         MaximizePerformance                   N/A
Leno-T470s AdaptiveThermalManagementBattery    Balanced                              N/A
Leno-T470s AlwaysOnUSB                         Enable                                N/A
Leno-T470s AMTControl                          Enable                                N/A
Leno-T470s BIOSPasswordAtBootDeviceList        Disable                               N/A
Leno-T470s BIOSPasswordAtReboot                Disable                               N/A
Leno-T470s BIOSPasswordAtUnattendedBoot        Enable                                N/A
Leno-T470s BIOSUpdateByEndUsers                Enable                                N/A
Leno-T470s BluetoothAccess                     Enable                                N/A
Leno-T470s BootDeviceListF12Option             Enable                                N/A
Leno-T470s BootDisplayDevice                   LCD                                   N/A
Leno-T470s BootMode                            Quick                                 N/A
Leno-T470s BootOrder                           USBCD:USBFDD:NVMe0:HDD0:USBHDD:PCILAN N/A
...
Leno-T470s USBPortAccess                       Enable                                N/A
Leno-T470s VirtualizationTechnology            Disable                               N/A
Leno-T470s VTdFeature                          Disable                               N/A
Leno-T470s WakeByThunderbolt                   Enable                                N/A
Leno-T470s WakeOnLAN                           ACOnly                                N/A
Leno-T470s WakeOnLANDock                       Enable                                N/A
Leno-T470s WiGig                               Enable                                N/A
Leno-T470s WiGigWake                           Disable                               N/A
Leno-T470s WindowsUEFIFirmwareUpdate           Enable                                N/A
Leno-T470s WirelessAutoDisconnection           Disable                               N/A
Leno-T470s WirelessLANAccess                   Enable                                N/A
Leno-T470s WirelessWANAccess                   Enable                                N/A

However if you’re on a ThinkCentre, like a M93, M900, M910 it’ll output something like this


ComputerName    Setting                                   CurrentValue                                                                                                              OptionalValue
------------    -------                                   ------------                                                                                                              -------------
Leno-M910 After Power Loss                          Last State                                                                                                                      Power On,Power Off,Last State
Leno-M910 Alarm Date(MM/DD/YYYY)                    [01/01/2016][Status:ShowOnly]                                                                                                   N/A
Leno-M910 Alarm Day of Week                         Sunday                                                                                                                          Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,SaturdayStatus:ShowOnly
Leno-M910 Alarm Time(HH:MM:SS)                      [00:00:00][Status:ShowOnly]                                                                                                     N/A
Leno-M910 Allow Flashing BIOS to a Previous Version Yes                                                                                                                             No,Yes
Leno-M910 Automatic Boot Sequence                   Network 1:M.2 Drive 1:PCIE4X_1 Drive:PCIE16X_1 Drive:SATA 1:SATA 2:SATA 3:SATA 4:Other Device                                   Network 2:Network 3:Network 4:USB FDD:USB HDD:USB CDROM:USB KEY
Leno-M910 Boot Agent                                PXE                                                                                                                             Disabled,PXE
Leno-M910 Boot Up Num-Lock Status                   On                                                                                                                              Off,On
...
Leno-M910 User Defined Alarm Time                   [00:00:00][Status:ShowOnly]                                                                                                     N/A
Leno-M910 VT-d                                      Enabled                                                                                                                         Disabled,Enabled
Leno-M910 Wake from Serial Port Ring                Primary                                                                                                                         Primary,Automatic,Disabled
Leno-M910 Wake on LAN                               Automatic                                                                                                                       Primary,Automatic,Disabled
Leno-M910 Wake Up on Alarm                          Disabled                                                                                                                        Single Event,Daily Event,Weekly Event,Disabled,User Defined
Leno-M910 Wednesday                                 Disabled                                                                                                                        Disabled,EnabledStatus:ShowOnly
Leno-M910 Windows UEFI Firmware Update              Enabled                                                                                                                         Disabled,Enabled

I like that the Desktop’s provide valid configuration settings and I hope this is something that will one day make it over to the laptops.

My two favorite parts about this script:

  • Supports querying remote systems
  • Supports querying for all, single or multiple specific settings

The script isn’t perfect but it works for our needs on our systems but I’m interested in hearing from you.

Function: Get-LenovoBIOSSetting

Usage

Get-LenovoBIOSSetting

Get-LenovoBIOSSetting -Setting Wi%

Get-LenovoBIOSSetting -ComputerName Leno-T470 -Setting 'Fingerprint%'

Get-LenovoBIOSSetting -ComputerName Leno-M900,Leno-M910 -Setting 'USB%','C State Support','Intel(R) Virtualization Technology'

Full code below


#region Function Get-LenovoBIOSSetting
Function Get-LenovoBIOSSetting
    {
        [cmdletbinding()]
        Param
            (
                [Parameter(Mandatory=$false)]
                    [string[]]$ComputerName = $env:computername,

                [Parameter(Mandatory=$false)]
                    [string[]]$Setting
            )

        Begin { [System.Collections.ArrayList]$BIOSSetting = @() }

        Process
            {
                foreach($Computer in $ComputerName)
                    {
                        if($Setting)
                            {
                                Foreach($Item in $Setting)
                                    {
                                        Try
                                            {
                                                $arrCurrentBIOSSetting = gwmi -class Lenovo_BiosSetting -namespace root\wmi -Filter "CurrentSetting like '$Item,%'" -ComputerName $Computer -ErrorAction Stop | ? { $_.CurrentSetting -ne "" } | Select -ExpandProperty CurrentSetting
                                                Foreach($CurrentBIOSSetting in $arrCurrentBIOSSetting)
                                                    {
                                                        [string]$CurrentItem = $CurrentBIOSSetting.SubString(0,$($CurrentBIOSSetting.IndexOf(',')))
                                                
                                                        if($CurrentBIOSSetting.IndexOf(';') -gt 0) { [string]$CurrentValue = $CurrentBIOSSetting.SubString($($CurrentBIOSSetting.IndexOf(',')+1),$CurrentBIOSSetting.IndexOf(';')-$($CurrentBIOSSetting.IndexOf(',')+1)) }
                                                        else { [string]$CurrentValue = $CurrentBIOSSetting.SubString($($CurrentBIOSSetting.IndexOf(',')+1)) }
                                                
                                                        if($CurrentBIOSSetting.IndexOf(';') -gt 0)
                                                            {
                                                                [string]$OptionalValue = $CurrentBIOSSetting.SubString($($CurrentBIOSSetting.IndexOf(';')+1))
                                                                [string]$OptionalValue = $OptionalValue.Replace('[','').Replace(']','').Replace('Optional:','').Replace('Excluded from boot order:','')
                                                            }
                                                        Else { [string]$OptionalValue = 'N/A' }
                                                                                
                                                        $BIOSSetting += [pscustomobject]@{ComputerName=$Computer;Setting=$CurrentItem;CurrentValue=$CurrentValue;OptionalValue=$OptionalValue;}
                                                
                                                        Remove-Variable CurrentItem,CurrentValue,OptionalValue -ErrorAction SilentlyContinue -WhatIf:$false
                                                    }
                                                Remove-Variable arrCurrentBIOSSetting -ErrorAction SilentlyContinue -WhatIf:$false
                                            }
                                        Catch { Write-Output "ERROR: UNABLE TO QUERY THE BIOS VIA CLASS [Lenovo_BiosSeting] ON [$Computer] - POSSIBLE INVALID SETTING SPECIFIED [$Item][$CurrentItem]: $_"; throw }
                                    }
                            }
                        Else
                            {
                                Try
                                    {
                                        $arrCurrentBIOSSetting = gwmi -class Lenovo_BiosSetting -namespace root\wmi -ComputerName $Computer -ErrorAction Stop | ? { $_.CurrentSetting -ne "" } | Select -ExpandProperty CurrentSetting
                                        Foreach($CurrentBIOSSetting in $arrCurrentBIOSSetting)
                                            {
                                                [string]$CurrentItem = $CurrentBIOSSetting.SubString(0,$($CurrentBIOSSetting.IndexOf(',')))
                                        
                                                if($CurrentBIOSSetting.IndexOf(';') -gt 0) { [string]$CurrentValue = $CurrentBIOSSetting.SubString($($CurrentBIOSSetting.IndexOf(',')+1),$CurrentBIOSSetting.IndexOf(';')-$($CurrentBIOSSetting.IndexOf(',')+1)) }
                                                else { [string]$CurrentValue = $CurrentBIOSSetting.SubString($($CurrentBIOSSetting.IndexOf(',')+1)) }
                                                                        
                                                if($CurrentBIOSSetting.IndexOf(';') -gt 0)
                                                    {
                                                        [string]$OptionalValue = $CurrentBIOSSetting.SubString($($CurrentBIOSSetting.IndexOf(';')+1))
                                                        [string]$OptionalValue = $OptionalValue.Replace('[','').Replace(']','').Replace('Optional:','').Replace('Excluded from boot order:','')
                                                    }
                                                Else { [string]$OptionalValue = 'N/A' }
                                                                                                                        
                                                $BIOSSetting += [pscustomobject]@{ComputerName=$Computer;Setting=$CurrentItem;CurrentValue=$CurrentValue;OptionalValue=$OptionalValue;}
                                        
                                                Remove-Variable CurrentItem,CurrentValue,OptionalValue -ErrorAction SilentlyContinue -WhatIf:$false
                                            }
                                        Remove-Variable arrCurrentBIOSSetting -ErrorAction SilentlyContinue -WhatIf:$false
                                    }
                                Catch { Write-Output "ERROR: UNABLE TO QUERY THE BIOS VIA CLASS [Lenovo_BiosSeting] ON [$Computer]: $_"; throw }
                            }
                    }
            }
        
        End { $BIOSSetting }
    }
#endregion Function Get-LenovoBIOSSetting

Wrap It Up!

If you decide to try this and run into problems or have questions, please let me know as I’m generally interested in use cases and constructive feedback.

Thanks and Good Providence to you!

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s