From 10848d104bb02fa3dc999cd2c6fe49daa71a3109 Mon Sep 17 00:00:00 2001 From: Manuel Thalmann Date: Wed, 28 Aug 2024 00:03:28 +0200 Subject: [PATCH] Make the install script action agnostic --- scripts/Common/Scripts/Config.ps1 | 46 ++++++- scripts/Windows/OS/Manage.ps1 | 114 +++++++++++------- .../Windows/Types/WindowsInstallerAction.ps1 | 4 + 3 files changed, 117 insertions(+), 47 deletions(-) create mode 100644 scripts/Windows/Types/WindowsInstallerAction.ps1 diff --git a/scripts/Common/Scripts/Config.ps1 b/scripts/Common/Scripts/Config.ps1 index cfcee7c2..aefedcd3 100644 --- a/scripts/Common/Scripts/Config.ps1 +++ b/scripts/Common/Scripts/Config.ps1 @@ -2,6 +2,12 @@ using namespace Microsoft.Win32; using namespace System.Security.AccessControl; using namespace System.Security.Principal; +enum WindowsInstallerStage { + Initialize + Run + Completed +} + enum SetupStage { Configure Install @@ -18,6 +24,7 @@ enum UserStage { $null = New-Module { [string] $configRoot = "HKLM:\Software\PortValhalla"; [string] $stageOption = "Stage"; + [string] $setupStageOption = "SetupStage"; [string] $userOption = "SetupUser"; [string] $userStageOption = "UserStage"; [string] $accountOption = "MSAccount"; @@ -272,11 +279,44 @@ $null = New-Module { <# .SYNOPSIS - Gets the name of the current setup stage. + Gets the name of the current stage of the Windows install script action. #> function Get-Stage { $stage = Get-SetupOption $stageOption; + if ($null -ne $stage) { + $stage = [WindowsInstallerStage]$stage; + } + + return $stage; + } + + <# + .SYNOPSIS + Sets the name of the current stage of the Windows install script action. + + .PARAMETER Name + The name of the stage to set. + #> + function Set-Stage { + param( + $Name + ) + + if (-not (($null -eq $Name) -or ($Name -is [string]))) { + $Name = ([WindowsInstallerStage]$Name).ToString(); + } + + $null = Set-SetupOption $stageOption $Name; + } + + <# + .SYNOPSIS + Gets the name of the current setup stage. + #> + function Get-SetupStage { + $stage = Get-SetupOption $setupStageOption; + if ($null -ne $stage) { $stage = [SetupStage]$stage; } @@ -291,7 +331,7 @@ $null = New-Module { .PARAMETER Name The name to set the current stage to. #> - function Set-Stage { + function Set-SetupStage { param( $Name ) @@ -300,7 +340,7 @@ $null = New-Module { $Name = ([SetupStage]$Name).ToString(); } - $null = Set-SetupOption $stageOption $Name; + $null = Set-SetupOption $setupStageOption $Name; } <# diff --git a/scripts/Windows/OS/Manage.ps1 b/scripts/Windows/OS/Manage.ps1 index 70225c6f..f7c117a6 100644 --- a/scripts/Windows/OS/Manage.ps1 +++ b/scripts/Windows/OS/Manage.ps1 @@ -17,6 +17,7 @@ $null = New-Module { . "$PSScriptRoot/../Scripts/Security.ps1"; . "$PSScriptRoot/../Scripts/Update.ps1"; . "$PSScriptRoot/../Scripts/Users.ps1"; + . "$PSScriptRoot/../Types/WindowsInstallerAction.ps1"; . "$PSScriptRoot/../../Common/Scripts/Config.ps1"; . "$PSScriptRoot/../../Common/Scripts/Operations.ps1"; . "$PSScriptRoot/../../Common/Scripts/Software.ps1"; @@ -29,7 +30,7 @@ $null = New-Module { #> function Start-WindowsInstallation { Start-Operation -NoImplicitCleanup { - Start-InstallationLoop; + Start-InstallationLoop ([WindowsInstallerAction]::Install); }; } @@ -38,60 +39,85 @@ $null = New-Module { Starts the installation loop. #> function Start-InstallationLoop { - while (-not (Get-IsFinished)) { - if (Test-Admin) { - $null = Import-Module PSWindowsUpdate; - - Invoke-Hook "Invoke-WindowsUpdate" -Fallback { - Update-WindowsInstallation; - }; - - if ((Get-WURebootStatus -Silent)) { - Restart-Intermediate; - return; - } - } + param( + [WindowsInstallerAction] $Action + ) + while ((Get-Stage) -ne ([WindowsInstallerStage]::Completed)) { switch (Get-Stage) { ($null) { - Set-Stage ([SetupStage]::Configure); + Set-Stage ([WindowsInstallerStage]::Initialize); break; } - ([SetupStage]::Configure) { - if (Get-Config "valhalla.windows.dualboot.enable") { - if (-not (Test-Qemu)) { - # Fix synchronization between Linux and Windows clocks. - Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Value 1 -Type "DWord"; - } + ([WindowsInstallerStage]::Initialize) { + Set-Stage ([WindowsInstallerStage]::Run); + break; + } + ([WindowsInstallerStage]::Run) { + switch ($Action) { + ([WindowsInstallerAction]::Install) { + while (-not (Get-IsFinished)) { + if (Test-Admin) { + $null = Import-Module PSWindowsUpdate; - # Force time resynchronization - $timeZoneOption = "Start"; - $timeZoneKey = "HKLM:\SYSTEM\CurrentControlSet\Services\tzautoupdate"; - $service = Get-Service W32Time; - $autoUpdate = (Get-Item $timeZoneKey).GetValue($timeZoneOption); - $stopped = ($service.Status -eq "Stopped"); + Invoke-Hook "Invoke-WindowsUpdate" -Fallback { + Update-WindowsInstallation; + }; - $setUpdate = { param([int] $Value) Set-ItemProperty $timeZoneKey -Name $timeZoneOption $Value }; - & $setUpdate 3; - Start-Service $service; - w32tm /resync /force; - & $setUpdate $autoUpdate; + if ((Get-WURebootStatus -Silent)) { + Restart-Intermediate; + return; + } + } - if ($stopped) { - Stop-Service $service; + switch (Get-SetupStage) { + ($null) { + Set-SetupStage ([SetupStage]::Configure); + break; + } + ([SetupStage]::Configure) { + if (Get-Config "valhalla.windows.dualboot.enable") { + if (-not (Test-Qemu)) { + # Fix synchronization between Linux and Windows clocks. + Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Value 1 -Type "DWord"; + } + + # Force time resynchronization + $timeZoneOption = "Start"; + $timeZoneKey = "HKLM:\SYSTEM\CurrentControlSet\Services\tzautoupdate"; + $service = Get-Service W32Time; + $autoUpdate = (Get-Item $timeZoneKey).GetValue($timeZoneOption); + $stopped = ($service.Status -eq "Stopped"); + + $setUpdate = { param([int] $Value) Set-ItemProperty $timeZoneKey -Name $timeZoneOption $Value }; + & $setUpdate 3; + Start-Service $service; + w32tm /resync /force; + & $setUpdate $autoUpdate; + + if ($stopped) { + Stop-Service $service; + } + } + + Set-SetupStage ([SetupStage]::Install); + } + ([SetupStage]::Install) { + Write-Host "Entering install phase"; + Deploy-SoftwareAction; + Set-SetupStage ([SetupStage]::CreateUser); + } + ([SetupStage]::CreateUser) { + Install-ValhallaUsers; + Set-IsFinished $true; + } + } + } } } - Set-Stage ([SetupStage]::Install); - } - ([SetupStage]::Install) { - Write-Host "Entering install phase"; - Deploy-SoftwareAction; - Set-Stage ([SetupStage]::CreateUser); - } - ([SetupStage]::CreateUser) { - Install-ValhallaUsers; - Set-IsFinished $true; + Set-Stage ([WindowsInstallerStage]::Completed); + break; } } } diff --git a/scripts/Windows/Types/WindowsInstallerAction.ps1 b/scripts/Windows/Types/WindowsInstallerAction.ps1 new file mode 100644 index 00000000..3cc3b9a0 --- /dev/null +++ b/scripts/Windows/Types/WindowsInstallerAction.ps1 @@ -0,0 +1,4 @@ +enum WindowsInstallerAction { + Backup + Install +}