diff --git a/HP/Install-HPCMSL.ps1 b/HP/Install-HPCMSL.ps1 new file mode 100644 index 0000000..535e323 --- /dev/null +++ b/HP/Install-HPCMSL.ps1 @@ -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 = "" + #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 \ No newline at end of file diff --git a/HP/Manage-HPBiosPasswords.ps1 b/HP/Manage-HPBiosPasswords.ps1 new file mode 100644 index 0000000..982beec --- /dev/null +++ b/HP/Manage-HPBiosPasswords.ps1 @@ -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 + + Set or change a setup password + Manage-HPBiosPasswords.ps1 -SetupSet -SetupPassword -OldSetupPassword , + + Clear existing setup password(s) + Manage-HPBiosPasswords.ps1 -SetupClear -OldSetupPassword , + + Set a new setup password and set a new power on password when no old passwords exist + Manage-HPBiosPasswords.ps1 -SetupSet -PowerOnSet -SetupPassword -PowerOnPassword + + Set or change an existing setup password and clear a power on password + Manage-HPBiosPasswords.ps1 -SetupSet -SetupPassword -OldSetupPassword , -PowerOnClear -OldPowerOnPassword , + + Clear existing Setup and power on passwords + Manage-HPBiosPasswords.ps1 -SetupClear -OldSetupPassword , -PowerOnClear -OldPowerOnPassword , + + Set a new power on password when the setup password is already set + Manage-HPBiosPasswords.ps1 -PowerOnSet -PowerOnPassword -SetupPassword + + .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,"" + $Password,"" + $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,"" + $Password,"")).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,"" + $Password,"" + $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,"" + $Password,"" + $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,"","" + $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 = "" + #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 \ No newline at end of file diff --git a/HP/Manage-HPBiosSettings.ps1 b/HP/Manage-HPBiosSettings.ps1 new file mode 100644 index 0000000..9c9de1e --- /dev/null +++ b/HP/Manage-HPBiosSettings.ps1 @@ -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,"" + $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 = "" + #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","" + $SetupPassword,"" + $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 \ No newline at end of file diff --git a/HP/Settings_CSV_General.csv b/HP/Settings_CSV_General.csv new file mode 100644 index 0000000..76be477 --- /dev/null +++ b/HP/Settings_CSV_General.csv @@ -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 \ No newline at end of file diff --git a/HP/Settings_CSV_SecureBoot.csv b/HP/Settings_CSV_SecureBoot.csv new file mode 100644 index 0000000..4fefe69 --- /dev/null +++ b/HP/Settings_CSV_SecureBoot.csv @@ -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 \ No newline at end of file diff --git a/HP/Settings_CSV_TPM.csv b/HP/Settings_CSV_TPM.csv new file mode 100644 index 0000000..dfbaf6c --- /dev/null +++ b/HP/Settings_CSV_TPM.csv @@ -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 \ No newline at end of file diff --git a/HP/Settings_InScript_All.txt b/HP/Settings_InScript_All.txt new file mode 100644 index 0000000..fc56e19 --- /dev/null +++ b/HP/Settings_InScript_All.txt @@ -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 \ No newline at end of file diff --git a/HP/bruteforce.ps1 b/HP/bruteforce.ps1 new file mode 100644 index 0000000..4c37437 --- /dev/null +++ b/HP/bruteforce.ps1 @@ -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 + } +} diff --git a/HP/passlist.ps1 b/HP/passlist.ps1 new file mode 100644 index 0000000..c76a177 --- /dev/null +++ b/HP/passlist.ps1 @@ -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 +}