Compare commits
	
		
			No commits in common. "master" and "d1b55fc685d11956a03b846388806f1699c6bf50" have entirely different histories.
		
	
	
		
			master
			...
			d1b55fc685
		
	
		| 
						 | 
				
			
			@ -1,570 +0,0 @@
 | 
			
		|||
<#
 | 
			
		||||
    .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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,710 +0,0 @@
 | 
			
		|||
<#
 | 
			
		||||
	.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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,513 +0,0 @@
 | 
			
		|||
<#
 | 
			
		||||
    .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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,61 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
		
		
			
  | 
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
		
		
			
  | 
| 
						 | 
				
			
			@ -1,19 +0,0 @@
 | 
			
		|||
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
 | 
			
		||||
		
		
			
  | 
| 
						 | 
				
			
			@ -1,104 +0,0 @@
 | 
			
		|||
#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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,29 +0,0 @@
 | 
			
		|||
# 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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
# 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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
@echo off
 | 
			
		||||
setlocal enabledelayedexpansion
 | 
			
		||||
 | 
			
		||||
REM Define the path to the HP tools
 | 
			
		||||
set HPQPswdPath=C:\Path\To\HPQPswd.exe
 | 
			
		||||
set BiosConfigUtilityPath=C:\Path\To\BiosConfigUtility.exe
 | 
			
		||||
 | 
			
		||||
REM Define the path for the password files
 | 
			
		||||
set EncryptedPasswordFile=C:\Path\To\EncryptedPassword.bin
 | 
			
		||||
 | 
			
		||||
REM Define the character set and password length
 | 
			
		||||
set charset=abc
 | 
			
		||||
set passlength=3
 | 
			
		||||
 | 
			
		||||
REM Generate and try all possible combinations
 | 
			
		||||
for %%a in (!charset!) do (
 | 
			
		||||
    for %%b in (!charset!) do (
 | 
			
		||||
        for %%c in (!charset!) do (
 | 
			
		||||
            set "pass=%%a%%b%%c"
 | 
			
		||||
            echo Trying password: !pass!
 | 
			
		||||
 | 
			
		||||
            REM Create the encrypted password file for the current password
 | 
			
		||||
            "!HPQPswdPath!" /p"!pass!" /f"!EncryptedPasswordFile!"
 | 
			
		||||
 | 
			
		||||
            REM Attempt to reset the BIOS password using the current password
 | 
			
		||||
            "!BiosConfigUtilityPath!" /cpwdfile:"!EncryptedPasswordFile!" /npwdfile:""
 | 
			
		||||
            
 | 
			
		||||
            REM Optionally check for success and break the loop if succeeded
 | 
			
		||||
            REM This would depend on the output of BiosConfigUtility.exe indicating success
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
REM Cleanup
 | 
			
		||||
del "%EncryptedPasswordFile%"
 | 
			
		||||
 | 
			
		||||
endlocal
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ for /F "tokens=*" %%p in (%PasswordListFile%) do (
 | 
			
		|||
    "%HPQPswdPath%" /p"%%p" /f"%EncryptedPasswordFile%"
 | 
			
		||||
 | 
			
		||||
    REM Attempt to reset the BIOS password using the current password
 | 
			
		||||
    "%BiosConfigUtilityPath%" /cpwdfile:"%EncryptedPasswordFile%" /npwdfile:""
 | 
			
		||||
    "%BiosConfigUtilityPath%" /cpwdfile:"%EncryptedPasswordFile%" /nowdfile:""
 | 
			
		||||
    
 | 
			
		||||
    REM Optionally check for success and break the loop if succeeded
 | 
			
		||||
    REM This would depend on the output of BiosConfigUtility.exe indicating success
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue