LenovoBIOS.psm1


#
#
# Lenovo BIOS Module
#
#

$ErrorActionPreference = 'Stop'

#
# Private common function: Show-ProgressBar
#

Function Show-ProgressBar {

    Param (

        [String]$Activity,
        [Int]$TotalItems,
        [Int]$Counter,
        [String]$ProcessItem

    )

    [Int]$PercentComplete = ($Counter / $TotalItems * 100)

    Write-Progress -Activity $Activity -PercentComplete $PercentComplete -CurrentOperation "$("$Counter of $TotalItems") - $($PercentComplete)$("% Complete.")" -Status "$("Processing: ")$($ProcessItem)"

}


#
# Lenovo BIOS functions
#

Function Get-LenovoBIOSCurrentSetting {

    <#
 
     .SYNOPSIS
     Get all the current BIOS settings
 
     .DESCRIPTION
     Get all the current BIOS settings
 
     .PARAMETER ComputerName
     Name of the host to retrieve the BIOS settings from
 
     .EXAMPLE
     Get-LenovoBIOSCurrentSetting -ComputerName LabPC2064
 
     .NOTES
     N/A
 
     .LINK
     N/A
 
    #>


    Param (

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter computer name'
                   )
        ]

        [String[]]$ComputerName

    )

    BEGIN {

        $TotalItems = $ComputerName.Count

        If ($TotalItems -eq 0) {

            $TotalItems = 1
            $FromPipeline = $True

        }

        $Index = 1

        Function Show-Output ($Values) {

            $OutputObj = New-Object -TypeName PSObject

            $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Values[0]
            $OutputObj | Add-Member -MemberType NoteProperty -Name SettingName -Value $Values[1]
            $OutputObj | Add-Member -MemberType NoteProperty -Name Value -Value $Values[2]
            $OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $Values[3]

            Write-Output $OutputObj

        }

    }

    PROCESS {

        ForEach ($Computer In $ComputerName) {

            If ($FromPipeline) {

                Show-ProgressBar -Activity 'Getting BIOS Settings' -TotalItems $TotalItems -Counter 1 -ProcessItem $Computer.ToUpper()

            }

            Else {

                Show-ProgressBar -Activity 'Getting BIOS Settings' -TotalItems $TotalItems -Counter $Index -ProcessItem $Computer.ToUpper()

                $Index++

            }

            If (Test-Connection $Computer -Count 1 -Quiet) {

                Try {

                    $LenovoSettings = Get-WmiObject -Class Lenovo_BiosSetting -NameSpace Root\WMI -ComputerName $Computer | Where-Object {$_.CurrentSetting -ne ''}

                    ForEach ($Setting In $LenovoSettings) {

                        $Temp = $Setting.CurrentSetting -split ','

                        Show-Output ($Computer.ToUpper(), $Temp[0], $Temp[1], 'Ok')

                    }

                }

                Catch {

                    Show-Output ($Computer.ToUpper(), '', '', $PSItem.Exception.Message)

                }

            }

            Else {

                Show-Output ($Computer.ToUpper(), '', '', 'Unreachable')

            }

        }

    }

    END {}

}


