529 lines
20 KiB
PowerShell
529 lines
20 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Tester - Automatic specification gathering, testing, and configuration tool.
|
|
|
|
.DESCRIPTION
|
|
Performs automated provisioning tasks including:
|
|
- Smart Windows Update with reboot resume
|
|
- GPU detection and discrete driver installation
|
|
- Hardware specification gathering
|
|
- OEM BIOS configuration (HP, Dell, Lenovo)
|
|
- BurnInTest automation
|
|
- Secure erase tooling
|
|
- Cleanup
|
|
|
|
.PARAMETER Help
|
|
Display usage information.
|
|
|
|
.PARAMETER LogFile
|
|
Path to a .log file for transcript logging.
|
|
|
|
.PARAMETER QROnly
|
|
Only retrieve system specifications as a QR code.
|
|
|
|
.PARAMETER BiosOnly
|
|
Only handle BIOS for Lenovo, HP, and Dell systems.
|
|
|
|
.PARAMETER TestOnly
|
|
Only install and run BurnInTest.
|
|
|
|
.PARAMETER EraseOnly
|
|
Only install and run the data eraser.
|
|
|
|
.PARAMETER Deprecated
|
|
Use handwritten specs like a pleb.
|
|
|
|
.NOTES
|
|
Author: Josh Ashton
|
|
Email: joshua.ashton@npsstore.com
|
|
Secondary Email: me@joshashton.dev
|
|
Last Modified: 2026-04-20
|
|
|
|
.CHANGELOG
|
|
v0.0.1 Initial version (HP BIOS)
|
|
v0.0.2 Added Dell BIOS, resolution, BurnInTest
|
|
v0.0.3 Fixed resolution bug, added cleanup
|
|
v0.0.4 Improved cleanup & logging
|
|
v0.0.5 Fixed Dell BIOS logic
|
|
v0.0.6 Logging improvements
|
|
v0.0.7 Lenovo BIOS password detection and GPU-aware Windows Update with reboot resume
|
|
v0.0.8 Added BiosOnly flag.
|
|
v0.0.9 Updated SpecOnly to SpecsOnly, and added DDR5 PartNumber to Specs.
|
|
v0.1.0 Updated Get-Drives to include drive power on hours.
|
|
v0.2.0 Data transfer to NPS computer via QR code and Google Chrome extension for auto-filling Pricer.
|
|
v0.2.1 Modified SpecsOnly flag to QROnly, added automatic chassis detection to include screen info.
|
|
v0.2.2 Feature removed - drive power on hours as it's generally N/A.
|
|
v0.2.3 Added output to console with device specs.
|
|
#>
|
|
|
|
param(
|
|
[switch]$Help,
|
|
[switch]$QROnly,
|
|
[switch]$BiosOnly,
|
|
[switch]$TestOnly,
|
|
[switch]$EraseOnly,
|
|
[switch]$Deprecated,
|
|
|
|
[ValidateScript({
|
|
if ($_ -notmatch "\.log$") {
|
|
throw "LogFile must be a .log file"
|
|
}
|
|
$true
|
|
})]
|
|
[System.IO.FileInfo]$LogFile = "C:\Users\Administrator\Desktop\nps.log"
|
|
)
|
|
|
|
# ==================================================
|
|
# Configuration
|
|
# ==================================================
|
|
$RegPath = "HKLM:\SOFTWARE\NPS\Provisioning"
|
|
$RegName = "WindowsUpdated"
|
|
|
|
# ==================================================
|
|
# Registry helpers
|
|
# ==================================================
|
|
function Get-UpdateFlag {
|
|
if (Test-Path $RegPath) {
|
|
(Get-ItemProperty -Path $RegPath -Name $RegName -ErrorAction SilentlyContinue).$RegName
|
|
}
|
|
}
|
|
|
|
function Set-UpdateFlag {
|
|
if (-not (Test-Path $RegPath)) {
|
|
New-Item -Path $RegPath -Force | Out-Null
|
|
}
|
|
Set-ItemProperty -Path $RegPath -Name $RegName -Value 1 -Type DWord
|
|
}
|
|
|
|
function Clear-UpdateFlag {
|
|
if (Test-Path $RegPath) {
|
|
Remove-Item -Path $RegPath -Recurse -Force
|
|
}
|
|
}
|
|
|
|
# ==================================================
|
|
# Windows Update
|
|
# ==================================================
|
|
function Update-Windows {
|
|
Install-Module PSWindowsUpdate -Force -Confirm:$false
|
|
Import-Module PSWindowsUpdate
|
|
Get-WindowsUpdate -MicrosoftUpdate -Install -AcceptAll -IgnoreReboot
|
|
|
|
Set-UpdateFlag
|
|
Restart-Computer -Force
|
|
exit
|
|
}
|
|
|
|
# ==================================================
|
|
# GPU handling
|
|
# ==================================================
|
|
function Install-Nvidia {
|
|
Invoke-WebRequest -Uri "https://us6-dl.techpowerup.com/files/9op87Lz6fZ9K3oUZLZlWxg/1769245820/NVCleanstall_1.19.0.exe" -Outfile "C:\Users\Administrator\Desktop\NVCleanstall.exe"
|
|
|
|
Start-Process "C:\Users\Administrator\Desktop\NVCleanstall.exe" -Wait
|
|
}
|
|
|
|
function Install-AMD {
|
|
|
|
}
|
|
|
|
function Handle-GPU {
|
|
$Adapters = @(Get-CimInstance Win32_VideoController |
|
|
Select-Object -ExpandProperty Name)
|
|
|
|
$Updated = Get-UpdateFlag
|
|
|
|
if (-not $Updated) {
|
|
if ($Adapters.Count -ge 1 -and
|
|
"Microsoft Basic Display Adapter" -In $Adapters) {
|
|
|
|
Write-Host "Basic Display Adapter detected. Running Windows Update."
|
|
Update-Windows
|
|
}
|
|
return
|
|
}
|
|
|
|
if ($Updated -and $Adapters.Count -ge 2 -and ("Microsoft Basic Display Adapter" -In $Adapters)) {
|
|
Write-Host "Second adapter still Basic Display Adapter. Discrete GPU detected."
|
|
|
|
$GpuDevices = Get-PnpDevice -Class Display -Status OK
|
|
foreach ($gpu in $GpuDevices) {
|
|
$ids = (Get-PnpDeviceProperty `
|
|
-InstanceId $gpu.InstanceId `
|
|
-KeyName 'DEVPKEY_Device_HardwareIds' `
|
|
-ErrorAction SilentlyContinue).Data
|
|
|
|
if ($ids -match 'VEN_10DE') { Install-Nvidia }
|
|
elseif ($ids -match 'VEN_1002') { Write-Host "Automated installation of AMD Radeon Graphics drivers is not supported yet!" -ForegroundColor Yellow }
|
|
}
|
|
}
|
|
|
|
Clear-UpdateFlag
|
|
}
|
|
|
|
# ==================================================
|
|
# Specs
|
|
# ==================================================
|
|
function Get-RAM {
|
|
# Sum the capacity of all physical sticks to get the "Marketing" total
|
|
$PhysicalMem = Get-CimInstance Win32_PhysicalMemory
|
|
$RawSize = ($PhysicalMem | Measure-Object -Property Capacity -Sum).Sum
|
|
$Size = [Math]::Round($RawSize / 1GB)
|
|
|
|
# Get the first stick for metadata
|
|
$MemStick = $PhysicalMem | Select-Object -First 1
|
|
$Type = $MemStick.SMBIOSMemoryType
|
|
$PartNumber = $MemStick.PartNumber.Trim()
|
|
|
|
$TypeStr = switch ($Type) {
|
|
34 { "DDR5" }
|
|
26 { "DDR4" }
|
|
24 { "DDR3" }
|
|
default { "DDR" }
|
|
}
|
|
|
|
if ($TypeStr -eq "DDR5") {
|
|
return "$Size GB $TypeStr ($PartNumber)"
|
|
} else {
|
|
return "$Size GB $TypeStr"
|
|
}
|
|
}
|
|
|
|
function Get-CDDrive {
|
|
$cd = Get-CimInstance Win32_CDROMDrive
|
|
if (-not $cd) { "---" }
|
|
elseif ($cd.CanWrite) { "Read/Write" }
|
|
else { "Read-only" }
|
|
}
|
|
|
|
function Get-Drives {
|
|
$PhysicalDisks = Get-PhysicalDisk | Where-Object { $_.BusType -ne 'USB' } |
|
|
Select-Object DeviceId, SerialNumber, BusType, MediaType, Size
|
|
|
|
return $PhysicalDisks | Select-Object `
|
|
DeviceId,
|
|
BusType,
|
|
MediaType,
|
|
@{Name="Size"; Expression={
|
|
$rawGB = $_.Size / 1GB
|
|
if ($rawGB -gt 900 -and $rawGB -lt 1024) { 1000 }
|
|
elseif ($rawGB -gt 470 -and $rawGB -lt 512) { 512 }
|
|
elseif ($rawGB -gt 450 -and $rawGB -lt 500) { 500 }
|
|
elseif ($rawGB -gt 230 -and $rawGB -lt 256) { 256 }
|
|
elseif ($rawGB -gt 115 -and $rawGB -lt 128) { 128 }
|
|
elseif ($rawGB -gt 100 -and $rawGB -lt 115) { 128 }
|
|
else { [Math]::Round($rawGB) }
|
|
}}
|
|
}
|
|
|
|
function Get-Resolution {
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
$b = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
|
|
"$($b.Width)x$($b.Height)"
|
|
}
|
|
|
|
function Get-Specs {
|
|
Handle-GPU
|
|
|
|
$Model = (Get-CimInstance Win32_ComputerSystem).Model
|
|
$CPU = (Get-CimInstance Win32_Processor).Name
|
|
$RAM = Get-RAM
|
|
$CD = Get-CDDrive
|
|
$GPU = (Get-CimInstance Win32_VideoController | Select-Object -ExpandProperty Name) -join ", "
|
|
$OS = (Get-CimInstance Win32_OperatingSystem).Caption
|
|
$Res = Get-Resolution
|
|
$Drives = Get-Drives
|
|
|
|
Write-Host "`nSystem Information`n------------------" -ForegroundColor Cyan
|
|
Write-Host @"
|
|
Model: $Model
|
|
CPU: $CPU
|
|
RAM: $RAM
|
|
CD: $CD
|
|
GPU: $GPU
|
|
OS: $OS
|
|
Resolution: $Res
|
|
Drives:
|
|
"@
|
|
|
|
$Drives | Format-Table -AutoSize
|
|
}
|
|
|
|
# ==================================================
|
|
# BIOS handling
|
|
# ==================================================
|
|
function Handle-BIOS {
|
|
Write-Host "Configuring BIOS ..." -ForegroundColor Yellow
|
|
$Maker = (Get-CimInstance Win32_ComputerSystem).Manufacturer
|
|
|
|
switch ($Maker) {
|
|
|
|
"HP" {
|
|
Invoke-WebRequest -Uri "https://hpia.hpcloud.hp.com/downloads/cmsl/hp-cmsl-1.8.5.exe" `
|
|
-OutFile "C:\Users\Administrator\Desktop\hp.exe"
|
|
|
|
Start-Process "C:\Users\Administrator\Desktop\hp.exe" -Wait
|
|
$env:Path += "C:\Program Files\WindowsPowerShell\Scripts\HP.ClientScriptLibrary;"
|
|
|
|
if ((Get-HPBIOSSetupPasswordIsSet) -eq $false) {
|
|
if ((Get-HPBIOSSetting -Name "Absolute Persistence Module Current State").Active -ne $false) {
|
|
Set-HPBIOSSettingValue -Name "Permanent Disable Absolute Persistence Module Set Once" -Value "Yes"
|
|
Write-Host "Absolute Persistence Module disabled." -ForegroundColor Green
|
|
}
|
|
}
|
|
else { Write-Host "BIOS Admin and/or System password is set and cannot disable BIOS tracking! Attempt to clear password with hardware pins and reboot." -ForegroundColor Red }
|
|
}
|
|
|
|
"Dell Inc." {
|
|
Install-Module DellBIOSProvider -Force
|
|
Import-Module DellBIOSProvider
|
|
|
|
if ((Get-Item DellSmbios:\Security\IsAdminPasswordSet) -and
|
|
(Get-Item DellSmbios:\Security\IsSystemPasswordSet)) {
|
|
|
|
Set-Item DellSmbios:\Security\Absolute "PermanentlyDisabled"
|
|
Write-Host "Dell Absolute disabled." -ForegroundColor Green
|
|
}
|
|
else { Write-Host "BIOS Admin and/or System password is set and cannot disable BIOS tracking! Attempt to clear password with hardware pins and reboot." -ForegroundColor Red }
|
|
}
|
|
|
|
"Lenovo" {
|
|
$PasswordState = (Get-WmiObject -Namespace root\wmi -Class Lenovo_BiosPasswordSettings).PasswordState
|
|
|
|
switch ($PasswordState) {
|
|
0 { Write-Host "No BIOS passwords are set! Enter BIOS settings manually to permanently disable Computrace/Absolute BIOS tracking." -ForegroundColor Green }
|
|
1 { Write-Host "Power on Password is set! How did we get here ... Attempt to manually clear password with hardware pins." -ForegroundColor Red }
|
|
2 { Write-Host "Supervisor password is set! Attempt to manually clear password with hardware pins." -ForegroundColor Red }
|
|
3 { Write-Host "Power on and supervisor passwords are set! How did we get here ... Attempt to manually clear passwords with hardware pins." -ForegroundColor Red }
|
|
4 { Write-Host "Hard drive password is set! How did we get here ... Replace the hard drive." -ForegroundColor Red }
|
|
5 { Write-Host "Power on and hard drive passwords are set! Really, how did we get here? ... Attempt to manually clear password with hardware pins and replace the hard drive." -ForegroundColor Red }
|
|
6 { Write-Host "Supervisor and hard drive passwords are set! How did we get here ... Attempt to manually clear password with hardware pins and replace the hard drive." -ForegroundColor Red }
|
|
7 { Write-Host "Supervisor, power on, and hard drive passwords are set! Really, how did we get here? I'm in agony ... Attempt to manually clear password with hardware pins and replace the hard drive." -ForegroundColor Red }
|
|
64 { Write-Host "System management password is set! Attempt to manually clear password with hardware pins, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
65 { Write-Host "System management and power on passwords are set! How did we get here ... Attempt to manually clear password with hardware pins, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
66 { Write-Host "System management and supervisor passwords are set! Execute Order 66 ... Attempt to manually clear password with hardware pins, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
67 { Write-Host "System management, supervisor, and power on passwords are set! Really, how did we get here? I'm in agony ... Attempt to manually clear passwords with hardware pins and replace the hard drive, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
68 { Write-Host "System management and hard drive passwords are set! How did we get here ... Attempt to manually clear password with hardware pins and replace the hard drive, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
69 { Write-Host "System management, power on, and hard drive passwords are set! Nice code. How did we get here ... Attempt to manually clear password with hardware pins and replace the hard drive, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
70 { Write-Host "System management, supervisor, and hard drive passwords are set! How did we get here ... Attempt to manually clear passwords with hardware pins and replace the hard drive, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
71 { Write-Host "System management, supervisor, power on, and hard drive passwords are set! Really, how did we get here? I'm in agony ... Attempt to manually clear passwords with hardware pins and replace the hard drive, but it probably won't work ... PAIN" -ForegroundColor Red }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# ==================================================
|
|
# BurnInTest / Eraser / Cleanup
|
|
# ==================================================
|
|
function Start-BurnInTest {
|
|
Write-Host "Installing BurnInTest ..." -ForegroundColor Yellow
|
|
Start-Process ".\BurnInTest_Windows_x86-64.exe" -Wait
|
|
|
|
Write-Host "Running BurnInTest, press continue in the pop-up ..." -ForegroundColor Yellow
|
|
Start-Process "C:\Program Files\BurnInTest\bit.exe" -ArgumentList "-R","-C",".\config.bitcfg" -Wait
|
|
}
|
|
|
|
function Start-Eraser {
|
|
Write-Host "Installing Eraser ..." -ForegroundColor Yellow
|
|
Start-Process ".\Eraser 6.2.0.2970.exe" -Wait
|
|
|
|
Write-Host "Running Eraser. Once completed, exit through the System Tray." -ForegroundColor Yellow
|
|
Start-Process "C:\Program Files\Eraser\Eraser.exe" -Wait
|
|
}
|
|
|
|
function Cleanup {
|
|
Write-Host "Cleaning up..." -ForegroundColor Yellow
|
|
$Maker = (Get-CimInstance Win32_ComputerSystem).Manufacturer
|
|
|
|
switch ($Maker) {
|
|
"HP" {
|
|
Remove-Item -Path "C:\Users\Administrator\Desktop\hp.exe"
|
|
}
|
|
"Dell Inc." {}
|
|
"Lenovo" {}
|
|
}
|
|
|
|
Remove-Item -Recurse -Path "C:\Program Files\Eraser"
|
|
|
|
Start-Process -FilePath "C:\Program Files\BurnInTest\unins000.exe" -Wait
|
|
|
|
Write-Host "Cleanup complete!" -ForegroundColor Green
|
|
}
|
|
|
|
# ==================================================
|
|
# Help
|
|
# ==================================================
|
|
function Help {
|
|
Write-Host @"
|
|
Tester - Automatic specification gathering, testing, and configuration tool.
|
|
|
|
Usage:
|
|
tester.ps1
|
|
tester.ps1 -Help
|
|
tester.ps1 -QROnly
|
|
tester.ps1 -BiosOnly
|
|
tester.ps1 -TestOnly
|
|
tester.ps1 -EraseOnly
|
|
"@ -ForegroundColor Green
|
|
}
|
|
|
|
# ==================================================
|
|
# User Inputs
|
|
# ==================================================
|
|
function Get-UserInputs {
|
|
Write-Host "`n--- Condition & Type Entry ---" -ForegroundColor Yellow
|
|
|
|
$ChassisMap = @{
|
|
"1" = "Other"
|
|
"2" = "Unknown"
|
|
"3" = "Desktop"
|
|
"4" = "Low Profile Desktop"
|
|
"5" = "Pizza Box"
|
|
"6" = "Mini Tower"
|
|
"7" = "Tower"
|
|
"8" = "Portable"
|
|
"9" = "Laptop"
|
|
"10" = "Notebook"
|
|
"11" = "Handheld"
|
|
"12" = "Docking Station"
|
|
"13" = "All-in-One"
|
|
"14" = "Sub-Notebook"
|
|
"15" = "Space-Saving"
|
|
"16" = "Lunch box"
|
|
"17" = "Main System Chassis"
|
|
"18" = "Expansion Chassis"
|
|
"19" = "SubChassis"
|
|
"20" = "Bus Expansion Chassis"
|
|
"21" = "Peripheral Chassis"
|
|
"22" = "Storage Chassis"
|
|
"23" = "Rack Mount Chassis"
|
|
"24" = "Sealed-Case"
|
|
"30" = "Tablet"
|
|
"31" = "Convertible"
|
|
"32" = "Detachable"
|
|
}
|
|
|
|
$ChassisCode = (Get-CimInstance -ClassName Win32_SystemEnclosure).ChassisTypes
|
|
$Screen = $null
|
|
|
|
# 1. Device Type
|
|
if ($ChassisCode -match "1|2|5|12|15|16|17|18|19|20|21|24") {
|
|
$Chassis = Read-Host "Ambiguous chassis code, please enter PC type (ie. laptop, tower, etc.):"
|
|
} else {
|
|
$Chassis = $ChassisMap["$ChassisCode"]
|
|
}
|
|
|
|
|
|
if ($ChassisCode -match "8|9|10|11|13|30|31|32" -OR $Chassis -match "laptop|Laptop|All-in-One|AIO") {
|
|
$MonitorParams = Get-CimInstance -Namespace "root\wmi" -ClassName WmiMonitorBasicDisplayParams | Where-Object { $_.InstanceName -eq $InternalMonitor.InstanceName }
|
|
$WidthCM = $MonitorParams.MaxHorizontalImageSize
|
|
$HeightCM = $MonitorParams.MaxVerticalImageSize
|
|
|
|
if ($WidthCM -gt 0) {
|
|
$DiagonalInches = [Math]::Round(([Math]::Sqrt([Math]::Pow($WidthCM, 2) + [Math]::Pow($HeightCM, 2)) / 2.54), 1)
|
|
$Res = Get-Resolution
|
|
|
|
$Screen = "$($DiagonalInches)in @ $($Res), "
|
|
}
|
|
}
|
|
|
|
# 2. Condition Category
|
|
$Cats = @("New - 0%", "Used - 0%", "AS-IS - 40%", "New other (see details) - 0%")
|
|
for ($i=0; $i -lt $Cats.Count; $i++) { Write-Host "[$($i+1)] $($Cats[$i])" }
|
|
$catIdx = Read-Host "Select Condition Category"
|
|
$ConditionCat = $Cats[($catIdx-1)]
|
|
|
|
# 3. Description
|
|
$Description = Read-Host "Enter short condition description (e.g. Minor scratches on lid)"
|
|
|
|
return @{
|
|
Chassis = $Chassis
|
|
Screen = $Screen
|
|
Cat = $ConditionCat
|
|
Desc = $Description
|
|
}
|
|
}
|
|
|
|
function Generate-CompressedJson {
|
|
# 1. Gather raw data from your existing functions
|
|
$Inputs = Get-UserInputs # The custom prompts we built
|
|
$Model = (Get-CimInstance Win32_ComputerSystem).Model
|
|
$Brand = (Get-CimInstance Win32_ComputerSystem).Manufacturer.Split(' ')[0] # Gets "Dell" from "Dell Inc."
|
|
$CPU = (Get-CimInstance Win32_Processor).Name.Trim()
|
|
$RAM = Get-RAM
|
|
$OS = (Get-CimInstance Win32_OperatingSystem).Caption -replace "Microsoft ", ""
|
|
$Serial = (Get-CimInstance Win32_Bios).SerialNumber
|
|
|
|
if ($Serial -eq "Default string") { $Serial = "" }
|
|
|
|
# 2. Process Drives & Optical
|
|
$DriveList = Get-Drives
|
|
$DriveStr = ($DriveList | ForEach-Object { "$($_.Size)GB $($_.BusType) $($_.MediaType)" }) -join ", "
|
|
|
|
$CD = Get-CDDrive
|
|
$OptStr = if ($CD -ne "---") { ", $CD Optical Drive" } else { "" }
|
|
|
|
# 3. Process GPUs
|
|
$GPUList = Get-CimInstance Win32_VideoController | Select-Object -ExpandProperty Name
|
|
if ($GPUList.Count -gt 1) {
|
|
$GPUStr = $GPUList -join " & "
|
|
} else {
|
|
$GPUStr = $GPUList
|
|
}
|
|
|
|
# 4. Construct the Master Description String
|
|
# Format: Type (CPU, RAM, Drives, Optical, GPUs, OS)
|
|
$FullDescription = "$($Inputs.Chassis) PC ($($Inputs.Screen)$CPU, $RAM, $DriveStr$OptStr, $GPUStr, $OS)"
|
|
|
|
# 5. Build Final JSON Object
|
|
$FinalObj = @{
|
|
"b" = $Brand.ToUpper() # Brand
|
|
"d" = $FullDescription # Description
|
|
"c" = $Inputs.Cat # Condition
|
|
"n" = $Inputs.Desc # Notes
|
|
"s" = $Model # Style
|
|
"e" = $Serial # Serial
|
|
}
|
|
|
|
Write-Host $($FinalObj | ConvertTo-Json)
|
|
|
|
$Json = $FinalObj | ConvertTo-Json -Compress
|
|
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($Json)
|
|
return [Convert]::ToBase64String($Bytes)
|
|
}
|
|
|
|
function Show-QR-Local {
|
|
$Data = Generate-CompressedJson
|
|
|
|
$OutPath = "$env:TEMP\specs_qr.png"
|
|
# $PSScriptRoot points to the folder where the script is running (your USB)
|
|
$ExePath = Join-Path $PSScriptRoot "qrencode.exe"
|
|
|
|
if (Test-Path $ExePath) {
|
|
# -s 10: Pixel size (makes it large/readable)
|
|
# -m 2: Margin size
|
|
# -l H: High error correction (good for scanning off screens)
|
|
& $ExePath -o $OutPath -s 10 -m 2 -l H "$Data"
|
|
|
|
winget install photos
|
|
Start-Process $OutPath
|
|
} else {
|
|
Write-Host "Local QR Tool not found at $ExePath" -ForegroundColor Red
|
|
}
|
|
}
|
|
|
|
# ==================================================
|
|
# Entry point
|
|
# ==================================================
|
|
Start-Transcript -Path $LogFile -Append
|
|
|
|
if ($Help) { Help }
|
|
elseif ($QROnly) { Show-QR-Local }
|
|
elseif ($BiosOnly) { Handle-BIOS }
|
|
elseif ($TestOnly) { Start-BurnInTest }
|
|
elseif ($EraseOnly) { Start-Eraser }
|
|
elseif ($Deprecated) { Get-Specs; Handle-BIOS; Start-BurnInTest; Start-Eraser; Cleanup }
|
|
else { Handle-GPU; Handle-BIOS; Start-BurnInTest; Start-Eraser; Cleanup; Show-QR-Local }
|
|
|
|
Stop-Transcript
|