PortValhalla/scripts/Windows/Scripts/PowerManagement.ps1
2024-10-06 21:25:34 +02:00

253 lines
6.8 KiB
PowerShell

using namespace Microsoft.Win32;
$null = New-Module {
. "$PSScriptRoot/../Scripts/Registry.ps1";
. "$PSScriptRoot/../../Common/Scripts/Scripting.ps1";
[RegistryKey] $key = $null;
$runOncePath = "Software\Microsoft\Windows\CurrentVersion\RunOnce";
$systemRunOncePath = "HKLM:\$runOncePath";
$logonPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$runOnceName = "PortValhalla";
$powerSchemeOption = "PowerScheme";
$autologinOption = "AutoAdminLogon";
$domainOption = "DefaultDomainName";
$userOption = "DefaultUserName";
$passwordOption = "DefaultPassword";
<#
.SYNOPSIS
Gets the reghistry key containing the `RunOnce` commands.
.PARAMETER UserKey
The key of the user to get the `RunOnce` key for.
#>
function Get-RunOnceKey {
param(
[RegistryKey] $UserKey
)
[string] $path = $null;
if ($UserKey) {
$path = Join-Path ($UserKey.PSPath) $runOncePath;
}
else {
$path = $systemRunOncePath;
}
if (-not (Test-Path $path)) {
New-Item $path;
}
else {
Get-Item $path;
}
}
<#
.SYNOPSIS
Generates a script for executing the installer.
#>
function Get-StartupScript {
"pwsh -Command " + (Get-StartupCommand);
}
<#
.SYNOPSIS
Generates a command for running the installer using `pwsh`.
#>
function Get-StartupCommand {
($env:DEBUG ? "`$env:DEBUG = $([int]$env:DEBUG);" : "") +
($env:VALHALLA_ROOT ? "`$env:VALHALLA_ROOT = $(ConvertTo-Injection $env:VALHALLA_ROOT);" : "") +
($env:PWSH_PATH ? "`$env:PWSH_PATH = $(ConvertTo-Injection $env:PWSH_PATH);" : "") +
($env:BACKUP_ARCHIVE ? "`$env:BACKUP_ARCHIVE = $(ConvertTo-Injection ([System.IO.Path]::GetFullPath($env:BACKUP_ARCHIVE)));" : "") +
"`$env:INSTALLER_SCRIPT = $(ConvertTo-Injection (Resolve-Path $env:INSTALLER_SCRIPT));" +
"`$env:CONFIG_NAME = $(ConvertTo-Injection $env:CONFIG_NAME);" +
"& `$env:INSTALLER_SCRIPT;";
}
<#
.SYNOPSIS
Gets the GUID of the current power scheme.
#>
function Get-PowerScheme {
[regex]::Match((powercfg /GETACTIVESCHEME), "Power Scheme GUID: ([0-9a-f-]+) ").Groups[1].Value;
}
<#
.SYNOPSIS
Sets the current power scheme.
.PARAMETER SchemeID
The ID of the scheme to set.
#>
function Set-PowerScheme {
param(
[string] $SchemeID
)
powercfg /S $SchemeID;
}
<#
.SYNOPSIS
Backs up and overrides the current power scheme if it might cause automatic standby.
#>
function Backup-PowerScheme {
$performanceScheme = "8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c";
$currentScheme = Get-PowerScheme;
if ($currentScheme -ne $performanceScheme) {
Write-Host "Disabling Power Save mode";
Set-SetupOption $powerSchemeOption $currentScheme;
powercfg /S $performanceScheme;
}
}
<#
.SYNOPSIS
Restores the backed up power scheme.
#>
function Restore-PowerScheme {
$scheme = Get-SetupOption $powerSchemeOption;
if ($scheme) {
powercfg /S $scheme;
}
}
<#
.SYNOPSIS
Registers a task to run the setup once after the next reboot.
.PARAMETER UserKey
The regtistry key of the user to register the task for.
#>
function Register-Setup {
param(
[Parameter(ParameterSetName = "System")]
[switch] $System,
[Parameter(ParameterSetName = "DefaultUser", Mandatory)]
[switch] $DefaultUser,
[Parameter(ParameterSetName = "User", Mandatory)]
[switch] $User,
[Parameter(ParameterSetName = "User")]
[Parameter(ParameterSetName = "SpecificUser", Mandatory)]
[RegistryKey] $UserKey
)
if ($DefaultUser.IsPresent) {
Edit-DefaultUserKey {
param(
[RegistryKey] $Key
)
Register-Setup -UserKey $Key;
}
return;
}
if ($User.IsPresent -or $UserKey) {
if (-not $UserKey) {
$UserKey = Get-Item "HKCU:\";
}
$key = Get-RunOnceKey $UserKey;
}
else {
$key = Get-RunOnceKey;
}
Set-ItemProperty -Path $key.PSPath -Name $runOnceName -Type "ExpandString" -Value (Get-StartupScript);
$key.Handle.Close();
}
<#
.SYNOPSIS
Clears leftovers from past registrations.
#>
function Clear-SetupRegistration {
Edit-DefaultUserKey {
param(
[RegistryKey] $Key
)
$runOnceKey = Get-RunOnceKey $Key;
Remove-Item $runOnceKey.PSPath;
}
}
<#
.SYNOPSIS
Sets the user to login automatically on boot.
.PARAMETER Name
The name of the user to login automatically.
#>
function Set-AutologinUser {
param(
[string] $Name
)
Set-ItemProperty $logonPath -Name $autologinOption "1";
if (-not $Name) {
$Name = Get-SetupUser;
}
$options = @{
$domainOption = "";
$userOption = $Name;
$passwordOption = "";
};
foreach ($key in $options.Keys) {
Set-ItemProperty $logonPath -Name $key -Value $options[$key];
}
}
<#
.SYNOPSIS
Disables the automatic login.
#>
function Disable-Autologin {
Set-ItemProperty $logonPath -Name $autologinOption "0";
foreach ($key in @($domainOption, $userOption, $passwordOption)) {
Remove-ItemProperty $logonPath -Name $key -ErrorAction SilentlyContinue;
}
}
<#
.SYNOPSIS
Reboots the machine intermediately and restarts the setup after the next login.
#>
function Restart-Intermediate {
param(
[Parameter(ParameterSetName = "None")]
[switch] $NoRegister,
[Parameter(ParameterSetName = "Default", Mandatory)]
[switch] $DefaultUser,
[Parameter(ParameterSetName = "Current", Mandatory)]
[switch] $CurrentUser
)
if (-not $NoRegister.IsPresent) {
if ($DefaultUser.IsPresent) {
Register-Setup -DefaultUser;
}
elseif ($CurrentUser.IsPresent) {
Register-Setup -User;
}
else {
Register-Setup;
}
}
if ($env:DEBUG -and (-not $Global:NonInteractive)) {
Read-Host "Press enter to reboot";
}
Restart-Computer -Force;
}
}