Function Set-LenovoBIOSSettings {
[CmdletBinding()]
param(
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=0)]
[string]$ComputerName = (Get-Content env:computername),
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=1)]
$SettingsToBeApplied)
Function Create-LogFile{
[CmdletBinding()]
param([Parameter(Mandatory=$true, ValueFromPipeline=$true,Position=0)]
[string]$LogName,
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=1)]
[string]$LogfileVarName = 'LogFile',
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=2)]
[string]$LogFileScope = 'Global')
$LogFileString = "c:\windows\logs\$($LogName)_$(get-date -UFormat %m-%d-%y).log"
if (Test-Path $LogFileString){Remove-Item -Path $LogFileString -Force}
Set-Variable -Name $LogfileVarName -Value $LogFileString -Scope $LogFileScope -Force}
Function Write-Log {
[CmdletBinding()]
param(
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=0)]
[string]$message,
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=1)]
[string]$LogName = "REPLACE",
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=2)]
[string]$LogfileVarName = 'LogFile',
[Parameter(Mandatory=$false, ValueFromPipeline=$true,Position=3)]
[string]$LogFileScope = 'Global')
$MessageScriptBlock = {
if ($message.Length -eq 0){
Write-Host " "
" "| Out-File -FilePath $LogFile -Force -Append; Return}
if ($message -ne $null) {
$message = "--"+ $message + " - $(Get-Date -Format "hh:mm:ss tt")--"
Write-Host $message
$message | Out-File -FilePath $LogFile -Force -Append}}
if ((Get-Variable $LogfileVarName) -eq $null) {
if ((Get-Command -Name Create-LogFile) -ne $null) {Create-LogFile -LogName $LogName}
else {
Write-Host "There is no log file nor is there a `"Create-LogFile`" Function available"
Write-Host "Creating a Logfile to continue the script: c:\windows\logs\REPLACE.log"
$LogFileString = "c:\windows\logs\REPLACE.log"
if (Test-Path $LogFileString){Remove-Item -Path $LogFileString -Force}
Set-Variable -Name $LogfileVarName -Value $LogFileString -Scope $LogFileScope -Force}}
Invoke-Command -ScriptBlock $MessageScriptBlock}
Create-LogFile -LogName SetLenovoBiosSettings
Write-Log “Updating the Bios Settings”
Write-Log “Start of Script. Date: $(get-date -UFormat %m-%d-%y)”
Write-Log “The original location of this log file is: $LogFile and this file was run on this computer: $ComputerName”
Write-Log “Here is the current running version of PowerShell:”
$PSVersionTable
#$PSVersionTable | Out-File -FilePath $LogFile -Append
if ($PSVersionTable.PSVersion.Major -lt 4) {Write-Log “Warning, this script has only been tested on PowerShell 4.”}
Write-Log
Write-Log
Write-Log “Here is the input parameter: `$SettingsToBeApplied: `”$SettingsToBeApplied`""
if (!(Test-Connection $ComputerName -Quiet)) {Write-Log “The computer $ComputerName is not pingable, make sure that it is on.”;Break}
if ((Get-WmiObject win32_computersystem -ComputerName $ComputerName).Manufacturer -notmatch “LENOVO”) {Write-Log “This computer is not a Lenovo, Breaking now”;Break}
Set-Variable -Name CurrentBIOSSettings -Value (Get-WmiObject lenovo_BIOSsetting -Namespace ‘Root\wmi’-ComputerName $ComputerName) -Scope Global
if ((Get-Variable -Name BIOSSettings) -eq $null) {Set-Variable -Name BIOSSettings -Value (Get-WmiObject lenovo_setBIOSsetting -namespace root\wmi -ComputerName $ComputerName) -Scope Global}
Write-Log “There is a total of $($SettingsToBeApplied.Count) setting(s) to be configured:”
$index = 1
Write-Log
Write-Log
$SetBIOSSettingScriptBlock = {
param([string]$SettingToBeApplied)
#Grabbing the Setting Name from the string which contains both the value and the name to make querying simpler, as we do not know what the value currently is.
$SettingName = $SettingToBeApplied.split(",")[0]
Write-Log
Write-Log
Write-Log
Write-Log
Write-Log "$index. Configuring $SettingName"
Set-Variable -Name index -Value ($index += 1) -Scope 1
$CurrentBIOSSetting = $CurrentBIOSSettings | where {($_.currentsetting).split(",")[0] -eq $SettingName} | Select-Object -Property CurrentSetting
Write-Log "Checking the `$SettingName variable, which is: `"$SettingName`", to make sure that the setting exists in the BIOS."
if ($CurrentBIOSSetting -eq $null) {Write-Log "The BIOS does not contain $SettingName as one of it's configurable BIOS Settings.";Return}
Write-Log "Here is the currently running configuration for this setting:"
$CurrentBIOSSetting | Out-File -FilePath $LogFile -Append -Force
if ($CurrentBIOSSetting.CurrentSetting -ne $SettingToBeApplied) {
Write-Log "Trying to apply the Setting: $SettingToBeApplied now."
$SuccessCode = $BIOSSettings.SetBIOSSetting($SettingToBeApplied).return
if ($SuccessCode -eq "Invalid Parameter") {Write-Log "The setting: `"$SettingToBeApplied`" is not properly configured for this Machine\BIOS version."}
elseif ($SuccessCode -eq "Success") {
Write-Log "Successfully applied the setting, below is the newly configured value for this particluar setting:"
#Grabing the latest instance of the BIOS setting object to log it's new value for confirmation\troubleshooting.
Get-WmiObject lenovo_BIOSsetting -Namespace 'Root\wmi' -ComputerName $ComputerName | where {$($_.CurrentSetting.split(',')[0]) -eq $SettingName} | Select-Object -Property CurrentSetting | Out-File -FilePath $LogFile -Append}}
if ($CurrentBIOSSetting.CurrentSetting -eq $SettingToBeApplied) {
Write-Log "The BIOS is already configured correctly. Below is the current values for both variables:"
Write-Log "`"`$CurrentBIOSSetting.currentSetting`" is:"
Write-Log
$CurrentBIOSSetting.CurrentSetting | Out-File -FilePath $LogFile -Append -Force
Write-Log
Write-Log "`"`$SettingToBeApplied`" is:"
Write-Log
$SettingToBeApplied | Out-File -FilePath $LogFile -Append -Force}
((Get-WmiObject lenovo_savebiossettings -ComputerName $ComputerName -Namespace root\wmi).savebiossettings()).return}
if (($SettingsToBeApplied -isnot [string]) -and ($SettingsToBeApplied -isnot [array])) {$SettingsToBeApplied = $SettingsToBeApplied.tostring()}
if (($SettingsToBeApplied -is [string]) -and ($SettingsToBeApplied -match “,”)) {Invoke-Command -ScriptBlock $SetBIOSSettingScriptBlock -ArgumentList $SettingsToBeApplied}
if ($SettingsToBeApplied -is [array]) {
foreach ($SettingToBeApplied in $SettingsToBeApplied) {
#Below is just some more error checking, making sure the input is correct
if (($SettingToBeApplied -isnot [string]) -or (($SettingToBeApplied -is [string]) -and ($SettingsToBeApplied -notmatch ","))) {
Write-Log "Each object defined in the array as the SettingsToBeApplied paramter must be a string containing at least one comma to differentiate a setting name from it's corresponding value."
Write-Log "The object: $SettingToBeApplied which is found at index#$($SettingsToBeApplied.IndexOf($SettingToBeApplied)) of the `"$SettingsToBeApplied`" fails meet the criteria. "}
#Applying the BIOS Settings below.
elseif (($SettingToBeApplied -is [string]) -and ($SettingToBeApplied -match ",")) {Invoke-Command -ScriptBlock $SetBIOSSettingScriptBlock -ArgumentList $SettingToBeApplied}}}}
$Settings = ‘Primary Boot Sequence,Hard Drive:Network Card:USB Key;[Exclude from boot order:USB Hard Disk:USB CD/DVD:Floppy Drive: USB Floppy:CD/DVD Drive]’
$pcnames = Import-Csv .\pcnames.csv
foreach ($name in $pcnames) {Set-LenovoBIOSSettings -ComputerName $name.name -SettingsToBeApplied $Settings}