Function Get-LenovoBIOSSettingState {

    <#
 
     .SYNOPSIS
     Get the current selected BIOS setting
 
     .DESCRIPTION
     Get the current selected BIOS setting
 
     .PARAMETER ComputerName
     Name of the host to retrieve the BIOS settings from
 
     .PARAMETER SettingName
     BIOS setting to query
 
     .EXAMPLE
     Get-LenovoBIOSSettingState -ComputerName LabPC2064 -SettingName WakeOnLAN
 
     .NOTES
     The Lenovo BIOS settings are case sensitive
 
     .LINK
     N/A
 
    #>


    Param (

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter computer name'
                   )
        ]

        [String[]]$ComputerName,

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter setting name'
                   )
        ]

        [String[]]$SettingName

    )

    BEGIN {

        $TotalItems = $ComputerName.Count

        If ($TotalItems -eq 0) {

            $TotalItems = 1
            $FromPipeline = $True

        }

        $Index = 1

        Function Show-Output ($Values) {

            $OutputObj = New-Object -TypeName PSObject

            $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Values[0]
            $OutputObj | Add-Member -MemberType NoteProperty -Name SettingName -Value $Values[1]
            $OutputObj | Add-Member -MemberType NoteProperty -Name State -Value $Values[2]
            $OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $Values[3]

            Write-Output $OutputObj

        }

    }

    PROCESS {

        ForEach ($Computer In $ComputerName) {

            If ($FromPipeline) {

                Show-ProgressBar -Activity 'Getting BIOS Settings' -TotalItems $TotalItems -Counter 1 -ProcessItem $Computer.ToUpper()

            }

            Else {

                Show-ProgressBar -Activity 'Getting BIOS Settings' -TotalItems $TotalItems -Counter $Index -ProcessItem $Computer.ToUpper()

                $Index++

            }

            If (Test-Connection $Computer -Count 1 -Quiet) {

                Try {

                    ForEach ($Setting In $SettingName) {

                        If ($LenovoSettings = Get-WmiObject -Class Lenovo_BiosSetting -NameSpace Root\WMI -ComputerName $Computer | Where-Object {$_.CurrentSetting.Split(',', [StringSplitOptions]::RemoveEmptyEntries) -eq $Setting}) {

                            $Temp = $LenovoSettings.CurrentSetting -split ','

                            Show-Output ($Computer.ToUpper(), $Setting, $Temp[1], 'Ok')

                        }

                        Else {

                            Show-Output ($Computer.ToUpper(), $Setting, '', 'Not Found')

                        }

                    }

                }

                Catch {

                    Show-Output ($Computer.ToUpper(), '', '', $PSItem.Exception.Message)

                }

            }

            Else {

                Show-Output ($Computer.ToUpper(), '', '', 'Unreachable')

            }

        }

    }

    END {}

}


Function Get-LenovoBIOSSettingAvailableValue {

    <#
 
     .SYNOPSIS
     Get all the possible values for the selected BIOS setting
 
     .DESCRIPTION
     Get all the possible values for the selected BIOS setting
 
     .PARAMETER ComputerName
     Name of the host to retrieve the BIOS settings from
 
     .PARAMETER SettingName
     BIOS setting to query
 
     .EXAMPLE
     Get-LenovoBIOSSettingAvailableValue -ComputerName LabPC2064 -SettingName WakeOnLAN
 
     This example will return:
     Disable,ACOnly,ACandBattery,Enable
 
     .NOTES
     The Lenovo BIOS settings are case sensitive
 
     .LINK
     N/A
 
    #>


    Param (

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter computer name'
                   )
        ]

        [String[]]$ComputerName,

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter setting name'
                   )
        ]

        [String[]]$SettingName

    )

    BEGIN {

        $TotalItems = $ComputerName.Count

        If ($TotalItems -eq 0) {

            $TotalItems = 1
            $FromPipeline = $True

        }

        $Index = 1

        Function Show-Output ($Values) {

            $OutputObj = New-Object -TypeName PSObject

            $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Values[0]
            $OutputObj | Add-Member -MemberType NoteProperty -Name SettingName -Value $Values[1]
            $OutputObj | Add-Member -MemberType NoteProperty -Name AvailableValue -Value $Values[2]
            $OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $Values[3]

            Write-Output $OutputObj

        }

    }

    PROCESS {

        ForEach ($Computer In $ComputerName) {

            If ($FromPipeline) {

                Show-ProgressBar -Activity 'Getting BIOS Settings' -TotalItems $TotalItems -Counter 1 -ProcessItem $Computer.ToUpper()

            }

            Else {

                Show-ProgressBar -Activity 'Getting BIOS Settings' -TotalItems $TotalItems -Counter $Index -ProcessItem $Computer.ToUpper()

                $Index++

            }

            If (Test-Connection $Computer -Count 1 -Quiet) {

                Try {

                    ForEach ($Setting In $SettingName) {

                        $LenovoSettings = (Get-WmiObject â€“Class Lenovo_GetBiosSelections â€“NameSpace Root\WMI -ComputerName $Computer).GetBiosSelections($Setting)

                        If ($LenovoSettings.Selections) {

                            Show-Output ($Computer.ToUpper(), $Setting, $LenovoSettings.Selections, 'Ok')

                        }

                        Else {

                            Show-Output ($Computer.ToUpper(), $Setting, '', 'Not Found')

                        }

                    }

                }

                Catch {

                    Show-Output ($Computer.ToUpper(), '', '', $PSItem.Exception.Message)

                }

            }

            Else {

                Show-Output ($Computer.ToUpper(), '', '', 'Unreachable')

            }

        }

    }

    END {}

}


