nyaaaaaa
This commit is contained in:
parent
661a6b899b
commit
107bbee86a
|
@ -0,0 +1,570 @@
|
||||||
|
<#
|
||||||
|
.DESCRIPTION
|
||||||
|
Install the HP Client Management Script Library PowerShell modules
|
||||||
|
|
||||||
|
.PARAMETER ModulePath
|
||||||
|
Specify the location of the HPCMSL modules source files. This parameter should be specified when the script is running in WinPE or when the system does not have internet access
|
||||||
|
|
||||||
|
.PARAMETER LogFile
|
||||||
|
Specify the name of the log file along with the full path where it will be stored. The file must have a .log extension. During a task sequence the path will always be set to _SMSTSLogPath
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Running in a full Windows OS and installing from the internet
|
||||||
|
Install-HPCMSL.ps1
|
||||||
|
|
||||||
|
Running in WinPE or offline
|
||||||
|
Install-HPCMSL.ps1 -ModulePath HPCMSL
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Created by: Jon Anderson (@ConfigJon)
|
||||||
|
Reference: https://www.configjon.com/installing-the-hp-client-management-script-library\
|
||||||
|
Modified: 2020-09-17
|
||||||
|
|
||||||
|
.CHANGELOG
|
||||||
|
2020-09-14 - Added a LogFile parameter. Changed the default log path in full Windows to $ENV:ProgramData\ConfigJonScripts\HP.
|
||||||
|
Created a new function (Stop-Script) to consolidate some duplicate code and improve error reporting. Made a number of minor formatting and syntax changes
|
||||||
|
2020-09-17 - Improved the log file path configuration
|
||||||
|
#>
|
||||||
|
|
||||||
|
#Parameters ===================================================================================================================
|
||||||
|
|
||||||
|
param(
|
||||||
|
[ValidateScript({
|
||||||
|
if(!($_ | Test-Path))
|
||||||
|
{
|
||||||
|
throw "The ModulePath folder path does not exist"
|
||||||
|
}
|
||||||
|
if(!($_ | Test-Path -PathType Container))
|
||||||
|
{
|
||||||
|
throw "The ModulePath argument must be a folder path"
|
||||||
|
}
|
||||||
|
return $true
|
||||||
|
})]
|
||||||
|
[Parameter(Mandatory=$false)][System.IO.DirectoryInfo]$ModulePath,
|
||||||
|
[Parameter(DontShow)][Switch]$Rerun,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateScript({
|
||||||
|
if($_ -notmatch "(\.log)")
|
||||||
|
{
|
||||||
|
throw "The file specified in the LogFile paramter must be a .log file"
|
||||||
|
}
|
||||||
|
return $true
|
||||||
|
})]
|
||||||
|
[System.IO.FileInfo]$LogFile = "$ENV:ProgramData\ConfigJonScripts\HP\Install-HPCMSL.log"
|
||||||
|
)
|
||||||
|
|
||||||
|
#Functions ====================================================================================================================
|
||||||
|
|
||||||
|
Function Get-TaskSequenceStatus
|
||||||
|
{
|
||||||
|
#Determine if a task sequence is currently running
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment
|
||||||
|
}
|
||||||
|
catch{}
|
||||||
|
if($NULL -eq $TSEnv)
|
||||||
|
{
|
||||||
|
return $False
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$SMSTSType = $TSEnv.Value("_SMSTSType")
|
||||||
|
}
|
||||||
|
catch{}
|
||||||
|
if($NULL -eq $SMSTSType)
|
||||||
|
{
|
||||||
|
return $False
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Stop-Script
|
||||||
|
{
|
||||||
|
#Write an error to the log file and terminate the script
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$ErrorMessage,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$Exception
|
||||||
|
)
|
||||||
|
Write-LogEntry -Value $ErrorMessage -Severity 3
|
||||||
|
if($Exception)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Exception Message: $Exception" -Severity 3
|
||||||
|
}
|
||||||
|
throw $ErrorMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Install-HPCMSLLocal
|
||||||
|
{
|
||||||
|
#Install the HPCMSL from local source files
|
||||||
|
|
||||||
|
param(
|
||||||
|
[parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$InstallPath,
|
||||||
|
[parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$ModulePath,
|
||||||
|
[parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$ModuleName,
|
||||||
|
[parameter(Mandatory = $false)][ValidateNotNullOrEmpty()][String]$Version
|
||||||
|
)
|
||||||
|
Write-LogEntry -Value "Install the $ModuleName module from $ModulePath" -Severity 1
|
||||||
|
$Error.Clear()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Copy-Item $ModulePath -Destination "$InstallPath\WindowsPowerShell\Modules" -Recurse -Force | Out-Null
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failed to copy the $ModuleName module from $ModulePath to $InstallPath\WindowsPowerShell\Modules" -Severity 3
|
||||||
|
}
|
||||||
|
if(!($Error))
|
||||||
|
{
|
||||||
|
if($NULL -ne $Version)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully installed $ModuleName module version $Version" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully installed the $ModuleName module" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Install-HPCMSLRemote
|
||||||
|
{
|
||||||
|
#Install the HPCMSL from the PowerShell Gallery
|
||||||
|
|
||||||
|
param(
|
||||||
|
[parameter(Mandatory = $false)][ValidateNotNullOrEmpty()][String]$Version
|
||||||
|
)
|
||||||
|
Write-LogEntry -Value "Install the HPCMSL module from the PowerShell Gallery" -Severity 1
|
||||||
|
$Error.Clear()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Install-Module -Name HPCMSL -Force -AcceptLicense
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Unable to install the HPCMSL module from the PowerShell Gallery"
|
||||||
|
}
|
||||||
|
if(!($Error))
|
||||||
|
{
|
||||||
|
if($NULL -ne $Version)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully installed HPCMSL module version $Version" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully installed the HPCMSL module" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Update-NuGet
|
||||||
|
{
|
||||||
|
#Update the NuGet package provider
|
||||||
|
|
||||||
|
#Check if the NuGet package provider is installed
|
||||||
|
$Nuget = Get-PackageProvider | Where-Object Name -eq "NuGet"
|
||||||
|
#If NuGet is installed, ensure it is the current version
|
||||||
|
if($Nuget)
|
||||||
|
{
|
||||||
|
$Major = $Nuget.Version | Select-Object -ExpandProperty Major
|
||||||
|
$Minor = $Nuget.Version | Select-Object -ExpandProperty Minor
|
||||||
|
$Build = $Nuget.Version | Select-Object -ExpandProperty Build
|
||||||
|
$Revision = $Nuget.Version | Select-Object -ExpandProperty Revision
|
||||||
|
$NugetLocalVersion = "$($Major)." + "$($Minor)." + "$($Build)." + "$($Revision)"
|
||||||
|
$NugetWebVersion = Find-PackageProvider NuGet | Select-Object -ExpandProperty Version
|
||||||
|
if($NugetLocalVersion -ge $NugetWebVersion)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The latest version of the NuGet package provider ($NugetLocalVersion) is already installed" -Severity 1
|
||||||
|
}
|
||||||
|
#If the currently installed version of NuGet is outdated, update it from the internet
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Updating the NuGet package provider" -Severity 1
|
||||||
|
$Error.Clear()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Install-PackageProvider -Name "NuGet" -Force -Confirm:$False | Out-Null
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Unable to update the NuGet package provider" -Severity 3
|
||||||
|
}
|
||||||
|
if(!($Error))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully updated the NuGet package provider to version $NugetWebVersion" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#If NuGet is not installed, install it from the internet
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Update the NuGet package provider" -Severity 1
|
||||||
|
$Error.Clear()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Install-PackageProvider -Name "NuGet" -Force -Confirm:$False | Out-Null
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Unable to update the NuGet package provider" -Severity 3
|
||||||
|
}
|
||||||
|
if(!($Error))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully updated the NuGet package provider" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Update-PowerShellGet
|
||||||
|
{
|
||||||
|
#Update the PowerShellGet module
|
||||||
|
|
||||||
|
Import-Module -Name PowerShellGet -Force
|
||||||
|
$PsGetVersion = Get-Module PowerShellGet | Select-Object -ExpandProperty Version
|
||||||
|
$PsGetVersionFull = "$($PsGetVersion.Major)." + "$($PsGetVersion.Minor)." + "$($PsGetVersion.Build)"
|
||||||
|
$PsGetVersionWeb = Find-Package -Name PowerShellGet | Select-Object -ExpandProperty Version
|
||||||
|
if($PsGetVersionFull -ge $PsGetVersionWeb)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The latest version of the PowerShellGet module ($PsGetVersionFull) is already installed" -Severity 1
|
||||||
|
}
|
||||||
|
#If the currently installed version of the PowerShellGet module is outdated, update it from the internet
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Updating the PowerShellGet module" -Severity 1
|
||||||
|
$Error.Clear()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Remove-Module -Name PowerShellGet -Force #Unload the current version of the PowerShellGet module
|
||||||
|
Install-Module -Name PowerShellGet -Force #Install the latest version of the PowerShellGet module
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Unable to update the PowerShellGet module" -Severity 3
|
||||||
|
}
|
||||||
|
if(!($Error))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully updated the PowerShellGet module to version $PsGetVersionWeb" -Severity 1
|
||||||
|
#Re-launch the script in a new session to detect the new PowerShellGet module version
|
||||||
|
Start-Process -FilePath "$Env:WinDir\system32\WindowsPowerShell\v1.0\powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File $ScriptPath -Rerun" -Wait -PassThru
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Write-LogEntry
|
||||||
|
{
|
||||||
|
#Write data to a CMTrace compatible log file. (Credit to SCConfigMgr - https://www.scconfigmgr.com/)
|
||||||
|
|
||||||
|
param(
|
||||||
|
[parameter(Mandatory = $true, HelpMessage = "Value added to the log file.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$Value,
|
||||||
|
[parameter(Mandatory = $true, HelpMessage = "Severity for the log entry. 1 for Informational, 2 for Warning and 3 for Error.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[ValidateSet("1", "2", "3")]
|
||||||
|
[string]$Severity,
|
||||||
|
[parameter(Mandatory = $false, HelpMessage = "Name of the log file that the entry will written to.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$FileName = ($script:LogFile | Split-Path -Leaf)
|
||||||
|
)
|
||||||
|
#Determine log file location
|
||||||
|
$LogFilePath = Join-Path -Path $LogsDirectory -ChildPath $FileName
|
||||||
|
#Construct time stamp for log entry
|
||||||
|
if(-not(Test-Path -Path 'variable:global:TimezoneBias'))
|
||||||
|
{
|
||||||
|
[string]$global:TimezoneBias = [System.TimeZoneInfo]::Local.GetUtcOffset((Get-Date)).TotalMinutes
|
||||||
|
if($TimezoneBias -match "^-")
|
||||||
|
{
|
||||||
|
$TimezoneBias = $TimezoneBias.Replace('-', '+')
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$TimezoneBias = '-' + $TimezoneBias
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$Time = -join @((Get-Date -Format "HH:mm:ss.fff"), $TimezoneBias)
|
||||||
|
#Construct date for log entry
|
||||||
|
$Date = (Get-Date -Format "MM-dd-yyyy")
|
||||||
|
#Construct context for log entry
|
||||||
|
$Context = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
|
||||||
|
#Construct final log entry
|
||||||
|
$LogText = "<![LOG[$($Value)]LOG]!><time=""$($Time)"" date=""$($Date)"" component=""Install-HPCMSL"" context=""$($Context)"" type=""$($Severity)"" thread=""$($PID)"" file="""">"
|
||||||
|
#Add value to log file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Out-File -InputObject $LogText -Append -NoClobber -Encoding Default -FilePath $LogFilePath -ErrorAction Stop
|
||||||
|
}
|
||||||
|
catch [System.Exception]
|
||||||
|
{
|
||||||
|
Write-Warning -Message "Unable to append log entry to $FileName file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Main program =================================================================================================================
|
||||||
|
|
||||||
|
#Set the names of the HPCMSL modules
|
||||||
|
$HPModules = ("HP.ClientManagement","HP.Firmware","HP.Private","HP.Repo","HP.Sinks","HP.Softpaq","HP.Utility","HPCMSL")
|
||||||
|
|
||||||
|
#Get the path to the script (Used if the script needs to be re-launched)
|
||||||
|
$ScriptPath = $MyInvocation.MyCommand
|
||||||
|
|
||||||
|
#Configure Logging and task sequence variables
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
|
||||||
|
$LogsDirectory = $TSEnv.Value("_SMSTSLogPath")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$LogsDirectory = ($LogFile | Split-Path)
|
||||||
|
if([string]::IsNullOrEmpty($LogsDirectory))
|
||||||
|
{
|
||||||
|
$LogsDirectory = $PSScriptRoot
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(Test-Path -PathType Container $LogsDirectory))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
New-Item -Path $LogsDirectory -ItemType "Directory" -Force -ErrorAction Stop | Out-Null
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw "Failed to create the log file directory: $LogsDirectory. Exception Message: $($PSItem.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!($Rerun)){
|
||||||
|
Write-Output "Log path set to $LogFile"
|
||||||
|
Write-LogEntry -Value "START - HP Client Management Script Library installation script" -Severity 1
|
||||||
|
|
||||||
|
#Make sure the folder names in the ModulePath match the HPCMSL folder names
|
||||||
|
if($ModulePath)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Validate the folder names in $ModulePath" -Severity 1
|
||||||
|
#Validate the top level folders
|
||||||
|
$ModulePathFolders = Get-ChildItem $ModulePath -Directory | Select-Object -ExpandProperty Name
|
||||||
|
ForEach($Folder in $ModulePathFolders){
|
||||||
|
if($HPModules -notcontains $Folder)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "$Folder is not a valid HPCMSL module folder name" -Severity 3
|
||||||
|
$InvalidFolder = $True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($InvalidFolder)
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Invalid folder names found in $ModulePath. Valid folder names are: ""HP.ClientManagement"" ""HP.Firmware"" ""HP.Private"" ""HP.Repo"" ""HP.Sinks"" ""HP.Softpaq"" ""HP.Utility"" ""HPCMSL"""
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#Validate the subfolders
|
||||||
|
ForEach($Folder in $ModulePathFolders){
|
||||||
|
$Subfolder = Get-ChildItem "$ModulePath\$Folder" -Directory | Select-Object -ExpandProperty Name
|
||||||
|
if($NULL -eq $Subfolder)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "No subfolders detected under $Folder. There should be 1 first-level subfolder." -Severity 3
|
||||||
|
$InvalidSubfolder = $True
|
||||||
|
}
|
||||||
|
elseif($Subfolder.Count -gt 1)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Multiple first-level subfolders detected under $Folder. There should only be 1 first-level subfolder." -Severity 3
|
||||||
|
$InvalidSubfolder = $True
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$PatternCheck = (([regex]"^(\*|\d+(\.\d+){1,3}(\.\*)?)$").Matches($Subfolder)).Success
|
||||||
|
if($PatternCheck -ne "True")
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "$Folder\$Subfolder is not a valid subfolder" -Severity 3
|
||||||
|
$InvalidSubfolder = $True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($InvalidSubfolder)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Each module folder should contain a single first-level subfolder. The folder should be named the version of the module." -Severity 2
|
||||||
|
Write-LogEntry -Value 'Valid first-level subfolder names should be in the format of "1.2" or "1.2.3" or "1.2.3.4"' -Severity 2
|
||||||
|
throw "Invalid subfolder structure found in $ModulePath. See the log file for more details"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully validated the folder names" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Check the PowerShell version
|
||||||
|
Write-LogEntry -Value "Checking the installed PowerShell version" -Severity 1
|
||||||
|
$PsVerMajor = $PSVersionTable.PSVersion | Select-Object -ExpandProperty Major
|
||||||
|
$PsVerMinor = $PSVersionTable.PSVersion | Select-Object -ExpandProperty Minor
|
||||||
|
$PsVerFull = "$($PsVerMajor)." + "$($PsVerMinor)."
|
||||||
|
if($PsVerFull -ge 5.1)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The current PowerShell version is $PsVerFull" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "The current PowerShell version is $PsVerFull. The mininum supported PowerShell version is 5.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
#Set the PowerShell Module insatll path
|
||||||
|
$ModuleInstallPath = $env:ProgramFiles
|
||||||
|
|
||||||
|
#Get the versions of the currently installed HPCMSL modules
|
||||||
|
Write-LogEntry -Value "Checking the versions of the currently installed HPCMSL modules" -Severity 1
|
||||||
|
$LocalModuleVersions = [PSCustomObject]@{}
|
||||||
|
ForEach($HPModule in $HPModules){
|
||||||
|
if(Test-Path "$ModuleInstallPath\WindowsPowerShell\Modules\$HPModule")
|
||||||
|
{
|
||||||
|
$LocalVersionList = Get-ChildItem "$ModuleInstallPath\WindowsPowerShell\Modules\$HPModule" -Directory | Select-Object -ExpandProperty Name
|
||||||
|
if($LocalVersionList.Count -gt 1)
|
||||||
|
{
|
||||||
|
$LocalVersion = "0.0"
|
||||||
|
ForEach($Version in $LocalVersionList){
|
||||||
|
if(([Version]$Version).CompareTo([Version]$LocalVersion) -eq 1)
|
||||||
|
{
|
||||||
|
$LocalVersion = $Version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$LocalVersion = $LocalVersionList
|
||||||
|
}
|
||||||
|
|
||||||
|
if($NULL -ne $LocalVersion)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The version of the currently installed $HPModule module is $LocalVersion" -Severity 1
|
||||||
|
$LocalModuleVersions | Add-Member -NotePropertyName $HPModule -NotePropertyValue $LocalVersion
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "$HPModule module not found on the local machine" -Severity 2
|
||||||
|
$LocalModuleVersions | Add-Member -NotePropertyName $HPModule -NotePropertyValue '0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "$HPModule module not found on the local machine" -Severity 2
|
||||||
|
$LocalModuleVersions | Add-Member -NotePropertyName $HPModule -NotePropertyValue '0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Attempt to install the HPCMSL from local source files
|
||||||
|
if($ModulePath)
|
||||||
|
{
|
||||||
|
ForEach($HPModule in $HPModules){
|
||||||
|
#Get the version of the module
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$SourceVersion = Get-ChildItem "$ModulePath\$HPModule" -Directory | Select-Object -ExpandProperty Name
|
||||||
|
if($NULL -ne $SourceVersion)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The version of the $HPModule module in $ModulePath is $SourceVersion" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failed to check the version of the $HPModule module in $ModulePath" -Severity 3
|
||||||
|
}
|
||||||
|
if($NULL -ne $SourceVersion)
|
||||||
|
{
|
||||||
|
$LocalVersionCompare = ([Version]$SourceVersion).CompareTo([Version]$LocalModuleVersions.$HPModule)
|
||||||
|
if($LocalVersionCompare -eq 0)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The latest version of the $HPModule module is already installed" -Severity 1
|
||||||
|
}
|
||||||
|
elseif($LocalVersionCompare -eq -1)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "A newer version of $HPModule is already installed" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Install-HPCMSLLocal -InstallPath $ModuleInstallPath -ModuleName $HPModule -ModulePath "$ModulePath\$HPModule" -Version $SourceVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Install-HPCMSLLocal -InstallPath $ModuleInstallPath -ModuleName $HPModule -ModulePath "$ModulePath\$HPModule"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Attempt to install the HPCMSL module from the PowerShell Gallery
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!($Rerun)){
|
||||||
|
#Ensure the NuGet package provider is installed and updated
|
||||||
|
Write-LogEntry -Value "Checking the version of the NuGet package provider" -Severity 1
|
||||||
|
Update-NuGet
|
||||||
|
|
||||||
|
#Ensure the PowerShellGet module is updated
|
||||||
|
Write-LogEntry -Value "Checking the version of the PowerShellGet module" -Severity 1
|
||||||
|
Update-PowerShellGet
|
||||||
|
}
|
||||||
|
#Get the version of the HPCMSL module in the PowerShell Gallery
|
||||||
|
Write-LogEntry -Value "Checking the version of the HPCMSL module in the PowerShell Gallery" -Severity 1
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$WebVersion = Find-Package HPCMSL | Select-Object -ExpandProperty Version
|
||||||
|
if($NULL -ne $WebVersion)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The version of the HPCMSL module in the PowerShell Gallery is $WebVersion" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failed to check the version of the HPCMSL module in the PowerShell Gallery" -Severity 3
|
||||||
|
}
|
||||||
|
if($NULL -ne $WebVersion)
|
||||||
|
{
|
||||||
|
$WebVersionCompare = ([Version]$WebVersion).CompareTo([Version]$LocalModuleVersions.HPCMSL)
|
||||||
|
if($WebVersionCompare -eq 0)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The latest version of the HPCMSL module is already installed" -Severity 1
|
||||||
|
}
|
||||||
|
elseif($WebVersionCompare -eq -1)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "A newer version of the HPCMSL module is already installed" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Install-HPCMSLRemote -Version $WebVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif(($NULL -ne $WebVersion) -and ($NULL -eq $LocalVersion))
|
||||||
|
{
|
||||||
|
Install-HPCMSLRemote -Version $WebVersion
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Install-HPCMSLRemote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Import the HPCMSL module
|
||||||
|
Write-LogEntry -Value "Import the HPCMSL module" -Severity 1
|
||||||
|
$Error.Clear()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Import-Module HPCMSL -Force -ErrorAction Stop
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Failed to import the HPCMSL module" -Exception $PSItem.Exception.Message
|
||||||
|
}
|
||||||
|
if(!($Error))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully imported the HPCMSL module" -Severity 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-LogEntry -Value "END - HP Client Management Script Library installation script" -Severity 1
|
|
@ -0,0 +1,710 @@
|
||||||
|
<#
|
||||||
|
.DESCRIPTION
|
||||||
|
Automatically configure HP BIOS passwords and prompt the user if manual intervention is required.
|
||||||
|
|
||||||
|
.PARAMETER SetupSet
|
||||||
|
Specify this switch to set a new setup password or change an existing setup password.
|
||||||
|
|
||||||
|
.PARAMETER SetupClear
|
||||||
|
Specify this swtich to clear an existing setup password. Must also specify the OldSetupPassword parameter.
|
||||||
|
|
||||||
|
.PARAMETER PowerOnSet
|
||||||
|
Specify this switch to set a new power on password or change an existing power on password.
|
||||||
|
|
||||||
|
.PARAMETER PowerOnClear
|
||||||
|
Specify this switch to clear an existing power on password. Must also specify the OldPowerOnPassword parameter.
|
||||||
|
|
||||||
|
.PARAMETER SetupPassword
|
||||||
|
Specify the new setup password to set.
|
||||||
|
|
||||||
|
.PARAMETER OldSetupPassword
|
||||||
|
Specify the old setup password(s) to be changed. Multiple passwords can be specified as a comma seperated list.
|
||||||
|
|
||||||
|
.PARAMETER PowerOnPassword
|
||||||
|
Specify the new power on password to set.
|
||||||
|
|
||||||
|
.PARAMETER OldPowerOnPassword
|
||||||
|
Specify the old power on password(s) to be changed. Multiple passwords can be specified as a comma seperated list.
|
||||||
|
|
||||||
|
.PARAMETER NoUserPrompt
|
||||||
|
The script will run silently and will not prompt the user with a message box.
|
||||||
|
|
||||||
|
.PARAMETER ContinueOnError
|
||||||
|
The script will ignore any errors caused by changing or clearing the passwords. This will not suppress errors caused by parameter validation.
|
||||||
|
|
||||||
|
.PARAMETER SMSTSPasswordRetry
|
||||||
|
For use in a task sequence. If specified, the script will assume the script needs to run at least one more time. This will ignore password errors and suppress user prompts.
|
||||||
|
|
||||||
|
.PARAMETER LogFile
|
||||||
|
Specify the name of the log file along with the full path where it will be stored. The file must have a .log extension. During a task sequence the path will always be set to _SMSTSLogPath
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Set a new setup password when no old passwords exist
|
||||||
|
Manage-HPBiosPasswords.ps1 -SetupSet -SetupPassword <String>
|
||||||
|
|
||||||
|
Set or change a setup password
|
||||||
|
Manage-HPBiosPasswords.ps1 -SetupSet -SetupPassword <String> -OldSetupPassword <String1>,<String2>
|
||||||
|
|
||||||
|
Clear existing setup password(s)
|
||||||
|
Manage-HPBiosPasswords.ps1 -SetupClear -OldSetupPassword <String1>,<String2>
|
||||||
|
|
||||||
|
Set a new setup password and set a new power on password when no old passwords exist
|
||||||
|
Manage-HPBiosPasswords.ps1 -SetupSet -PowerOnSet -SetupPassword <String1> -PowerOnPassword <String1>
|
||||||
|
|
||||||
|
Set or change an existing setup password and clear a power on password
|
||||||
|
Manage-HPBiosPasswords.ps1 -SetupSet -SetupPassword <String> -OldSetupPassword <String1>,<String2> -PowerOnClear -OldPowerOnPassword <String1>,<String2>
|
||||||
|
|
||||||
|
Clear existing Setup and power on passwords
|
||||||
|
Manage-HPBiosPasswords.ps1 -SetupClear -OldSetupPassword <String1>,<String2> -PowerOnClear -OldPowerOnPassword <String1>,<String2>
|
||||||
|
|
||||||
|
Set a new power on password when the setup password is already set
|
||||||
|
Manage-HPBiosPasswords.ps1 -PowerOnSet -PowerOnPassword <String> -SetupPassword <String>
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Created by: Jon Anderson (@ConfigJon)
|
||||||
|
Reference: https://www.configjon.com/lenovo-bios-password-management/
|
||||||
|
Modifed: 2020-09-17
|
||||||
|
|
||||||
|
.CHANGELOG
|
||||||
|
2019-07-27 - Formatting changes. Changed the SMSTSPasswordRetry parameter to be a switch instead of an integer value. Changed the SMSTSChangeSetup TS variable to HPChangeSetup.
|
||||||
|
Changed the SMSTSClearSetup TS variable to HPClearSetup. Changed the SMSTSChangePowerOn TS variable to HPChangePowerOn. Changed the SMSTSClearPowerOn TS variable to HPClearPowerOn.
|
||||||
|
2019-11-04 - Added additional logging. Changed the default log path to $ENV:ProgramData\BiosScripts\HP. Modifed the parameter validation logic.
|
||||||
|
2020-01-30 - Removed the SetupChange and PowerOnChange parameters. SetupSet and PowerOnSet now work to set or change a password. Changed the HPChangeSetup task sequence variable to HPSetSetup.
|
||||||
|
Changed the HPChangePowerOn task sequence variable to HPSetPowerOn. Updated the parameter validation checks.
|
||||||
|
2020-09-14 - Added a LogFile parameter. Changed the default log path in full Windows to $ENV:ProgramData\ConfigJonScripts\HP.
|
||||||
|
Consolidated duplicate code into new functions (Stop-Script, Get-WmiData, New-HPBiosPassword, Set-HPBiosPassword, Clear-HPBiosPassword). Made a number of minor formatting and syntax changes
|
||||||
|
When using the SetupSet and PowerOnSet parameters, the OldPassword parameters are no longer required. There is now logic to handle and report this type of failure.
|
||||||
|
2020-09-17 - Improved the log file path configuration
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
#Parameters ===================================================================================================================
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$SetupSet,
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$SetupClear,
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$PowerOnSet,
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$PowerOnClear,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$SetupPassword,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String[]]$OldSetupPassword,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$PowerOnPassword,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String[]]$OldPowerOnPassword,
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$NoUserPrompt,
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$ContinueOnError,
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$SMSTSPasswordRetry,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateScript({
|
||||||
|
if($_ -notmatch "(\.log)")
|
||||||
|
{
|
||||||
|
throw "The file specified in the LogFile paramter must be a .log file"
|
||||||
|
}
|
||||||
|
return $true
|
||||||
|
})]
|
||||||
|
[System.IO.FileInfo]$LogFile = "$ENV:ProgramData\ConfigJonScripts\HP\Manage-HPBiosPasswords.log"
|
||||||
|
)
|
||||||
|
|
||||||
|
#Functions ====================================================================================================================
|
||||||
|
|
||||||
|
Function Get-TaskSequenceStatus
|
||||||
|
{
|
||||||
|
#Determine if a task sequence is currently running
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment
|
||||||
|
}
|
||||||
|
catch{}
|
||||||
|
if($NULL -eq $TSEnv)
|
||||||
|
{
|
||||||
|
return $False
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$SMSTSType = $TSEnv.Value("_SMSTSType")
|
||||||
|
}
|
||||||
|
catch{}
|
||||||
|
if($NULL -eq $SMSTSType)
|
||||||
|
{
|
||||||
|
return $False
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Stop-Script
|
||||||
|
{
|
||||||
|
#Write an error to the log file and terminate the script
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$ErrorMessage,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$Exception
|
||||||
|
)
|
||||||
|
Write-LogEntry -Value $ErrorMessage -Severity 3
|
||||||
|
if($Exception)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Exception Message: $Exception" -Severity 3
|
||||||
|
}
|
||||||
|
throw $ErrorMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-WmiData
|
||||||
|
{
|
||||||
|
#Gets WMI data using either the WMI or CIM cmdlets and stores the data in a variable
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$Namespace,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$ClassName,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateSet('CIM','WMI')]$CmdletType,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String[]]$Select
|
||||||
|
)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if($CmdletType -eq "CIM")
|
||||||
|
{
|
||||||
|
if($Select)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $Classname WMI class from the $Namespace namespace and select properties: $Select" -Severity 1
|
||||||
|
$Query = Get-CimInstance -Namespace $Namespace -ClassName $ClassName -ErrorAction Stop | Select-Object $Select -ErrorAction Stop
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $ClassName WMI class from the $Namespace namespace" -Severity 1
|
||||||
|
$Query = Get-CimInstance -Namespace $Namespace -ClassName $ClassName -ErrorAction Stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif($CmdletType -eq "WMI")
|
||||||
|
{
|
||||||
|
if($Select)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $Classname WMI class from the $Namespace namespace and select properties: $Select" -Severity 1
|
||||||
|
$Query = Get-WmiObject -Namespace $Namespace -Class $ClassName -ErrorAction Stop | Select-Object $Select -ErrorAction Stop
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $ClassName WMI class from the $Namespace namespace" -Severity 1
|
||||||
|
$Query = Get-WmiObject -Namespace $Namespace -Class $ClassName -ErrorAction Stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if($Select)
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "An error occurred while attempting to get the $Select properties from the $Classname WMI class in the $Namespace namespace" -Exception $PSItem.Exception.Message
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "An error occurred while connecting to the $Classname WMI class in the $Namespace namespace" -Exception $PSItem.Exception.Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "Successfully connected to the $ClassName WMI class" -Severity 1
|
||||||
|
return $Query
|
||||||
|
}
|
||||||
|
|
||||||
|
Function New-HPBiosPassword
|
||||||
|
{
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateSet('Setup','PowerOn')]$PasswordType,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$Password,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$SetupPW
|
||||||
|
)
|
||||||
|
if($PasswordType -eq "Setup")
|
||||||
|
{
|
||||||
|
$PasswordName = "Setup Password"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$PasswordName = "Power-On Password"
|
||||||
|
}
|
||||||
|
#Attempt to set the power on password when the setup password is already set
|
||||||
|
if($SetupPW)
|
||||||
|
{
|
||||||
|
if(($Interface.SetBIOSSetting($PasswordName,"<utf-16/>" + $Password,"<utf-16/>" + $SetupPW)).Return -eq 0)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The $PasswordType password has been successfully set" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Set-Variable -Name "$($PasswordType)PWExists" -Value "Failed" -Scope Script
|
||||||
|
Write-LogEntry -Value "Failed to set the $PasswordType password" -Severity 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Attempt to set the setup or power on password
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(($Interface.SetBIOSSetting($PasswordName,"<utf-16/>" + $Password,"<utf-16/>")).Return -eq 0)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The $PasswordType password has been successfully set" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Set-Variable -Name "$($PasswordType)PWExists" -Value "Failed" -Scope Script
|
||||||
|
Write-LogEntry -Value "Failed to set the $PasswordType password" -Severity 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Set-HPBiosPassword
|
||||||
|
{
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateSet('Setup','PowerOn')]$PasswordType,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$Password,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String[]]$OldPassword
|
||||||
|
)
|
||||||
|
if($PasswordType -eq "Setup")
|
||||||
|
{
|
||||||
|
$PasswordName = "Setup Password"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$PasswordName = "Power-On Password"
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "Attempt to change the existing $PasswordType password" -Severity 1
|
||||||
|
Set-Variable -Name "$($PasswordType)PWSet" -Value "Failed" -Scope Script
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv.Value("HPSet$($PasswordType)") = "Failed"
|
||||||
|
}
|
||||||
|
#Check if the password is already set to the correct value
|
||||||
|
if(($Interface.SetBIOSSetting($PasswordName,"<utf-16/>" + $Password,"<utf-16/>" + $Password)).Return -eq 0)
|
||||||
|
{
|
||||||
|
#Password is set to correct value
|
||||||
|
Set-Variable -Name "$($PasswordType)PWSet" -Value "Success" -Scope Script
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv.Value("HPSet$($PasswordType)") = "Success"
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "The $PasswordType password is already set correctly" -Severity 1
|
||||||
|
}
|
||||||
|
#Password is not set to correct value
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if($OldPassword)
|
||||||
|
{
|
||||||
|
$Counter = 0
|
||||||
|
While($Counter -lt $OldPassword.Count)
|
||||||
|
{
|
||||||
|
if(($Interface.SetBIOSSetting($PasswordName,"<utf-16/>" + $Password,"<utf-16/>" + $OldPassword[$Counter])).Return -eq 0)
|
||||||
|
{
|
||||||
|
#Successfully changed the password
|
||||||
|
Set-Variable -Name "$($PasswordType)PWSet" -Value "Success" -Scope Script
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv.Value("HPSet$($PasswordType)") = "Success"
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "The $PasswordType password has been successfully changed" -Severity 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#Failed to change the password
|
||||||
|
$Counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((Get-Variable -Name "$($PasswordType)PWSet" -ValueOnly -Scope Script) -eq "Failed")
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failed to change the $PasswordType password" -Severity 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The $PasswordType password is currently set to something other than then supplied value, but no old passwords were supplied. Try supplying additional values using the Old$($PasswordType)Password parameter" -Severity 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Clear-HPBiosPassword
|
||||||
|
{
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateSet('Setup','PowerOn')]$PasswordType,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String[]]$OldPassword
|
||||||
|
)
|
||||||
|
if($PasswordType -eq "Setup")
|
||||||
|
{
|
||||||
|
$PasswordName = "Setup Password"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$PasswordName = "Power-On Password"
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "Attempt to clear the existing $PasswordType password" -Severity 1
|
||||||
|
Set-Variable -Name "$($PasswordType)PWClear" -Value "Failed" -Scope Script
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv.Value("HPClear$($PasswordType)") = "Failed"
|
||||||
|
}
|
||||||
|
$Counter = 0
|
||||||
|
While($Counter -lt $OldPassword.Count)
|
||||||
|
{
|
||||||
|
if(($Interface.SetBIOSSetting($PasswordName,"<utf-16/>","<utf-16/>" + $OldPassword[$Counter])).Return -eq 0)
|
||||||
|
{
|
||||||
|
#Successfully cleared the password
|
||||||
|
Set-Variable -Name "$($PasswordType)PWClear" -Value "Success" -Scope Script
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv.Value("HPClear$($PasswordType)") = "Success"
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "The $PasswordType password has been successfully cleared" -Severity 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#Failed to clear the password
|
||||||
|
$Counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((Get-Variable -Name "$($PasswordType)PWClear" -ValueOnly -Scope Script) -eq "Failed")
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failed to clear the $PasswordType password" -Severity 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Start-UserPrompt
|
||||||
|
{
|
||||||
|
#Create a user prompt with custom body and title text if the NoUserPrompt variable is not set
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][String[]]$BodyText,
|
||||||
|
[Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][String[]]$TitleText
|
||||||
|
)
|
||||||
|
if(!($NoUserPrompt))
|
||||||
|
{
|
||||||
|
(New-Object -ComObject Wscript.Shell).Popup("$BodyText",0,"$TitleText",0x0 + 0x30) | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Write-LogEntry
|
||||||
|
{
|
||||||
|
#Write data to a CMTrace compatible log file. (Credit to SCConfigMgr - https://www.scconfigmgr.com/)
|
||||||
|
|
||||||
|
param(
|
||||||
|
[parameter(Mandatory = $true, HelpMessage = "Value added to the log file.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$Value,
|
||||||
|
[parameter(Mandatory = $true, HelpMessage = "Severity for the log entry. 1 for Informational, 2 for Warning and 3 for Error.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[ValidateSet("1", "2", "3")]
|
||||||
|
[string]$Severity,
|
||||||
|
[parameter(Mandatory = $false, HelpMessage = "Name of the log file that the entry will written to.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$FileName = ($script:LogFile | Split-Path -Leaf)
|
||||||
|
)
|
||||||
|
#Determine log file location
|
||||||
|
$LogFilePath = Join-Path -Path $LogsDirectory -ChildPath $FileName
|
||||||
|
#Construct time stamp for log entry
|
||||||
|
if(-not(Test-Path -Path 'variable:global:TimezoneBias'))
|
||||||
|
{
|
||||||
|
[string]$global:TimezoneBias = [System.TimeZoneInfo]::Local.GetUtcOffset((Get-Date)).TotalMinutes
|
||||||
|
if($TimezoneBias -match "^-")
|
||||||
|
{
|
||||||
|
$TimezoneBias = $TimezoneBias.Replace('-', '+')
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$TimezoneBias = '-' + $TimezoneBias
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$Time = -join @((Get-Date -Format "HH:mm:ss.fff"), $TimezoneBias)
|
||||||
|
#Construct date for log entry
|
||||||
|
$Date = (Get-Date -Format "MM-dd-yyyy")
|
||||||
|
#Construct context for log entry
|
||||||
|
$Context = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
|
||||||
|
#Construct final log entry
|
||||||
|
$LogText = "<![LOG[$($Value)]LOG]!><time=""$($Time)"" date=""$($Date)"" component=""Manage-HPBiosPasswords"" context=""$($Context)"" type=""$($Severity)"" thread=""$($PID)"" file="""">"
|
||||||
|
#Add value to log file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Out-File -InputObject $LogText -Append -NoClobber -Encoding Default -FilePath $LogFilePath -ErrorAction Stop
|
||||||
|
}
|
||||||
|
catch [System.Exception]
|
||||||
|
{
|
||||||
|
Write-Warning -Message "Unable to append log entry to $FileName file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Main program =================================================================================================================
|
||||||
|
|
||||||
|
#Configure Logging and task sequence variables
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
|
||||||
|
$TSProgress = New-Object -ComObject Microsoft.SMS.TsProgressUI
|
||||||
|
$LogsDirectory = $TSEnv.Value("_SMSTSLogPath")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$LogsDirectory = ($LogFile | Split-Path)
|
||||||
|
if([string]::IsNullOrEmpty($LogsDirectory))
|
||||||
|
{
|
||||||
|
$LogsDirectory = $PSScriptRoot
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(Test-Path -PathType Container $LogsDirectory))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
New-Item -Path $LogsDirectory -ItemType "Directory" -Force -ErrorAction Stop | Out-Null
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw "Failed to create the log file directory: $LogsDirectory. Exception Message: $($PSItem.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Output "Log path set to $LogFile"
|
||||||
|
Write-LogEntry -Value "START - HP BIOS password management script" -Severity 1
|
||||||
|
|
||||||
|
#Connect to the HP_BIOSSettingInterface WMI class
|
||||||
|
$Interface = Get-WmiData -Namespace root\hp\InstrumentedBIOS -ClassName HP_BIOSSettingInterface -CmdletType WMI
|
||||||
|
|
||||||
|
#Connect to the HP_BIOSSetting WMI class
|
||||||
|
$HPBiosSetting = Get-WmiData -Namespace root\hp\InstrumentedBIOS -ClassName HP_BIOSSetting -CmdletType WMI
|
||||||
|
|
||||||
|
#Get the current password status
|
||||||
|
Write-LogEntry -Value "Get the current password state" -Severity 1
|
||||||
|
|
||||||
|
$SetupPasswordCheck = ($HPBiosSetting | Where-Object Name -eq "Setup Password").IsSet
|
||||||
|
if($SetupPasswordCheck -eq 1)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The setup password is currently set" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The setup password is not currently set" -Severity 1
|
||||||
|
}
|
||||||
|
$PowerOnPasswordCheck = ($HPBiosSetting | Where-Object Name -eq "Power-On Password").IsSet
|
||||||
|
if($PowerOnPasswordCheck -eq 1)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The power on password is currently set" -Severity 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The power on password is not currently set" -Severity 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#Parameter validation
|
||||||
|
Write-LogEntry -Value "Begin parameter validation" -Severity 1
|
||||||
|
if(($SetupSet) -and !($SetupPassword))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "When using the SetupSet switch, the SetupPassword parameter must also be specified"
|
||||||
|
}
|
||||||
|
if(($SetupClear) -and !($OldSetupPassword))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "When using the SetupClear switch, the OldSetupPassword parameter must also be specified"
|
||||||
|
}
|
||||||
|
if(($PowerOnSet) -and !($PowerOnPassword))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "When using the PowerOnSet switch, the PowerOnPassword parameter must also be specified"
|
||||||
|
}
|
||||||
|
if(($PowerOnSet -and $SetupPasswordCheck -eq 1) -and !($SetupPassword))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "When using the PowerOnSet switch on a computer where the setup password is already set, the SetupPassword parameter must also be specified"
|
||||||
|
}
|
||||||
|
if(($PowerOnClear) -and !($OldPowerOnPassword))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "When using the PowerOnClear switch, the OldPowerOnPassword parameter must also be specified"
|
||||||
|
}
|
||||||
|
if(($SetupSet) -and ($SetupClear))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Cannot specify the SetupSet and SetupClear parameters simultaneously"
|
||||||
|
}
|
||||||
|
if(($PowerOnSet) -and ($PowerOnClear))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Cannot specify the PowerOnSet and PowerOnClear parameters simultaneously"
|
||||||
|
}
|
||||||
|
if(($OldSetupPassword -or $SetupPassword) -and !($SetupSet -or $SetupClear))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "When using the OldSetupPassword or SetupPassword parameters, one of the SetupSet or SetupClear parameters must also be specified"
|
||||||
|
}
|
||||||
|
if(($OldPowerOnPassword -or $PowerOnPassword) -and !($PowerOnSet -or $PowerOnClear))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "When using the OldPowerOnPassword or PowerOnPassword parameters, one of the PowerOnSet or PowerOnClear parameters must also be specified"
|
||||||
|
}
|
||||||
|
if($OldSetupPassword.Count -gt 2) #Prevents entering more than 2 old Setup passwords
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Please specify 2 or fewer old Setup passwords"
|
||||||
|
}
|
||||||
|
if($OldPowerOnPassword.Count -gt 2) #Prevents entering more than 2 old power on passwords
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Please specify 2 or fewer old power on passwords"
|
||||||
|
}
|
||||||
|
if(($SMSTSPasswordRetry) -and !(Get-TaskSequenceStatus))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The SMSTSPasswordRetry parameter was specifed while not running in a task sequence. Setting SMSTSPasswordRetry to false." -Severity 2
|
||||||
|
$SMSTSPasswordRetry = $False
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "Parameter validation completed" -Severity 1
|
||||||
|
|
||||||
|
#Set variables from a previous script session
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Check for existing task sequence variables" -Severity 1
|
||||||
|
$HPSetSetup = $TSEnv.Value("HPSetSetup")
|
||||||
|
if($HPSetSetup -eq "Failed")
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Previous unsuccessful setup password set attempt detected" -Severity 1
|
||||||
|
}
|
||||||
|
$HPClearSetup = $TSEnv.Value("HPClearSetup")
|
||||||
|
if($HPClearSetup -eq "Failed")
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Previous unsuccessful setup password clear attempt detected" -Severity 1
|
||||||
|
}
|
||||||
|
$HPSetPowerOn = $TSEnv.Value("HPSetPowerOn")
|
||||||
|
if($HPSetPowerOn -eq "Failed")
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Previous unsuccessful power on password set attempt detected" -Severity 1
|
||||||
|
}
|
||||||
|
$HPClearPowerOn = $TSEnv.Value("HPClearPowerOn")
|
||||||
|
if($HPClearPowerOn -eq "Failed")
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Previous unsuccessful power on password clear attempt detected" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#No setup password currently set
|
||||||
|
if($SetupPasswordCheck -eq 0)
|
||||||
|
{
|
||||||
|
if($SetupClear)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "No Setup password currently set. No need to clear the setup password" -Severity 2
|
||||||
|
Clear-Variable SetupClear
|
||||||
|
}
|
||||||
|
if($SetupSet)
|
||||||
|
{
|
||||||
|
New-HPBiosPassword -PasswordType Setup -Password $SetupPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#No power on password currently set
|
||||||
|
if($PowerOnPasswordCheck -eq 0)
|
||||||
|
{
|
||||||
|
if($PowerOnClear)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "No power on password currently set. No need to clear the power on password" -Severity 2
|
||||||
|
Clear-Variable SetupClear
|
||||||
|
}
|
||||||
|
if($PowerOnSet)
|
||||||
|
{
|
||||||
|
#If the setup password is currently set, the setup password is required to set the power on password
|
||||||
|
if(($HPBiosSetting | Where-Object Name -eq "Setup Password").IsSet -eq 1)
|
||||||
|
{
|
||||||
|
New-HPBiosPassword -PasswordType PowerOn -Password $PowerOnPassword -SetupPW $SetupPassword
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
New-HPBiosPassword -PasswordType PowerOn -Password $PowerOnPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#If a Setup password is set, attempt to clear or change it
|
||||||
|
if($SetupPasswordCheck -eq 1)
|
||||||
|
{
|
||||||
|
#Change the existing Setup password
|
||||||
|
if(($SetupSet) -and ($HPSetSetup -ne "Success"))
|
||||||
|
{
|
||||||
|
if($OldSetupPassword)
|
||||||
|
{
|
||||||
|
Set-HPBiosPassword -PasswordType Setup -Password $SetupPassword -OldPassword $OldSetupPassword
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Set-HPBiosPassword -PasswordType Setup -Password $SetupPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Clear the existing Setup password
|
||||||
|
if(($SetupClear) -and ($HPClearSetup -ne "Success"))
|
||||||
|
{
|
||||||
|
Clear-HPBiosPassword -PasswordType Setup -OldPassword $OldSetupPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#If a power on password is set, attempt to clear or change it
|
||||||
|
if($PowerOnPasswordCheck -eq 1)
|
||||||
|
{
|
||||||
|
#Change the existing power on password
|
||||||
|
if(($PowerOnSet) -and ($HPSetPowerOn -ne "Success"))
|
||||||
|
{
|
||||||
|
if($OldPowerOnPassword)
|
||||||
|
{
|
||||||
|
Set-HPBiosPassword -PasswordType PowerOn -Password $PowerOnPassword -OldPassword $OldPowerOnPassword
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Set-HPBiosPassword -PasswordType PowerOn -Password $PowerOnPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Clear the existing power on password
|
||||||
|
if(($PowerOnClear) -and ($HPClearPowerOn -ne "Success"))
|
||||||
|
{
|
||||||
|
Clear-HPBiosPassword -PasswordType PowerOn -OldPassword $OldPowerOnPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Prompt the user about any failures
|
||||||
|
if((($SetupPWExists -eq "Failed") -or ($SetupPWSet -eq "Failed") -or ($SetupPWClear -eq "Failed") -or ($PowerOnPWExists -eq "Failed") -or ($PowerOnPWSet -eq "Failed") -or ($PowerOnPWClear -eq "Failed")) -and (!($SMSTSPasswordRetry)))
|
||||||
|
{
|
||||||
|
if(!($NoUserPrompt))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failures detected, display on-screen prompts for any required manual actions" -Severity 2
|
||||||
|
#Close the task sequence progress dialog
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSProgress.CloseProgressDialog()
|
||||||
|
}
|
||||||
|
#Display prompts
|
||||||
|
if($SetupPWExists -eq "Failed")
|
||||||
|
{
|
||||||
|
Start-UserPrompt -BodyText "No setup password is set, but the script was unable to set a password. Please reboot the computer and manually set the setup password." -TitleText "HP Password Management Script"
|
||||||
|
}
|
||||||
|
if($SetupPWSet -eq "Failed")
|
||||||
|
{
|
||||||
|
Start-UserPrompt -BodyText "The setup password is set, but cannot be automatically changed. Please reboot the computer and manually change the setup password." -TitleText "HP Password Management Script"
|
||||||
|
}
|
||||||
|
if($SetupPWClear -eq "Failed")
|
||||||
|
{
|
||||||
|
Start-UserPrompt -BodyText "The setup password is set, but cannot be automatically cleared. Please reboot the computer and manually clear the setup password." -TitleText "HP Password Management Script"
|
||||||
|
}
|
||||||
|
if($PowerOnPWExists -eq "Failed")
|
||||||
|
{
|
||||||
|
Start-UserPrompt -BodyText "No power on password is set, but the script was unable to set a password. Please reboot the computer and manually set the power on password." -TitleText "HP Password Management Script"
|
||||||
|
}
|
||||||
|
if($PowerOnPWSet -eq "Failed")
|
||||||
|
{
|
||||||
|
Start-UserPrompt -BodyText "The power on password is set, but cannot be automatically changed. Please reboot the computer and manually change the power on password." -TitleText "HP Password Management Script"
|
||||||
|
}
|
||||||
|
if($PowerOnPWClear -eq "Failed")
|
||||||
|
{
|
||||||
|
Start-UserPrompt -BodyText "The power on password is set, but cannot be automatically cleared. Please reboot the computer and manually clear the power on password." -TitleText "HP Password Management Script"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Exit the script with an error
|
||||||
|
if(!($ContinueOnError))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failures detected, exiting the script" -Severity 3
|
||||||
|
Write-Output "Password management tasks failed. Check the log file for more information"
|
||||||
|
Write-LogEntry -Value "END - HP BIOS password management script" -Severity 1
|
||||||
|
Exit 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failures detected, but the ContinueOnError parameter was set. Script execution will continue" -Severity 3
|
||||||
|
Write-Output "Failures detected, but the ContinueOnError parameter was set. Script execution will continue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif((($SetupPWExists -eq "Failed") -or ($SetupPWSet -eq "Failed") -or ($SetupPWClear -eq "Failed") -or ($PowerOnPWExists -eq "Failed") -or ($PowerOnPWSet -eq "Failed") -or ($PowerOnPWClear -eq "Failed")) -and ($SMSTSPasswordRetry))
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failures detected, but the SMSTSPasswordRetry parameter was set. No user prompts will be displayed" -Severity 3
|
||||||
|
Write-Output "Failures detected, but the SMSTSPasswordRetry parameter was set. No user prompts will be displayed"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-Output "Password management tasks succeeded. Check the log file for more information"
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "END - HP BIOS password management script" -Severity 1
|
|
@ -0,0 +1,513 @@
|
||||||
|
<#
|
||||||
|
.DESCRIPTION
|
||||||
|
Automatically configure HP BIOS settings
|
||||||
|
|
||||||
|
SetBIOSSetting Return Codes
|
||||||
|
0 - Success
|
||||||
|
1 - Not Supported
|
||||||
|
2 - Unspecified Error
|
||||||
|
3 - Timeout
|
||||||
|
4 - Failed - (Check for typos in the setting value)
|
||||||
|
5 - Invalid Parameter
|
||||||
|
6 - Access Denied - (Check that the BIOS password is correct)
|
||||||
|
|
||||||
|
.PARAMETER GetSettings
|
||||||
|
Instruct the script to get a list of current BIOS settings
|
||||||
|
|
||||||
|
.PARAMETER SetSettings
|
||||||
|
Instruct the script to set BIOS settings
|
||||||
|
|
||||||
|
.PARAMETER CsvPath
|
||||||
|
The path to the CSV file to be imported or exported
|
||||||
|
|
||||||
|
.PARAMETER SetupPassword
|
||||||
|
The current BIOS password
|
||||||
|
|
||||||
|
.PARAMETER LogFile
|
||||||
|
Specify the name of the log file along with the full path where it will be stored. The file must have a .log extension. During a task sequence the path will always be set to _SMSTSLogPath
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
#Set BIOS settings supplied in the script
|
||||||
|
Manage-HPBiosSettings.ps1 -SetSettings -SetupPassword ExamplePassword
|
||||||
|
|
||||||
|
#Set BIOS settings supplied in a CSV file
|
||||||
|
Manage-HPBiosSettings.ps1 -SetSettings -CsvPath C:\Temp\Settings.csv -SetupPassword ExamplePassword
|
||||||
|
|
||||||
|
#Output a list of current BIOS settings to the screen
|
||||||
|
Manage-HPBiosSettings.ps1 -GetSettings
|
||||||
|
|
||||||
|
#Output a list of current BIOS settings to a CSV file
|
||||||
|
Manage-HPBiosSettings.ps1 -GetSettings -CsvPath C:\Temp\Settings.csv
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Created by: Jon Anderson (@ConfigJon)
|
||||||
|
Reference: https://www.configjon.com/hp-bios-settings-management/
|
||||||
|
Modified: 2020-09-17
|
||||||
|
|
||||||
|
.CHANGELOG
|
||||||
|
2019-11-04 - Added additional logging. Changed the default log path to $ENV:ProgramData\BiosScripts\HP.
|
||||||
|
2020-02-21 - Added the ability to get a list of current BIOS settings on a system via the GetSettings parameter
|
||||||
|
Added the ability to read settings from or write settings to a csv file with the CsvPath parameter
|
||||||
|
Added the SetSettings parameter to indicate that the script should attempt to set settings
|
||||||
|
Changed the $Settings array in the script to be comma seperated instead of semi-colon seperated
|
||||||
|
Updated formatting
|
||||||
|
2020-09-14 - Added a LogFile parameter. Changed the default log path in full Windows to $ENV:ProgramData\ConfigJonScripts\HP.
|
||||||
|
Consolidated duplicate code into new functions (Stop-Script, Get-WmiData). Made a number of minor formatting and syntax changes
|
||||||
|
2020-09-17 - Improved the log file path configuration
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
#Parameters ===================================================================================================================
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$GetSettings,
|
||||||
|
[Parameter(Mandatory=$false)][Switch]$SetSettings,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$SetupPassword,
|
||||||
|
[ValidateScript({
|
||||||
|
if($_ -notmatch "(\.csv)")
|
||||||
|
{
|
||||||
|
throw "The specified file must be a .csv file"
|
||||||
|
}
|
||||||
|
return $true
|
||||||
|
})]
|
||||||
|
[System.IO.FileInfo]$CsvPath,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateScript({
|
||||||
|
if($_ -notmatch "(\.log)")
|
||||||
|
{
|
||||||
|
throw "The file specified in the LogFile paramter must be a .log file"
|
||||||
|
}
|
||||||
|
return $true
|
||||||
|
})]
|
||||||
|
[System.IO.FileInfo]$LogFile = "$ENV:ProgramData\ConfigJonScripts\HP\Manage-HPBiosSettings.log"
|
||||||
|
)
|
||||||
|
|
||||||
|
#List of settings to be configured ============================================================================================
|
||||||
|
#==============================================================================================================================
|
||||||
|
$Settings = (
|
||||||
|
"Deep S3,Off",
|
||||||
|
"Deep Sleep,Off",
|
||||||
|
"S4/S5 Max Power Savings,Disable",
|
||||||
|
"S5 Maximum Power Savings,Disable",
|
||||||
|
"Fingerprint Device,Disable",
|
||||||
|
"Num Lock State at Power-On,Off",
|
||||||
|
"NumLock on at boot,Disable",
|
||||||
|
"Numlock state at boot,Off",
|
||||||
|
"Prompt for Admin password on F9 (Boot Menu),Enable",
|
||||||
|
"Prompt for Admin password on F11 (System Recovery),Enable",
|
||||||
|
"Prompt for Admin password on F12 (Network Boot),Enable",
|
||||||
|
"PXE Internal IPV4 NIC boot,Enable",
|
||||||
|
"PXE Internal IPV6 NIC boot,Enable",
|
||||||
|
"PXE Internal NIC boot,Enable",
|
||||||
|
"Wake On LAN,Boot to Hard Drive",
|
||||||
|
"Swap Fn and Ctrl (Keys),Disable"
|
||||||
|
)
|
||||||
|
#==============================================================================================================================
|
||||||
|
#==============================================================================================================================
|
||||||
|
|
||||||
|
#Functions ====================================================================================================================
|
||||||
|
|
||||||
|
Function Get-TaskSequenceStatus
|
||||||
|
{
|
||||||
|
#Determine if a task sequence is currently running
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment
|
||||||
|
}
|
||||||
|
catch{}
|
||||||
|
if($NULL -eq $TSEnv)
|
||||||
|
{
|
||||||
|
return $False
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$SMSTSType = $TSEnv.Value("_SMSTSType")
|
||||||
|
}
|
||||||
|
catch{}
|
||||||
|
if($NULL -eq $SMSTSType)
|
||||||
|
{
|
||||||
|
return $False
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Stop-Script
|
||||||
|
{
|
||||||
|
#Write an error to the log file and terminate the script
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$ErrorMessage,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$Exception
|
||||||
|
)
|
||||||
|
Write-LogEntry -Value $ErrorMessage -Severity 3
|
||||||
|
if($Exception)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Exception Message: $Exception" -Severity 3
|
||||||
|
}
|
||||||
|
throw $ErrorMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-WmiData
|
||||||
|
{
|
||||||
|
#Gets WMI data using either the WMI or CIM cmdlets and stores the data in a variable
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$Namespace,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$ClassName,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateSet('CIM','WMI')]$CmdletType,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String[]]$Select
|
||||||
|
)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if($CmdletType -eq "CIM")
|
||||||
|
{
|
||||||
|
if($Select)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $Classname WMI class from the $Namespace namespace and select properties: $Select" -Severity 1
|
||||||
|
$Query = Get-CimInstance -Namespace $Namespace -ClassName $ClassName -ErrorAction Stop | Select-Object $Select -ErrorAction Stop
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $ClassName WMI class from the $Namespace namespace" -Severity 1
|
||||||
|
$Query = Get-CimInstance -Namespace $Namespace -ClassName $ClassName -ErrorAction Stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif($CmdletType -eq "WMI")
|
||||||
|
{
|
||||||
|
if($Select)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $Classname WMI class from the $Namespace namespace and select properties: $Select" -Severity 1
|
||||||
|
$Query = Get-WmiObject -Namespace $Namespace -Class $ClassName -ErrorAction Stop | Select-Object $Select -ErrorAction Stop
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Get the $ClassName WMI class from the $Namespace namespace" -Severity 1
|
||||||
|
$Query = Get-WmiObject -Namespace $Namespace -Class $ClassName -ErrorAction Stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if($Select)
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "An error occurred while attempting to get the $Select properties from the $Classname WMI class in the $Namespace namespace" -Exception $PSItem.Exception.Message
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "An error occurred while connecting to the $Classname WMI class in the $Namespace namespace" -Exception $PSItem.Exception.Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "Successfully connected to the $ClassName WMI class" -Severity 1
|
||||||
|
return $Query
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Set-HPBiosSetting
|
||||||
|
{
|
||||||
|
#Set a specific HP BIOS setting
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$Name,
|
||||||
|
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String]$Value,
|
||||||
|
[Parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][String]$Password
|
||||||
|
)
|
||||||
|
#Ensure the specified setting exists and get the possible values
|
||||||
|
$CurrentSetting = $SettingList | Where-Object Name -eq $Name | Select-Object -ExpandProperty Value
|
||||||
|
if($NULL -ne $CurrentSetting)
|
||||||
|
{
|
||||||
|
#Split the current values
|
||||||
|
$CurrentSettingSplit = $CurrentSetting.Split(',')
|
||||||
|
#Find the currently set value
|
||||||
|
$Count = 0
|
||||||
|
while($Count -lt $CurrentSettingSplit.Count)
|
||||||
|
{
|
||||||
|
if($CurrentSettingSplit[$Count].StartsWith('*'))
|
||||||
|
{
|
||||||
|
$CurrentValue = $CurrentSettingSplit[$Count]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$Count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Setting is already set to specified value
|
||||||
|
if($CurrentValue.Substring(1) -eq $Value)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Setting ""$Name"" is already set to ""$Value""" -Severity 1
|
||||||
|
$Script:AlreadySet++
|
||||||
|
}
|
||||||
|
#Setting is not set to specified value
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!([String]::IsNullOrEmpty($Password)))
|
||||||
|
{
|
||||||
|
$SettingResult = ($Interface.SetBIOSSetting($Name,$Value,"<utf-16/>" + $Password)).Return
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$SettingResult = ($Interface.SetBIOSSetting($Name,$Value)).Return
|
||||||
|
}
|
||||||
|
if($SettingResult -eq 0)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Successfully set ""$Name"" to ""$Value""" -Severity 1
|
||||||
|
$Script:SuccessSet++
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Failed to set ""$Name"" to ""$Value"". Return code $SettingResult" -Severity 3
|
||||||
|
$Script:FailSet++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Setting not found
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Setting ""$Name"" not found" -Severity 2
|
||||||
|
$Script:NotFound++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Write-LogEntry
|
||||||
|
{
|
||||||
|
#Write data to a CMTrace compatible log file. (Credit to SCConfigMgr - https://www.scconfigmgr.com/)
|
||||||
|
|
||||||
|
param(
|
||||||
|
[parameter(Mandatory = $true, HelpMessage = "Value added to the log file.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$Value,
|
||||||
|
[parameter(Mandatory = $true, HelpMessage = "Severity for the log entry. 1 for Informational, 2 for Warning and 3 for Error.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[ValidateSet("1", "2", "3")]
|
||||||
|
[string]$Severity,
|
||||||
|
[parameter(Mandatory = $false, HelpMessage = "Name of the log file that the entry will written to.")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$FileName = ($script:LogFile | Split-Path -Leaf)
|
||||||
|
)
|
||||||
|
#Determine log file location
|
||||||
|
$LogFilePath = Join-Path -Path $LogsDirectory -ChildPath $FileName
|
||||||
|
#Construct time stamp for log entry
|
||||||
|
if(-not(Test-Path -Path 'variable:global:TimezoneBias'))
|
||||||
|
{
|
||||||
|
[string]$global:TimezoneBias = [System.TimeZoneInfo]::Local.GetUtcOffset((Get-Date)).TotalMinutes
|
||||||
|
if($TimezoneBias -match "^-")
|
||||||
|
{
|
||||||
|
$TimezoneBias = $TimezoneBias.Replace('-', '+')
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$TimezoneBias = '-' + $TimezoneBias
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$Time = -join @((Get-Date -Format "HH:mm:ss.fff"), $TimezoneBias)
|
||||||
|
#Construct date for log entry
|
||||||
|
$Date = (Get-Date -Format "MM-dd-yyyy")
|
||||||
|
#Construct context for log entry
|
||||||
|
$Context = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
|
||||||
|
#Construct final log entry
|
||||||
|
$LogText = "<![LOG[$($Value)]LOG]!><time=""$($Time)"" date=""$($Date)"" component=""Manage-HPBiosSettings"" context=""$($Context)"" type=""$($Severity)"" thread=""$($PID)"" file="""">"
|
||||||
|
#Add value to log file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Out-File -InputObject $LogText -Append -NoClobber -Encoding Default -FilePath $LogFilePath -ErrorAction Stop
|
||||||
|
}
|
||||||
|
catch [System.Exception]
|
||||||
|
{
|
||||||
|
Write-Warning -Message "Unable to append log entry to $FileName file. Error message at line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Main program =================================================================================================================
|
||||||
|
|
||||||
|
#Configure Logging and task sequence variables
|
||||||
|
if(Get-TaskSequenceStatus)
|
||||||
|
{
|
||||||
|
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
|
||||||
|
$LogsDirectory = $TSEnv.Value("_SMSTSLogPath")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$LogsDirectory = ($LogFile | Split-Path)
|
||||||
|
if([string]::IsNullOrEmpty($LogsDirectory))
|
||||||
|
{
|
||||||
|
$LogsDirectory = $PSScriptRoot
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(Test-Path -PathType Container $LogsDirectory))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
New-Item -Path $LogsDirectory -ItemType "Directory" -Force -ErrorAction Stop | Out-Null
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw "Failed to create the log file directory: $LogsDirectory. Exception Message: $($PSItem.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Output "Log path set to $LogFile"
|
||||||
|
Write-LogEntry -Value "START - HP BIOS settings management script" -Severity 1
|
||||||
|
|
||||||
|
#Connect to the HP_BIOSEnumeration WMI class
|
||||||
|
$SettingList = Get-WmiData -Namespace root\hp\InstrumentedBIOS -ClassName HP_BIOSEnumeration -CmdletType WMI
|
||||||
|
|
||||||
|
#Connect to the HP_BIOSSettingInterface WMI class
|
||||||
|
$Interface = Get-WmiData -Namespace root\hp\InstrumentedBIOS -ClassName HP_BIOSSettingInterface -CmdletType WMI
|
||||||
|
|
||||||
|
#Connect to the HP_BIOSSetting WMI class
|
||||||
|
$HPBiosSetting = Get-WmiData -Namespace root\hp\InstrumentedBIOS -ClassName HP_BIOSSetting -CmdletType WMI
|
||||||
|
|
||||||
|
#Parameter validation
|
||||||
|
Write-LogEntry -Value "Begin parameter validation" -Severity 1
|
||||||
|
if($GetSettings -and $SetSettings)
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Cannot specify the GetSettings and SetSettings parameters at the same time"
|
||||||
|
}
|
||||||
|
if(!($GetSettings -or $SetSettings))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "One of the GetSettings or SetSettings parameters must be specified when running this script"
|
||||||
|
}
|
||||||
|
if($SetSettings -and !($Settings -or $CsvPath))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "Settings must be specified using either the Settings variable in the script or the CsvPath parameter"
|
||||||
|
}
|
||||||
|
Write-LogEntry -Value "Parameter validation completed" -Severity 1
|
||||||
|
|
||||||
|
#Set counters to 0
|
||||||
|
if($SetSettings)
|
||||||
|
{
|
||||||
|
$AlreadySet = 0
|
||||||
|
$SuccessSet = 0
|
||||||
|
$FailSet = 0
|
||||||
|
$NotFound = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#Get the current password status
|
||||||
|
if($SetSettings)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "Check current BIOS setup password status" -Severity 1
|
||||||
|
$PasswordCheck = ($HPBiosSetting | Where-Object Name -eq "Setup Password").IsSet
|
||||||
|
if($PasswordCheck -eq 1)
|
||||||
|
{
|
||||||
|
#Setup password set but parameter not specified
|
||||||
|
if([String]::IsNullOrEmpty($SetupPassword))
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "The BIOS setup password is set, but no password was supplied. Use the SetupPassword parameter when a password is set"
|
||||||
|
}
|
||||||
|
#Setup password set correctly
|
||||||
|
if(($Interface.SetBIOSSetting("Setup Password","<utf-16/>" + $SetupPassword,"<utf-16/>" + $SetupPassword)).Return -eq 0)
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The specified setup password matches the currently set password" -Severity 1
|
||||||
|
}
|
||||||
|
#Setup password not set correctly
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stop-Script -ErrorMessage "The specified setup password does not match the currently set password"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-LogEntry -Value "The BIOS setup password is not currently set" -Severity 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Get the current settings
|
||||||
|
if($GetSettings)
|
||||||
|
{
|
||||||
|
$SettingList = $SettingList | Select-Object Name,Value | Sort-Object Name
|
||||||
|
$SettingObject = ForEach($Setting in $SettingList){
|
||||||
|
#Split the current values
|
||||||
|
$SettingSplit = ($Setting.Value).Split(',')
|
||||||
|
#Find the currently set value
|
||||||
|
$SplitCount = 0
|
||||||
|
while($SplitCount -lt $SettingSplit.Count)
|
||||||
|
{
|
||||||
|
if($SettingSplit[$SplitCount].StartsWith('*'))
|
||||||
|
{
|
||||||
|
$SetValue = ($SettingSplit[$SplitCount]).Substring(1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$SplitCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[PSCustomObject]@{
|
||||||
|
Name = $Setting.Name
|
||||||
|
Value = $SetValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($CsvPath)
|
||||||
|
{
|
||||||
|
$SettingObject | Export-Csv -Path $CsvPath -NoTypeInformation
|
||||||
|
(Get-Content $CsvPath) | ForEach-Object {$_ -Replace '"',""} | Out-File $CsvPath -Force -Encoding ascii
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-Output $SettingObject
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Set settings
|
||||||
|
if($SetSettings)
|
||||||
|
{
|
||||||
|
if($CsvPath)
|
||||||
|
{
|
||||||
|
Clear-Variable Settings -ErrorAction SilentlyContinue
|
||||||
|
$Settings = Import-Csv -Path $CsvPath
|
||||||
|
}
|
||||||
|
#Set HP BIOS settings - password is set
|
||||||
|
if($PasswordCheck -eq 1)
|
||||||
|
{
|
||||||
|
if($CsvPath)
|
||||||
|
{
|
||||||
|
ForEach($Setting in $Settings){
|
||||||
|
Set-HPBiosSetting -Name $Setting.Name -Value $Setting.Value -Password $SetupPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ForEach($Setting in $Settings){
|
||||||
|
$Data = $Setting.Split(',')
|
||||||
|
Set-HPBiosSetting -Name $Data[0].Trim() -Value $Data[1].Trim() -Password $SetupPassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#Set HP BIOS settings - password is not set
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if($CsvPath)
|
||||||
|
{
|
||||||
|
ForEach($Setting in $Settings){
|
||||||
|
Set-HPBiosSetting -Name $Setting.Name -Value $Setting.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ForEach($Setting in $Settings){
|
||||||
|
$Data = $Setting.Split(',')
|
||||||
|
Set-HPBiosSetting -Name $Data[0].Trim() -Value $Data[1].Trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Display results
|
||||||
|
if($SetSettings)
|
||||||
|
{
|
||||||
|
Write-Output "$AlreadySet settings already set correctly"
|
||||||
|
Write-LogEntry -Value "$AlreadySet settings already set correctly" -Severity 1
|
||||||
|
Write-Output "$SuccessSet settings successfully set"
|
||||||
|
Write-LogEntry -Value "$SuccessSet settings successfully set" -Severity 1
|
||||||
|
Write-Output "$FailSet settings failed to set"
|
||||||
|
Write-LogEntry -Value "$FailSet settings failed to set" -Severity 3
|
||||||
|
Write-Output "$NotFound settings not found"
|
||||||
|
Write-LogEntry -Value "$NotFound settings not found" -Severity 2
|
||||||
|
}
|
||||||
|
Write-Output "HP BIOS settings Management completed. Check the log file for more information"
|
||||||
|
Write-LogEntry -Value "END - HP BIOS settings management script" -Severity 1
|
|
@ -0,0 +1,61 @@
|
||||||
|
Name,Value
|
||||||
|
After Power Loss,Off
|
||||||
|
Deep S3,Off
|
||||||
|
Deep Sleep,Off
|
||||||
|
Power state after power loss,Power Off
|
||||||
|
S4/S5 Max Power Savings,Disable
|
||||||
|
S5 Maximum Power Savings,Disable
|
||||||
|
Wake unit from sleep when lid is opened,Enable
|
||||||
|
Wake unit from sleep when lid is opened,Enabled
|
||||||
|
Wake when Lid is Opened,Enable
|
||||||
|
Audio Alerts During Boot,Enable
|
||||||
|
Audio Device,Enable
|
||||||
|
Fingerprint Device,Disable
|
||||||
|
Integrated Audio,Enable
|
||||||
|
Integrated Camera,Enable
|
||||||
|
Integrated Microphone,Enable
|
||||||
|
Internal speaker,Enable
|
||||||
|
Internal speakers,Enable
|
||||||
|
Microphone,Enable
|
||||||
|
Num Lock State at Power-On,Off
|
||||||
|
NumLock on at boot,Off
|
||||||
|
NumLock on at boot,Disable
|
||||||
|
Numlock state at boot,Off
|
||||||
|
System Audio,Device available
|
||||||
|
Intel VT for Directed I/O (VT-d),Enable
|
||||||
|
Intel(R) VT-d,Enable
|
||||||
|
Virtualization Technology,Enable
|
||||||
|
Virtualization Technology (VTx),Enable
|
||||||
|
Virtualization Technology (VT-x),Enable
|
||||||
|
Virtualization Technology (VTx/VTd),Enable
|
||||||
|
Virtualization Technology Directed I/O (VTd),Enable
|
||||||
|
Virtualization Technology Directed I/O (VT-d2),Enable
|
||||||
|
Virtualization Technology for Directed I/O,Enable
|
||||||
|
Virtualization Technology for Directed I/O (VTd),Enable
|
||||||
|
Password prompt on F9 & F12,Enable
|
||||||
|
Password prompt on F9 F11 & F12,Enable
|
||||||
|
Prompt for Admin password on F9 (Boot Menu),Enable
|
||||||
|
Prompt for Admin password on F11 (System Recovery),Enable
|
||||||
|
Prompt for Admin password on F12 (Network Boot),Enable
|
||||||
|
Network (PXE) Boot,Enable
|
||||||
|
Network (PXE) Boot Configuration,IPv4 Before IPv6
|
||||||
|
Network Boot,Enable
|
||||||
|
Network Service Boot,Enable
|
||||||
|
PXE Internal IPV4 NIC boot,Enable
|
||||||
|
PXE Internal IPV6 NIC boot,Enable
|
||||||
|
PXE Internal NIC boot,Enable
|
||||||
|
Remote Wakeup Boot Source,Local Hard Drive
|
||||||
|
S4/S5 Wake on LAN,Enable
|
||||||
|
S5 Wake on LAN,Enable
|
||||||
|
S5 Wake On LAN,Boot to Hard Drive
|
||||||
|
Wake on LAN,Follow Boot Order
|
||||||
|
Wake On LAN,Boot to Hard Drive
|
||||||
|
Wake on LAN on DC mode,Enable
|
||||||
|
Wake on LAN on DC mode,Enabled
|
||||||
|
Wake on WLAN,Enable
|
||||||
|
Fast Boot,Enable
|
||||||
|
LAN / WLAN Auto Switching,Enabled
|
||||||
|
LAN / WLAN Auto Switching,Enable
|
||||||
|
LAN/WLAN Switching,Enable
|
||||||
|
Swap Fn and Ctrl (Keys),Disable
|
||||||
|
Swap Fn and Ctrl (Keys),Disabled
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
Name,Value
|
||||||
|
Boot Mode,UEFI Native (Without CSM)
|
||||||
|
Configure Option ROM Launch Policy,All UEFI
|
||||||
|
Legacy Boot Options,Disable
|
||||||
|
Legacy Support,Disable
|
||||||
|
PXE Option ROMs,UEFI Only
|
||||||
|
Storage Option ROMs,UEFI Only
|
||||||
|
UEFI Boot Mode,Enable
|
||||||
|
UEFI Boot Options,Enable
|
||||||
|
Video Option ROMs,UEFI Only
|
||||||
|
Configure Legacy Support and Secure Boot,Legacy Support Disable and Secure Boot Enable
|
||||||
|
Configure Legacy Support and Secure Boot,Disable Legacy Support and Enable Secure Boot
|
||||||
|
Secure Boot,Enable
|
||||||
|
SecureBoot,Enable
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
Name,Value
|
||||||
|
Embedded Security Device,Device available
|
||||||
|
Embedded Security Device Availability,Available
|
||||||
|
OS management of Embedded Security Device,Enable
|
||||||
|
OS Management of TPM,Enable
|
||||||
|
Reset of Embedded Security Device through OS,Enable
|
||||||
|
Reset of TPM from OS,Enable
|
||||||
|
TPM Device,Available
|
||||||
|
TPM State,Enable
|
||||||
|
Activate Embedded Security On Next Boot,Enable
|
||||||
|
Activate TPM On Next Boot,Enable
|
||||||
|
Embedded Security Activation Policy,No prompts
|
||||||
|
TPM Activation Policy,No prompts
|
||||||
|
Clear TPM,No
|
||||||
|
TPM Clear,Do not Clear
|
||||||
|
Physical Presence Interface,Disable
|
||||||
|
Tpm No PPI maintenance,Enable
|
||||||
|
Tpm No PPI provisioning,Enable
|
||||||
|
Tpm PPI policy changed by OS allowed,Enable
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
#Power Settings
|
||||||
|
"After Power Loss;Off", #Off,On,Previous State
|
||||||
|
"Deep S3;Off", #Off,On,Auto
|
||||||
|
"Deep Sleep;Off", #Off,On,Auto
|
||||||
|
"Power state after power loss;Power Off", #Power On,Power Off,Previous State
|
||||||
|
"S4/S5 Max Power Savings;Disable", #Disable,Enable
|
||||||
|
"S5 Maximum Power Savings;Disable", #Disable,Enable
|
||||||
|
"Wake unit from sleep when lid is opened;Enable", #Disable,Enable
|
||||||
|
"Wake unit from sleep when lid is opened;Enabled", #Disabled,Enabled
|
||||||
|
"Wake when Lid is Opened;Enable", #Disable,Enable
|
||||||
|
#Integrated Device Settings
|
||||||
|
"Audio Alerts During Boot;Enable", #Disable,Enable
|
||||||
|
"Audio Device;Enable", #Disable,Enable
|
||||||
|
"Fingerprint Device;Disable", #Disable,Enable
|
||||||
|
"Integrated Audio;Enable", #Disable,Enable
|
||||||
|
"Integrated Camera;Enable", #Disable,Enable
|
||||||
|
"Integrated Microphone;Enable", #Disable,Enable
|
||||||
|
"Internal speaker;Enable", #Disable,Enable
|
||||||
|
"Internal speakers;Enable", #Disable,Enable
|
||||||
|
"Microphone;Enable", #Disable,Enable
|
||||||
|
"Num Lock State at Power-On;Off", #Off,On
|
||||||
|
"NumLock on at boot;Off", #On,Off
|
||||||
|
"NumLock on at boot;Disable", #Disable,Enable
|
||||||
|
"Numlock state at boot;Off", #On,Off
|
||||||
|
"System Audio;Device available", #Device available,Device hidden
|
||||||
|
#Virtualization Settings
|
||||||
|
"Intel VT for Directed I/O (VT-d);Enable", #Disable,Enable
|
||||||
|
"Intel(R) VT-d;Enable", #Disable,Enable
|
||||||
|
"Virtualization Technology;Enable", #Disable,Enable,Reset to default
|
||||||
|
"Virtualization Technology (VTx);Enable", #Disable,Enable,Reset to default
|
||||||
|
"Virtualization Technology (VT-x);Enable", #Disable,Enable
|
||||||
|
"Virtualization Technology (VTx/VTd);Enable", #Disable,Enable
|
||||||
|
"Virtualization Technology Directed I/O (VTd);Enable", #Disable,Enable
|
||||||
|
"Virtualization Technology Directed I/O (VT-d2);Enable", #Disable,Enable
|
||||||
|
"Virtualization Technology for Directed I/O;Enable", #Disable,Enable,Reset to default
|
||||||
|
"Virtualization Technology for Directed I/O (VTd);Enable", #Disable,Enable,Reset to default
|
||||||
|
#Security Settings
|
||||||
|
"Password prompt on F9 & F12;Enable", #Enable,Disable
|
||||||
|
"Password prompt on F9 F11 & F12;Enable", #Enable,Disable
|
||||||
|
"Prompt for Admin password on F9 (Boot Menu);Enable", #Disable,Enable
|
||||||
|
"Prompt for Admin password on F11 (System Recovery);Enable", #Disable,Enable
|
||||||
|
"Prompt for Admin password on F12 (Network Boot);Enable", #Disable,Enable
|
||||||
|
#PXE Boot Settings
|
||||||
|
"Network (PXE) Boot;Enable", #Disable,Enable
|
||||||
|
"Network (PXE) Boot Configuration;IPv4 Before IPv6", #IPv4 Before IPv6,IPv6 Before IPv4,IPv4 Disabled,IPv6 Disabled
|
||||||
|
"Network Boot;Enable", #Disable,Enable
|
||||||
|
"Network Service Boot;Enable", #Disable,Enable
|
||||||
|
"PXE Internal IPV4 NIC boot;Enable", #Disable,Enable
|
||||||
|
"PXE Internal IPV6 NIC boot;Enable", #Disable,Enable
|
||||||
|
"PXE Internal NIC boot;Enable", #Disable,Enable
|
||||||
|
#Wake on LAN Settings
|
||||||
|
"Remote Wakeup Boot Source;Local Hard Drive", #Remote Server,Local Hard Drive
|
||||||
|
"S4/S5 Wake on LAN;Enable", #Disable,Enable
|
||||||
|
"S5 Wake on LAN;Enable", #Enable,Disable
|
||||||
|
"S5 Wake On LAN;Boot to Hard Drive", #Disable,Boot to Network,Boot to Hard Drive
|
||||||
|
"Wake on LAN;Follow Boot Order", #Disable,Boot to Network,Follow Boot Order
|
||||||
|
"Wake On LAN;Boot to Hard Drive", #Disabled,Boot to Network,Boot to Hard Drive,Boot to Normal Boot Order
|
||||||
|
"Wake on LAN on DC mode;Enable", #Disable,Enable
|
||||||
|
"Wake on LAN on DC mode;Enabled", #Disabled,Enabled
|
||||||
|
"Wake on WLAN;Enable", #Disable,Enable
|
||||||
|
#Other Settings
|
||||||
|
"Fast Boot;Enable", #Disable,Enable
|
||||||
|
"LAN / WLAN Auto Switching;Enabled", #Disabled,Enabled
|
||||||
|
"LAN / WLAN Auto Switching;Enable", #Disable,Enable
|
||||||
|
"LAN/WLAN Switching;Enable", #Disable,Enable
|
||||||
|
"Swap Fn and Ctrl (Keys);Disable", #Disable,Enable
|
||||||
|
"Swap Fn and Ctrl (Keys);Disabled", #Disabled,Enabled
|
||||||
|
#Enable TPM
|
||||||
|
"Embedded Security Device;Device available", #Device hidden,Device available
|
||||||
|
"Embedded Security Device Availability;Available", #Available,Hidden
|
||||||
|
"OS management of Embedded Security Device;Enable", #Enable,Disable
|
||||||
|
"OS Management of TPM;Enable", #Disable,Enable
|
||||||
|
"Reset of Embedded Security Device through OS;Enable", #Disable,Enable
|
||||||
|
"Reset of TPM from OS;Enable", #Disable,Enable
|
||||||
|
"TPM Device;Available", #Hidden,Available
|
||||||
|
"TPM State;Enable", #Disable,Enable
|
||||||
|
#Activate TPM
|
||||||
|
"Activate Embedded Security On Next Boot;Enable", #Disable,Enable
|
||||||
|
"Activate TPM On Next Boot;Enable", #Disable,Enable
|
||||||
|
"Embedded Security Activation Policy;No prompts", #F1 to Boot,Allow user to reject,No prompts
|
||||||
|
"TPM Activation Policy;No prompts", #F1 to Boot,Allow user to reject,No prompts
|
||||||
|
#Clear TPM
|
||||||
|
"Clear TPM;No", #No,On next boot
|
||||||
|
"TPM Clear;Do not Clear", #Do not Clear,Clear
|
||||||
|
#Physical Presence Interface Settings
|
||||||
|
"Physical Presence Interface;Disable", #Disable,Enable
|
||||||
|
"Tpm No PPI maintenance;Enable", #Disable,Enable
|
||||||
|
"Tpm No PPI provisioning;Enable", #Disable,Enable
|
||||||
|
"Tpm PPI policy changed by OS allowed;Enable", #Disable,Enable
|
||||||
|
#Enable UEFI Support
|
||||||
|
"Boot Mode;UEFI Native (Without CSM)", #Legacy,UEFI Hybrid (With CSM),UEFI Native (Without CSM)
|
||||||
|
"Configure Option ROM Launch Policy;All UEFI", #All Legacy,All UEFI,All UEFI Except Video
|
||||||
|
"Legacy Boot Options;Disable", #Disable,Enable
|
||||||
|
"Legacy Support;Disable", #Disable,Enable
|
||||||
|
"PXE Option ROMs;UEFI Only", #Do Not Launch,UEFI Only,Legacy Only
|
||||||
|
"Storage Option ROMs;UEFI Only", #Do Not Launch,UEFI Only,Legacy Only
|
||||||
|
"UEFI Boot Mode;Enable", #Disable,Enable
|
||||||
|
"UEFI Boot Options;Enable", #Disable,Enable
|
||||||
|
"Video Option ROMs;UEFI Only", #Legacy Only,UEFI Only
|
||||||
|
#Enable Secure Boot
|
||||||
|
"Configure Legacy Support and Secure Boot;Legacy Support Disable and Secure Boot Enable", #Legacy Support Enable and Secure Boot Disable,Legacy Support Disable and Secure Boot Enable,Legacy Support Disable and Secure Boot Disable
|
||||||
|
"Configure Legacy Support and Secure Boot;Disable Legacy Support and Enable Secure Boot", #Enable Legacy Support and Disable Secure Boot,Disable Legacy Support and Enable Secure Boot,Disable Legacy Support and Disable Secure Boot
|
||||||
|
"Secure Boot;Enable", #Disable,Enable
|
||||||
|
"SecureBoot;Enable" #Disable,Enable
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Define the character set, password length, and the file to save tried combinations
|
||||||
|
$charset = "abc"
|
||||||
|
$passLength = 3
|
||||||
|
$TriedCombinationsFile = ".\tried_combinations.txt"
|
||||||
|
|
||||||
|
# Function to generate all combinations
|
||||||
|
function Generate-Combinations($charset, $length) {
|
||||||
|
# Your combination generation logic here
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load tried combinations into memory
|
||||||
|
$triedCombinations = @{}
|
||||||
|
if (Test-Path $TriedCombinationsFile) {
|
||||||
|
Get-Content $TriedCombinationsFile | ForEach-Object { $triedCombinations[$_] = $true }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Attempt to clear the BIOS password with all combinations, skipping tried ones
|
||||||
|
Generate-Combinations $charset $passLength | ForEach-Object {
|
||||||
|
$password = $_
|
||||||
|
if (-not $triedCombinations.ContainsKey($password)) {
|
||||||
|
Write-Output "Trying password: $password"
|
||||||
|
|
||||||
|
# Attempt to clear the BIOS password using the current password
|
||||||
|
& "C:\Path\To\Manage-HPBiosPasswords.ps1" -SetupClear -OldSetupPassword $password
|
||||||
|
|
||||||
|
# Add password to tried combinations and save to file
|
||||||
|
$password | Add-Content $TriedCombinationsFile
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Define the path to the original and local password list file
|
||||||
|
$OriginalPasswordListFile = "C:\Path\To\passwordlist.txt"
|
||||||
|
$LocalPasswordListFile = ".\passwordlist_local.txt"
|
||||||
|
|
||||||
|
# Copy the original password list to the local directory if it doesn't exist
|
||||||
|
if (-not (Test-Path $LocalPasswordListFile)) {
|
||||||
|
Copy-Item $OriginalPasswordListFile $LocalPasswordListFile
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read and attempt each password, then remove it from the local list
|
||||||
|
Get-Content $LocalPasswordListFile | ForEach-Object {
|
||||||
|
$password = $_
|
||||||
|
Write-Output "Trying password: $password"
|
||||||
|
|
||||||
|
# Attempt to clear the BIOS password using the current password
|
||||||
|
& "C:\Path\To\Manage-HPBiosPasswords.ps1" -SetupClear -OldSetupPassword $password
|
||||||
|
|
||||||
|
# Remove the tried password from the local list
|
||||||
|
(Get-Content $LocalPasswordListFile) | Where-Object { $_ -ne $password } | Set-Content $LocalPasswordListFile
|
||||||
|
}
|
Loading…
Reference in New Issue