From 438c0b1cdf27e4ab3bbb93b550418624503ebab9 Mon Sep 17 00:00:00 2001 From: Manuel Thalmann Date: Tue, 10 Sep 2024 00:37:13 +0200 Subject: [PATCH] Add a script for creating backups --- scripts/Common/Scripts/Config.ps1 | 41 ++++++++++++ scripts/Windows/OS/Backup.ps1 | 4 ++ scripts/Windows/OS/Manage.ps1 | 74 ++++++++++++++++++++- scripts/Windows/Scripts/PowerManagement.ps1 | 2 +- 4 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 scripts/Windows/OS/Backup.ps1 diff --git a/scripts/Common/Scripts/Config.ps1 b/scripts/Common/Scripts/Config.ps1 index 99ac893c..7a94d744 100644 --- a/scripts/Common/Scripts/Config.ps1 +++ b/scripts/Common/Scripts/Config.ps1 @@ -11,11 +11,18 @@ enum WindowsInstallerStage { } enum SetupStage { + Initialize Configure Install CreateUser } +enum BackupStage { + Initialize + Backup + BackupUsers +} + enum UserStage { Create Configure @@ -27,6 +34,7 @@ $null = New-Module { [string] $configRoot = "HKLM:\Software\PortValhalla"; [string] $stageOption = "Stage"; [string] $setupStageOption = "SetupStage"; + [string] $backupStageOption = "BackupStage"; [string] $userOption = "SetupUser"; [string] $userStageOption = "UserStage"; [string] $accountOption = "MSAccount"; @@ -408,6 +416,39 @@ $null = New-Module { $null = Set-SetupOption $setupStageOption $Name; } + <# + .SYNOPSIS + Gets the name of the current stage of the backup. + #> + function Get-BackupStage { + $stage = Get-SetupOption $backupStageOption; + + if ($null -ne $stage) { + $stage = [BackupStage]$stage; + } + + return $stage; + } + + <# + .SYNOPSIS + Sets the current stage of the backup. + + .PARAMETER Name + The name to set the current stage to. + #> + function Set-BackupStage { + param( + $Name + ) + + if (-not (($null -eq $Name) -or ($Name -is [string]))) { + $Name = ([BackupStage]$Name).ToString(); + } + + $null = Set-SetupOption $backupStageOption $Name; + } + <# .SYNOPSIS Gets the current user to set up. diff --git a/scripts/Windows/OS/Backup.ps1 b/scripts/Windows/OS/Backup.ps1 new file mode 100644 index 00000000..c581b3dc --- /dev/null +++ b/scripts/Windows/OS/Backup.ps1 @@ -0,0 +1,4 @@ +#!/bin/pwsh +. "$PSScriptRoot/Manage.ps1"; +$env:INSTALLER_SCRIPT = "$PSCommandPath"; +Start-WindowsBackup; diff --git a/scripts/Windows/OS/Manage.ps1 b/scripts/Windows/OS/Manage.ps1 index 99baf196..daa41156 100644 --- a/scripts/Windows/OS/Manage.ps1 +++ b/scripts/Windows/OS/Manage.ps1 @@ -36,6 +36,16 @@ $null = New-Module { }; } + <# + .SYNOPSIS + Creates a backup of the current Windows machine. + #> + function Start-WindowsBackup { + Start-Operation -NoImplicitCleanup { + Start-InstallationLoop ([WindowsInstallerAction]::Backup); + }; + } + <# .SYNOPSIS Starts the installation loop. @@ -87,9 +97,12 @@ $null = New-Module { switch (Get-SetupStage) { ($null) { - Set-SetupStage ([SetupStage]::Configure); + Set-SetupStage ([SetupStage]::Initialize); break; } + ([SetupStage]::Initialize) { + Set-SetupStage ([SetupStage]::Configure); + } ([SetupStage]::Configure) { if (Get-Config "valhalla.windows.dualboot.enable") { if (-not (Test-Qemu)) { @@ -129,6 +142,65 @@ $null = New-Module { } } } + ([WindowsInstallerAction]::Backup) { + $finished = $false; + $setupUser = Get-SetupUser; + + $adminGroup = @{ + SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null); + }; + + while (-not $finished) { + switch (Get-BackupStage) { + $null { + Set-BackupStage ([BackupStage]::Initialize); + } + ([BackupStage]::Initialize) { + $null = New-LocalUser $setupUser -NoPassword; + Set-LocalUser $setupUser -PasswordNeverExpires $true; + Set-LocalUser $setupUser -PasswordNeverExpires $false; + Add-LocalGroupMember -Member $setupUser @adminGroup; + Set-AutologinUser $setupUser; + Disable-UAC; + Set-BackupStage ([BackupStage]::Backup); + Restart-Intermediate; + return; + } + ([BackupStage]::Backup) { + Deploy-SoftwareAction ([InstallerAction]::Backup); + Set-BackupStage ([BackupStage]::BackupUsers); + } + ([BackupStage]::BackupUsers) { + $users = @(Get-Users); + $i = Get-CurrentUser; + Disable-LocalUser $setupUser; + + for (; $i -lt $users.Count; $i++) { + Set-CurrentUser $i; + $user = $users[$i]; + + if ($env:UserName -ne $user) { + Set-BootMessage "Please Log In" "Please log in with the user ``$user``"; + Add-LocalGroupMember -Member "$user" @adminGroup -ErrorAction SilentlyContinue; + Disable-Autologin; + Restart-Intermediate; + return; + } else { + Deploy-SoftwareAction -Action ([InstallerAction]::BackupUser); + Remove-LocalGroupMember -Member "$user" @adminGroup; + + foreach ($group in Get-UserConfig -UserName "$user" "groups") { + Add-LocalGroupMember -Member "$user" $group; + } + } + } + + Disable-BootMessage; + $finished = $true; + } + } + } + } } Set-Stage ([WindowsInstallerStage]::Cleanup); diff --git a/scripts/Windows/Scripts/PowerManagement.ps1 b/scripts/Windows/Scripts/PowerManagement.ps1 index f8872075..94f65a04 100644 --- a/scripts/Windows/Scripts/PowerManagement.ps1 +++ b/scripts/Windows/Scripts/PowerManagement.ps1 @@ -53,7 +53,7 @@ $null = New-Module { function Get-StartupCommand { ($env:PWSH_PATH ? "`$env:PWSH_PATH = $(ConvertTo-Injection $env:PWSH_PATH);" : "") + ($env:DEBUG ? "`$env:DEBUG = $([int]$env:DEBUG);" : "") + - ($env:BACKUP_ARCHIVE ? "`$env:BACKUP_ARCHIVE = $(ConvertTo-Injection (Resolve-Path $env:BACKUP_ARCHIVE));" : "") + + ($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;";