Function Set-LenovoBIOSSetting {

    <#
 
     .SYNOPSIS
     Set the value of a BIOS setting
 
     .DESCRIPTION
     Set the value of a BIOS setting
 
     .PARAMETER ComputerName
     Name of the host to set the BIOS setting
 
     .PARAMETER SettingName
     Name of the BIOS setting to change
 
     .PARAMETER SettingValue
     Value of the setting
 
     .EXAMPLE
     Set-LenovoBIOSSetting -ComputerName LabPC2064 -SettingName WakeOnLAN -SettingValue Disable
 
     .NOTES
     The Lenovo BIOS settings are case sensitive
 
     .LINK
     N/A
 
    #>


    Param (

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter computer name'
                   )
        ]

        [String[]]$ComputerName,

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter setting name'
                   )
        ]

        [String[]]$SettingName,

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter setting value'
                   )
        ]

        [String[]]$SettingValue

    )

    BEGIN {

        $TotalItems = $ComputerName.Count

        If ($TotalItems -eq 0) {

            $TotalItems = 1
            $FromPipeline = $True

        }

        $Index = 1
        $ValueCounter = 0

        Function Show-Output ($Values) {

            $OutputObj = New-Object -TypeName PSObject

            $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Values[0]
            $OutputObj | Add-Member -MemberType NoteProperty -Name SettingName -Value $Values[1]
            $OutputObj | Add-Member -MemberType NoteProperty -Name Value -Value $Values[2]
            $OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $Values[3]

            Write-Output $OutputObj

        }

    }

    PROCESS {

        ForEach ($Computer In $ComputerName) {

            If ($FromPipeline) {

                Show-ProgressBar -Activity 'Modifying BIOS Settings' -TotalItems $TotalItems -Counter 1 -ProcessItem $Computer.ToUpper()

            }

            Else {

                Show-ProgressBar -Activity 'Modifying BIOS Settings' -TotalItems $TotalItems -Counter $Index -ProcessItem $Computer.ToUpper()

                $Index++

            }

            If (Test-Connection $Computer -Count 1 -Quiet) {

                Try {

                    ForEach ($Setting In $SettingName) {

                        $Temp = $SettingName.Trim() + ',' + $SettingValue[$ValueCounter].Trim()
                        $SettingResult = (Get-WmiObject -Class Lenovo_SetBiosSetting â€“NameSpace Root\WMI -ComputerName $Computer).SetBiosSetting($Temp)

                        If ($SettingResult.Return -eq 'Success') {

                            (Get-WmiObject -Class Lenovo_SaveBiosSettings -NameSpace Root\WMI -ComputerName $Computer).SaveBiosSettings() | Out-Null

                            Show-Output ($Computer.ToUpper(), $Setting, $SettingValue[$ValueCounter], 'Modified')

                        }

                        Else {

                            Show-Output ($Computer.ToUpper(), $Setting, '', $SettingResult.Return)

                        }

                        $ValueCounter++

                    }

                }

                Catch {

                    Show-Output ($Computer.ToUpper(), '', '', $PSItem.Exception.Message)

                }

            }

            Else {

                Show-Output ($Computer.ToUpper(), '', '', 'Unreachable')

            }

        }

    }

    END {}

}


Function Set-LenovoBIOSSettingWithAdminPassword {

    <#
 
     .SYNOPSIS
     Set the value of a BIOS setting
 
     .DESCRIPTION
     Set the value of a BIOS setting
 
     .PARAMETER ComputerName
     Name of the host to set the BIOS setting
 
     .PARAMETER SettingName
     Name of the BIOS setting to change
 
     .PARAMETER SettingValue
     Value of the setting
 
     .PARAMETER AdminPassword
     BIOS admin password
 
     .EXAMPLE
     Set-LenovoBIOSSettingWithAdminPassword -ComputerName LabPC2064 -SettingName WakeOnLAN -SettingValue Disable -AdminPassword @dminP@ssw0rd!
 
     .NOTES
     The Lenovo BIOS settings are case sensitive
 
     .LINK
     N/A
 
    #>


    Param (

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter computer name'
                   )
        ]

        [String[]]$ComputerName,

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter setting name'
                   )
        ]

        [String[]]$SettingName,

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter setting value'
                   )
        ]

        [String[]]$SettingValue,

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter admin password'
                   )
        ]

        [String[]]$AdminPassword

    )

    BEGIN {

        $TotalItems = $ComputerName.Count

        If ($TotalItems -eq 0) {

            $TotalItems = 1
            $FromPipeline = $True

         }

         $Index = 1
         $ValueCounter = 0

         Function Show-Output ($Values) {

             $OutputObj = New-Object -TypeName PSObject

             $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Values[0]
             $OutputObj | Add-Member -MemberType NoteProperty -Name SettingName -Value $Values[1]
             $OutputObj | Add-Member -MemberType NoteProperty -Name Value -Value $Values[2]
             $OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $Values[3]

             Write-Output $OutputObj

         }

    }

    PROCESS {

        ForEach ($Computer In $ComputerName) {

            If ($FromPipeline) {

                Show-ProgressBar -Activity 'Modifying BIOS Settings With Admin Password' -TotalItems $TotalItems -Counter 1 -ProcessItem $Computer.ToUpper()

            }

            Else {

                Show-ProgressBar -Activity 'Modifying BIOS Settings With Admin Password' -TotalItems $TotalItems -Counter $Index -ProcessItem $Computer.ToUpper()

                $Index++

            }

            If (Test-Connection $Computer -Count 1 -Quiet) {

                Try {

                    ForEach ($Setting In $SettingName) {

                        $AdminInfo = $AdminPassword[$ValueCounter].Trim() + ',ascii,us'
                        $Temp = $SettingName.Trim() + ',' + $SettingValue[$ValueCounter].Trim() + ',' + $AdminInfo
                        $SettingResult = (Get-WmiObject -Class Lenovo_SetBiosSetting -NameSpace Root\WMI -ComputerName $Computer).SetBiosSetting($Temp)

                        If ($SettingResult.Return -eq 'Success') {

                            (Get-WmiObject -Class Lenovo_SaveBiosSettings -NameSpace Root\WMI -ComputerName $Computer).SaveBiosSettings($AdminInfo) | Out-Null

                            Show-Output ($Computer.ToUpper(), $Setting, $SettingValue[$ValueCounter], 'Modified')

                        }

                        Else {

                            Show-Output ($Computer.ToUpper(), $Setting, '', $SettingResult.Return)

                        }

                        $ValueCounter++

                    }

                }

                Catch {

                    Show-Output ($Computer.ToUpper(), '', '', $PSItem.Exception.Message)

                }

            }

            Else {

                Show-Output ($Computer.ToUpper(), '', '', 'Unreachable')

            }

        }

    }

    END {}

}