From 1b0c7155146b29fc277e8571a19e8072167d689d Mon Sep 17 00:00:00 2001 From: Manuel Thalmann Date: Tue, 27 Aug 2024 04:15:37 +0200 Subject: [PATCH] Handle initialization in operation code --- scripts/Common/Scripts/Operations.ps1 | 174 ++++- scripts/Windows/OS/Install.ps1 | 994 +++++++++++--------------- 2 files changed, 583 insertions(+), 585 deletions(-) diff --git a/scripts/Common/Scripts/Operations.ps1 b/scripts/Common/Scripts/Operations.ps1 index ad264429..89a1b889 100644 --- a/scripts/Common/Scripts/Operations.ps1 +++ b/scripts/Common/Scripts/Operations.ps1 @@ -1,12 +1,16 @@ -. "$PSScriptRoot/Config.ps1"; +using namespace System.Management.Automation.Host; + . "$PSScriptRoot/../Types/OneShotTask.ps1"; -. "$PSScriptRoot/../../Windows/Scripts/PowerManagement.ps1"; -. "$PSScriptRoot/../../Windows/Scripts/Registry.ps1"; -. "$PSScriptRoot/../../Windows/Scripts/Security.ps1"; -. "$PSScriptRoot/../../Windows/Scripts/WSL.ps1"; $null = New-Module { + . "$PSScriptRoot/Config.ps1"; + . "$PSScriptRoot/../Scripts/SoftwareManagement.ps1"; . "$PSScriptRoot/../Types/OneShotTask.ps1"; + . "$PSScriptRoot/../../Windows/Scripts/Hooks.ps1"; + . "$PSScriptRoot/../../Windows/Scripts/PowerManagement.ps1"; + . "$PSScriptRoot/../../Windows/Scripts/Registry.ps1"; + . "$PSScriptRoot/../../Windows/Scripts/Security.ps1"; + . "$PSScriptRoot/../../Windows/Scripts/WSL.ps1"; $oneShotTaskName = "PortValhalla OneShot"; $logName = "Application"; $oneShotTrigger = 1337; @@ -59,6 +63,166 @@ $null = New-Module { Clear-OperationResources; }; } + + Set-Stage ((Get-Stage) ?? ([SetupStage]::Initialize)); + + & { + while ((Get-Stage) -eq ([SetupStage]::Initialize)) { + if ($IsWindows) { + if (-not ((Test-Command "choco") -and (Test-Command "refreshenv"))) { + Invoke-Hook "Install-Chocolatey" -Fallback { + # Install chocolatey + New-Item -Force $PROFILE; + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; + Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')); + Import-Module $env:ChocolateyInstall/helpers/chocolateyProfile.psm1; + refreshenv; + }; + + continue; + } + + if (-not (Test-ChocoPackage "powershell-core")) { + Invoke-Hook "Install-PowerShellCore" -Fallback { + choco install -y powershell-core --install-arguments='"ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 REGISTER_MANIFEST=1 USER_MU=1 ENABLE_MU=1"'; + }; + + Restart-Intermediate; + return; + } + + if ($env:PWSH_PATH -and (Test-Path $env:PWSH_PATH)) { + attrib "-R" "$env:PWSH_PATH\*" /S /D; + Remove-Item -Recurse -Force $env:PWSH_PATH; + continue; + } + + if ($env:DEBUG) { + if ( + (Get-Item $env:INSTALLER_SCRIPT).IsReadOnly -and + (Test-Qemu) -and + ($Host.UI.PromptForChoice( + "Confirm", + "Do you wish to swap to live scripts?", + [ChoiceDescription[]]@( + [ChoiceDescription]::new("&No", "Use scripts stored in the virtual machine"), + [ChoiceDescription]::new("&Yes", "Use live scripts stored on the host")), + 0) -eq 1)) { + Install-ChocoPackage winfsp qemu-guest-agent; + Get-Service VirtioFsSvc | Start-Service -PassThru | Set-Service -StartupType Automatic; + + while (-not (Test-Path Z:\)) { + Start-Sleep 0.1; + } + + foreach ($name in @("CONFIG_MODULE", "INSTALLER_SCRIPT")) { + $variable = Get-Item "Env:\$name"; + + $path = Join-Path ` + "Z:\Repositories\PortValhalla" ` + ([System.IO.Path]::GetRelativePath("$PSScriptRoot/../../..", $variable.Value)); + + Set-Item "Env:\$name" $path; + Write-Host "The new value of ``$name`` is ``$path``"; + } + + Restart-Intermediate; + exit; + } + } + + if (-not (Test-Command "gsudo")) { + Install-ChocoPackage gsudo; + refreshenv; + continue; + } + + if ($env:DEBUG) { + & { + $sys32 = "$env:WINDIR/System32"; + $osk = (Get-Item "$sys32/osk.exe").FullName; + $cmd = (Get-Item "$sys32/cmd.exe").FullName; + $tmpOsk = New-TemporaryFile; + $tmpCmd = New-TemporaryFile; + gsudo -d copy "$osk" "$tmpOsk"; + gsudo -d copy "$cmd" "$tmpCmd"; + + if ((Get-FileHash $tmpOsk).Hash -ne (Get-FileHash $tmpCmd).Hash) { + Set-MpPreference -ExclusionPath $osk; + gsudo -d --ti move $osk "${osk}_"; + gsudo -d -s copy $cmd $osk; + continue; + } + }; + } + + if (-not (Test-Winget)) { + . "$PSScriptRoot/../../Windows/Software/winget/Manage.ps1"; + continue; + } + + if (-not (Test-Command "git")) { + Install-WingetPackage Git.Git; + refreshenv; + continue; + } + + if (-not (Test-Wsl)) { + Install-Wsl; + Restart-Intermediate; + return; + } + + if (-not (Test-WslDistributions)) { + Install-WslDistribution; + continue; + } + + if (-not (wsl --shell-type login type -t nix)) { + wsl -- sh `<`(curl -L https://nixos.org/nix/install`) --daemon --yes; + wsl --shutdown; + continue; + } + + Invoke-Hook "Install-PSModules" -Fallback { + $modules = @( + @("KnownFolders"), + @("PSWindowsUpdate"), + @("PSScriptAnalyzer"), + @("LocalAccounts", $true), + @("NuGet") + ); + + foreach ($module in $modules) { + $parameters = @{ }; + + if ($module[1]) { + $parameters = @{ + allowPrerelease = $true; + }; + } + + if (-not (Test-PSModule $module[0])) { + Install-Module -Scope AllUsers -AcceptLicense -Force -AllowClobber $module[0] @parameters; + Import-Module $module[0]; + } + } + + . "$PSScriptRoot/../../Windows/Software/PinnedItem/Manage.ps1"; + }; + + if (-not (Test-PSPackage Selenium.WebDriver)) { + Write-Host "Installing browser automation tools…"; + $null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies; + continue; + } + + Install-ChocoPackage selenium-gecko-driver firefox; + Install-WingetPackage AutoHotkey.AutoHotkey; + Set-Stage ([SetupStage]::Configure); + } + } + } } & $Action; diff --git a/scripts/Windows/OS/Install.ps1 b/scripts/Windows/OS/Install.ps1 index f1a6e0b2..26d243e2 100644 --- a/scripts/Windows/OS/Install.ps1 +++ b/scripts/Windows/OS/Install.ps1 @@ -1,5 +1,4 @@ #!/bin/pwsh -using namespace System.Management.Automation.Host; using namespace System.Security.Principal; . "$PSScriptRoot/../Scripts/Prerequisites.ps1"; @@ -42,615 +41,450 @@ $null = New-Module { #> function Start-InstallationLoop { while (-not (Get-IsFinished)) { + if (-not (Test-Wsl)) { + Register-WslDistribution; + } + switch (Get-Stage) { - ($null) { - Set-Stage ([SetupStage]::Initialize); - break; - } - ([SetupStage]::Initialize) { - if (-not ((Test-Command "choco") -and (Test-Command "refreshenv"))) { - Invoke-Hook "Install-Chocolatey" -Fallback { - # Install chocolatey - New-Item -Force $PROFILE; - [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; - Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')); - Import-Module $env:ChocolateyInstall/helpers/chocolateyProfile.psm1; - refreshenv; - }; + ([SetupStage]::OneShot) { + Write-Host "Running OneShot task ``$(Get-OneShotTask)``"; - continue; - } - - - if (-not (Test-ChocoPackage "powershell-core")) { - Invoke-Hook "Install-PowerShellCore" -Fallback { - choco install -y powershell-core --install-arguments='"ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 REGISTER_MANIFEST=1 USER_MU=1 ENABLE_MU=1"'; - }; - - Restart-Intermediate; - return; - } - - if ($env:PWSH_PATH -and (Test-Path $env:PWSH_PATH)) { - attrib "-R" "$env:PWSH_PATH\*" /S /D; - Remove-Item -Recurse -Force $env:PWSH_PATH; - continue; - } - - if ($env:DEBUG) { - if ( - (Get-Item $env:INSTALLER_SCRIPT).IsReadOnly -and - (Test-Qemu) -and - ($Host.UI.PromptForChoice( - "Confirm", - "Do you wish to swap to live scripts?", - [ChoiceDescription[]]@( - [ChoiceDescription]::new("&No", "Use scripts stored in the virtual machine"), - [ChoiceDescription]::new("&Yes", "Use live scripts stored on the host")), - 0) -eq 1)) { - Install-ChocoPackage winfsp qemu-guest-agent; - Get-Service VirtioFsSvc | Start-Service -PassThru | Set-Service -StartupType Automatic; - - while (-not (Test-Path Z:\)) { - Start-Sleep 0.1; + Start-OneShot { + switch (Get-OneShotTask) { + ([OneShotTask]::InitializeMSAccount) { + Initialize-UserCreation; } - - foreach ($name in @("CONFIG_MODULE", "INSTALLER_SCRIPT")) { - $variable = Get-Item "Env:\$name"; - - $path = Join-Path ` - "Z:\Repositories\PortValhalla" ` - ([System.IO.Path]::GetRelativePath("$PSScriptRoot/../../..", $variable.Value)); - - Set-Item "Env:\$name" $path; - Write-Host "The new value of ``$name`` is ``$path``"; - } - - Restart-Intermediate; - exit; - } - } - - if (-not (Test-Command "gsudo")) { - Install-ChocoPackage gsudo; - refreshenv; - continue; - } - - if ($env:DEBUG) { - & { - $sys32 = "$env:WINDIR/System32"; - $osk = (Get-Item "$sys32/osk.exe").FullName; - $cmd = (Get-Item "$sys32/cmd.exe").FullName; - $tmpOsk = New-TemporaryFile; - $tmpCmd = New-TemporaryFile; - gsudo -d copy "$osk" "$tmpOsk"; - gsudo -d copy "$cmd" "$tmpCmd"; - - if ((Get-FileHash $tmpOsk).Hash -ne (Get-FileHash $tmpCmd).Hash) { - Set-MpPreference -ExclusionPath $osk; - gsudo -d --ti move $osk "${osk}_"; - gsudo -d -s copy $cmd $osk; - continue; - } - }; - } - - if (-not (Test-Winget)) { - . "$PSScriptRoot/../Software/winget/Manage.ps1"; - continue; - } - - if (-not (Test-Command "git")) { - Install-WingetPackage Git.Git; - refreshenv; - continue; - } - - if (-not (Test-Wsl)) { - Install-Wsl; - Restart-Intermediate; - return; - } - - if (-not (Test-WslDistributions)) { - Install-WslDistribution; - continue; - } - - if (-not (wsl --shell-type login type -t nix)) { - wsl -- sh `<`(curl -L https://nixos.org/nix/install`) --daemon --yes; - wsl --shutdown; - continue; - } - - Invoke-Hook "Install-PSModules" -Fallback { - $modules = @( - @("KnownFolders"), - @("PSWindowsUpdate"), - @("PSScriptAnalyzer"), - @("LocalAccounts", $true), - @("NuGet") - ); - - foreach ($module in $modules) { - $parameters = @{ }; - - if ($module[1]) { - $parameters = @{ - allowPrerelease = $true; - }; - } - - if (-not (Test-PSModule $module[0])) { - Install-Module -Scope AllUsers -AcceptLicense -Force -AllowClobber $module[0] @parameters; - Import-Module $module[0]; + ([OneShotTask]::DisableUAC) { + Disable-UAC; + Register-Setup; } } - - . "$PSScriptRoot/../Software/PinnedItem/Manage.ps1"; }; - if (-not (Test-PSPackage Selenium.WebDriver)) { - Write-Host "Installing browser automation tools…"; - $null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies; - continue; - } - - Install-ChocoPackage selenium-gecko-driver firefox; - - Install-WingetPackage AutoHotkey.AutoHotkey; - Set-Stage ([SetupStage]::Configure); break; } default { - if (-not (Test-Wsl)) { - Register-WslDistribution; + if (Test-Admin) { + $null = Import-Module PSWindowsUpdate; + + Invoke-Hook "Invoke-WindowsUpdate" -Fallback { + Update-WindowsInstallation; + }; + + if ((Get-WURebootStatus -Silent)) { + Restart-Intermediate; + return; + } + } + + <# + .SYNOPSIS + Deploys an action for each software. + + .PARAMETER Action + The action to execute by default. + #> + function Deploy-SoftwareAction { + param( + [Nullable[InstallerAction]] $Action = $null + ) + + [bool] $install = $false; + $arguments = [hashtable]@{ }; + + if ($null -ne $Action) { + $install = ($Action -eq ([InstallerAction]::Install)); + $null = $arguments.Add("action", $Action); + } else { + $install = $true; + } + + # Drivers + & { + $driverPath = "$PSScriptRoot/../Drivers"; + $mbPath = "$driverPath/ROG Zenith Extreme Alpha"; + + if ($install) { + if (Get-Config "valhalla.hardware.elgatoWave") { + if (-not (Test-ChocoPackage wavelink)) { + Install-ChocoPackage wavelink -ArgumentList '--install-arguments="/norestart"'; + Remove-DesktopIcon "*Wave Link*"; + Restart-Intermediate; + exit; + } + } + } + + foreach ($component in (Get-Config "valhalla.hardware.components")) { + switch ($component) { + ("ROG Zenith Extreme Alpha") { + & "$mbPath/MarvellEthernet/Manage.ps1" @arguments; + & "$mbPath/IntelWiFi/Manage.ps1" @arguments; + & "$mbPath/IntelBluetooth/Manage.ps1" @arguments; + & "$mbPath/AMDChipsetX399/Manage.ps1" @arguments; + & "$driverPath/AMDChipsetX399/Manage.ps1" @arguments; + } + ("Predator Z301C") { + & "$driverPath/Predator Z301C/Manage.ps1" @arguments; + } + } + } + + if ($install) { + if (Get-Config "valhalla.hardware.amdCPU") { + Install-ChocoPackage amd-ryzen-master; + # ToDo: backup Ryzen energy saving plan + } + + if (Get-Config "valhalla.hardware.nvidiaGPU") { + Install-ChocoPackage geforce-game-ready-driver; + Remove-DesktopIcon "*Geforce*"; + } + + if (Get-Config "valhalla.hardware.corsairDevice") { + Install-ChocoPackage icue; + } + } + + if (Get-Config "valhalla.hardware.eyeX") { + & "$driverPath/Tobii EyeX/Manage.ps1" @arguments; + } + }; + + & { + # Windows Config + $softwarePath = "$PSScriptRoot/../Software"; + $commonSoftware = "$PSScriptRoot/../../Common/Software"; + & "$softwarePath/Windows/Manage.ps1" @arguments; + + if (Get-Config "valhalla.hardware.logitechG") { + & "$softwarePath/LGHub/Manage.ps1" @arguments; + } + + if (Test-Collection "essential") { + # Essentials + & "$softwarePath/aliae/Main.ps1" @arguments; + & "$softwarePath/git/Manage.ps1" @arguments; + & "$softwarePath/OpenSSH/Manage.ps1" @arguments; + & "$softwarePath/PowerShell/Manage.ps1" @arguments; + & "$softwarePath/chocolatey/Manage.ps1" @arguments; + & "$softwarePath/zoxide/Manage.ps1" @arguments; + & "$commonSoftware/posh-git/Manage.ps1" @arguments; + & "$commonSoftware/Terminal-Icons/Manage.ps1" @arguments; + & "$softwarePath/Oh My Posh/Manage.ps1" @arguments; + + if (Get-Config "valhalla.windows.dualboot") { + & "$softwarePath/Ext4Fsd/Main.ps1" @arguments; + } + + if ($install) { + Install-ChocoPackage ` + procexp ` + procmon ` + ; + + Install-WingetPackage ` + KDE.KDEConnect ` + ; + } + } + + if (Test-Collection "common") { + # Common Software + & "$softwarePath/WinSCP/Manage.ps1" @arguments; + & "$softwarePath/Thunderbird/Manage.ps1" @arguments; + & "$softwarePath/PuTTY/Manage.ps1" @arguments; + + if ($install) { + Install-ChocoPackage ` + 7zip ` + chocolateygui ` + DefaultProgramsEditor ` + bitwarden ` + keepass ` + ; + + Install-WingetPackage ` + SomePythonThings.WingetUIStore ` + ; + + Remove-DesktopIcon "UniGetUI*"; + } + } + + if (Test-Collection "desktopExperience") { + if ($install) { + # Fonts + Install-ChocoPackage nerd-fonts-CascadiaCode; + + # Internet Access + Install-WingetPackage Brave.Brave kamranahmedse.pennywise; + Remove-DesktopIcon "*Brave*"; + Remove-TaskbarItem "*Brave*"; + Remove-DesktopIcon "Pennywise*"; + + # Tools + Install-SetupPackage -Source "https://github.com/mRemoteNG/mRemoteNG/releases/download/2023.03.03-v1.77.3-nb/mRemoteNG-Installer-1.77.3.nb-1784.msi" -ArgumentList "/Quiet"; + Remove-DesktopIcon "mRemoteNG*"; + + Install-ChocoPackage ` + gimp ` + gpu-z ` + windirstat ` + winmerge ` + handbrake ` + hwmonitor ` + qbittorrent ` + imgburn ` + inkscape ` + krita ` + MetaX ` + obs-studio ` + ; + + Remove-DesktopIcon "GIMP*"; + Remove-DesktopIcon "GPU-Z*"; + Remove-DesktopIcon "WinDirStat*"; + Remove-DesktopIcon "*HWMonitor*"; + Remove-DesktopIcon "ImgBurn*"; + Remove-DesktopIcon "InkScape*"; + Remove-DesktopIcon "Krita*"; + Remove-DesktopIcon "MetaX*"; + Remove-DesktopIcon "OBS Studio*"; + + Install-WingetPackage ` + AntSoftware.AntRenamer ` + AppWork.JDownloader; + + Remove-DesktopIcon "JDownloader*"; + } + + # ToDo: Consider hiding behind own config? + & "$softwarePath/Ubiquiti UniFi Controller/Manage.ps1" @arguments; + + # Internet Access + & "$softwarePath/Firefox/Manage.ps1" @arguments; + & "$softwarePath/MSEdgeRedirect/Manage.ps1" @arguments; + + if (Test-Collection "fileSync") { + & "$softwarePath/Nextcloud/Main.ps1" @arguments; + } + } + + if (Test-Collection "socialMedia") { + if ($install) { + Install-ChocoPackage ` + signal ` + threema-desktop ` + element-desktop ` + teamspeak ` + ; + + Remove-DesktopIcon "*Element*"; + Remove-DesktopIcon "*TeamSpeak*"; + + Install-WingetPackage Discord.Discord; + Remove-DesktopIcon "*Discord*"; + } + } + + if (Test-Collection "media") { + if ($install) { + Install-ChocoPackage ` + k-litecodecpackmega ` + vlc ` + ; + + Remove-DesktopIcon "VLC*"; + Install-ChocoPackage jellyfin-media-player -ArgumentList "--install-args","/norestart"; + Remove-DesktopIcon "Jellyfin Media Player*"; + Install-WingetPackage Ytmdesktop.Ytmdesktop; + Remove-DesktopIcon "Youtube Music*"; + } + } + + if (Test-Collection "coding") { + if ($install) { + Install-ChocoPackage ` + gh ` + github-desktop ` + ida-free ` + HxD ` + docker-desktop ` + imhex ` + dotpeek ` + ; + + Remove-DesktopIcon "IDA *"; + Remove-DesktopIcon "GitHub*"; + Remove-DesktopIcon "Docker*"; + } + + & "$softwarePath/vscode/Main.ps1" @arguments; + & "$softwarePath/VisualStudio/Manage.ps1" @arguments; + + # Node.js + & "$softwarePath/NVS/Manage.ps1" @arguments; + } + + if (Test-Collection "gaming") { + # Gaming + if ($install) { + Install-ChocoPackage ` + goggalaxy ` + epicgameslauncher ` + rayman-controlpanel ` + ppsspp ` + ; + + Remove-DesktopIcon "*Epic Games*"; + Remove-DesktopIcon "*PPSSPP *-Bit*"; + + Install-ChocoPackage ` + steam ` + ubisoft-connect ` + -ArgumentList "--ignore-checksums" ` + ; + + Remove-DesktopIcon "*Steam*"; + Remove-DesktopIcon "*Ubisoft Connect*"; + + Install-WingetPackage ElectronicArts.EADesktop; + Remove-DesktopIcon "EA.*"; + } + + & "$softwarePath/TrackMania Nations Forever/Manage.ps1" @arguments; + & "$softwarePath/TrackMania United Forever/Manage.ps1" @arguments; + & "$softwarePath/ManiaPlanet/Manage.ps1" @arguments; + & "$softwarePath/osu!/Manage.ps1" @arguments; + & "$softwarePath/osu!lazer/Manage.ps1" @arguments; + & "$softwarePath/RetroArch/Manage.ps1" @arguments; + & "$softwarePath/reWASD/Manage.ps1" @arguments; + } + }; } switch ($_) { - ([SetupStage]::OneShot) { - Write-Host "Running OneShot task ``$(Get-OneShotTask)``"; - - Start-OneShot { - switch (Get-OneShotTask) { - ([OneShotTask]::InitializeMSAccount) { - Initialize-UserCreation; - } - ([OneShotTask]::DisableUAC) { - Disable-UAC; - Register-Setup; - } + ([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"; } - }; - break; + # 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-Stage ([SetupStage]::Install); } - default { - if (Test-Admin) { - $null = Import-Module PSWindowsUpdate; + ([SetupStage]::Install) { + Write-Host "Entering install phase"; + Deploy-SoftwareAction; + Set-Stage ([SetupStage]::CreateUser); + } + ([SetupStage]::CreateUser) { + $users = @(Get-Users); + $i = Get-CurrentUser; - Invoke-Hook "Invoke-WindowsUpdate" -Fallback { - Update-WindowsInstallation; - }; + for (; $i -lt $users.Count; $i++) { + $name = $users[$i]; + $msAccount = Get-UserConfig -UserName $name "microsoftAccount"; + Set-CurrentUser $i; - if ((Get-WURebootStatus -Silent)) { - Restart-Intermediate; - return; - } - } - - <# - .SYNOPSIS - Deploys an action for each software. - - .PARAMETER Action - The action to execute by default. - #> - function Deploy-SoftwareAction { - param( - [Nullable[InstallerAction]] $Action = $null - ) - - [bool] $install = $false; - $arguments = [hashtable]@{ }; - - if ($null -ne $Action) { - $install = ($Action -eq ([InstallerAction]::Install)); - $null = $arguments.Add("action", $Action); - } else { - $install = $true; + if (Test-Admin) { + Disable-BootMessage; } - # Drivers - & { - $driverPath = "$PSScriptRoot/../Drivers"; - $mbPath = "$driverPath/ROG Zenith Extreme Alpha"; - - if ($install) { - if (Get-Config "valhalla.hardware.elgatoWave") { - if (-not (Test-ChocoPackage wavelink)) { - Install-ChocoPackage wavelink -ArgumentList '--install-arguments="/norestart"'; - Remove-DesktopIcon "*Wave Link*"; - Restart-Intermediate; - exit; - } + while ((Get-UserStage) -ne ([UserStage]::Completed)) { + switch (Get-UserStage) { + ($null) { + Set-UserStage ([UserStage]::Create); + continue; } - } + ([UserStage]::Create) { + if ($env:UserName -ne $name) { + New-ValhallaUser $name; - foreach ($component in (Get-Config "valhalla.hardware.components")) { - switch ($component) { - ("ROG Zenith Extreme Alpha") { - & "$mbPath/MarvellEthernet/Manage.ps1" @arguments; - & "$mbPath/IntelWiFi/Manage.ps1" @arguments; - & "$mbPath/IntelBluetooth/Manage.ps1" @arguments; - & "$mbPath/AMDChipsetX399/Manage.ps1" @arguments; - & "$driverPath/AMDChipsetX399/Manage.ps1" @arguments; - } - ("Predator Z301C") { - & "$driverPath/Predator Z301C/Manage.ps1" @arguments; - } - } - } - - if ($install) { - if (Get-Config "valhalla.hardware.amdCPU") { - Install-ChocoPackage amd-ryzen-master; - # ToDo: backup Ryzen energy saving plan - } - - if (Get-Config "valhalla.hardware.nvidiaGPU") { - Install-ChocoPackage geforce-game-ready-driver; - Remove-DesktopIcon "*Geforce*"; - } - - if (Get-Config "valhalla.hardware.corsairDevice") { - Install-ChocoPackage icue; - } - } - - if (Get-Config "valhalla.hardware.eyeX") { - & "$driverPath/Tobii EyeX/Manage.ps1" @arguments; - } - }; - - & { - # Windows Config - $softwarePath = "$PSScriptRoot/../Software"; - $commonSoftware = "$PSScriptRoot/../../Common/Software"; - & "$softwarePath/Windows/Manage.ps1" @arguments; - - if (Get-Config "valhalla.hardware.logitechG") { - & "$softwarePath/LGHub/Manage.ps1" @arguments; - } - - if (Test-Collection "essential") { - # Essentials - & "$softwarePath/aliae/Main.ps1" @arguments; - & "$softwarePath/git/Manage.ps1" @arguments; - & "$softwarePath/OpenSSH/Manage.ps1" @arguments; - & "$softwarePath/PowerShell/Manage.ps1" @arguments; - & "$softwarePath/chocolatey/Manage.ps1" @arguments; - & "$softwarePath/zoxide/Manage.ps1" @arguments; - & "$commonSoftware/posh-git/Manage.ps1" @arguments; - & "$commonSoftware/Terminal-Icons/Manage.ps1" @arguments; - & "$softwarePath/Oh My Posh/Manage.ps1" @arguments; - - if (Get-Config "valhalla.windows.dualboot") { - & "$softwarePath/Ext4Fsd/Main.ps1" @arguments; - } - - if ($install) { - Install-ChocoPackage ` - procexp ` - procmon ` - ; - - Install-WingetPackage ` - KDE.KDEConnect ` - ; - } - } - - if (Test-Collection "common") { - # Common Software - & "$softwarePath/WinSCP/Manage.ps1" @arguments; - & "$softwarePath/Thunderbird/Manage.ps1" @arguments; - & "$softwarePath/PuTTY/Manage.ps1" @arguments; - - if ($install) { - Install-ChocoPackage ` - 7zip ` - chocolateygui ` - DefaultProgramsEditor ` - bitwarden ` - keepass ` - ; - - Install-WingetPackage ` - SomePythonThings.WingetUIStore ` - ; - - Remove-DesktopIcon "UniGetUI*"; - } - } - - if (Test-Collection "desktopExperience") { - if ($install) { - # Fonts - Install-ChocoPackage nerd-fonts-CascadiaCode; - - # Internet Access - Install-WingetPackage Brave.Brave kamranahmedse.pennywise; - Remove-DesktopIcon "*Brave*"; - Remove-TaskbarItem "*Brave*"; - Remove-DesktopIcon "Pennywise*"; - - # Tools - Install-SetupPackage -Source "https://github.com/mRemoteNG/mRemoteNG/releases/download/2023.03.03-v1.77.3-nb/mRemoteNG-Installer-1.77.3.nb-1784.msi" -ArgumentList "/Quiet"; - Remove-DesktopIcon "mRemoteNG*"; - - Install-ChocoPackage ` - gimp ` - gpu-z ` - windirstat ` - winmerge ` - handbrake ` - hwmonitor ` - qbittorrent ` - imgburn ` - inkscape ` - krita ` - MetaX ` - obs-studio ` - ; - - Remove-DesktopIcon "GIMP*"; - Remove-DesktopIcon "GPU-Z*"; - Remove-DesktopIcon "WinDirStat*"; - Remove-DesktopIcon "*HWMonitor*"; - Remove-DesktopIcon "ImgBurn*"; - Remove-DesktopIcon "InkScape*"; - Remove-DesktopIcon "Krita*"; - Remove-DesktopIcon "MetaX*"; - Remove-DesktopIcon "OBS Studio*"; - - Install-WingetPackage ` - AntSoftware.AntRenamer ` - AppWork.JDownloader; - - Remove-DesktopIcon "JDownloader*"; - } - - # ToDo: Consider hiding behind own config? - & "$softwarePath/Ubiquiti UniFi Controller/Manage.ps1" @arguments; - - # Internet Access - & "$softwarePath/Firefox/Manage.ps1" @arguments; - & "$softwarePath/MSEdgeRedirect/Manage.ps1" @arguments; - - if (Test-Collection "fileSync") { - & "$softwarePath/Nextcloud/Main.ps1" @arguments; - } - } - - if (Test-Collection "socialMedia") { - if ($install) { - Install-ChocoPackage ` - signal ` - threema-desktop ` - element-desktop ` - teamspeak ` - ; - - Remove-DesktopIcon "*Element*"; - Remove-DesktopIcon "*TeamSpeak*"; - - Install-WingetPackage Discord.Discord; - Remove-DesktopIcon "*Discord*"; - } - } - - if (Test-Collection "media") { - if ($install) { - Install-ChocoPackage ` - k-litecodecpackmega ` - vlc ` - ; - - Remove-DesktopIcon "VLC*"; - Install-ChocoPackage jellyfin-media-player -ArgumentList "--install-args","/norestart"; - Remove-DesktopIcon "Jellyfin Media Player*"; - Install-WingetPackage Ytmdesktop.Ytmdesktop; - Remove-DesktopIcon "Youtube Music*"; - } - } - - if (Test-Collection "coding") { - if ($install) { - Install-ChocoPackage ` - gh ` - github-desktop ` - ida-free ` - HxD ` - docker-desktop ` - imhex ` - dotpeek ` - ; - - Remove-DesktopIcon "IDA *"; - Remove-DesktopIcon "GitHub*"; - Remove-DesktopIcon "Docker*"; - } - - & "$softwarePath/vscode/Main.ps1" @arguments; - & "$softwarePath/VisualStudio/Manage.ps1" @arguments; - - # Node.js - & "$softwarePath/NVS/Manage.ps1" @arguments; - } - - if (Test-Collection "gaming") { - # Gaming - if ($install) { - Install-ChocoPackage ` - goggalaxy ` - epicgameslauncher ` - rayman-controlpanel ` - ppsspp ` - ; - - Remove-DesktopIcon "*Epic Games*"; - Remove-DesktopIcon "*PPSSPP *-Bit*"; - - Install-ChocoPackage ` - steam ` - ubisoft-connect ` - -ArgumentList "--ignore-checksums" ` - ; - - Remove-DesktopIcon "*Steam*"; - Remove-DesktopIcon "*Ubisoft Connect*"; - - Install-WingetPackage ElectronicArts.EADesktop; - Remove-DesktopIcon "EA.*"; - } - - & "$softwarePath/TrackMania Nations Forever/Manage.ps1" @arguments; - & "$softwarePath/TrackMania United Forever/Manage.ps1" @arguments; - & "$softwarePath/ManiaPlanet/Manage.ps1" @arguments; - & "$softwarePath/osu!/Manage.ps1" @arguments; - & "$softwarePath/osu!lazer/Manage.ps1" @arguments; - & "$softwarePath/RetroArch/Manage.ps1" @arguments; - & "$softwarePath/reWASD/Manage.ps1" @arguments; - } - }; - } - - switch ($_) { - ([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-Stage ([SetupStage]::Install); - } - ([SetupStage]::Install) { - Write-Host "Entering install phase"; - Deploy-SoftwareAction; - Set-Stage ([SetupStage]::CreateUser); - } - ([SetupStage]::CreateUser) { - $users = @(Get-Users); - $i = Get-CurrentUser; - - for (; $i -lt $users.Count; $i++) { - $name = $users[$i]; - $msAccount = Get-UserConfig -UserName $name "microsoftAccount"; - Set-CurrentUser $i; - - if (Test-Admin) { - Disable-BootMessage; - } - - while ((Get-UserStage) -ne ([UserStage]::Completed)) { - switch (Get-UserStage) { - ($null) { - Set-UserStage ([UserStage]::Create); - continue; - } - ([UserStage]::Create) { - - if ($env:UserName -ne $name) { - New-ValhallaUser $name; - - if ($msAccount) { - logoff; - } else { - Restart-Intermediate; - } - - exit; - } else { - if ($msAccount) { - if (-not (Test-Admin)) { - Invoke-OneShot DisableUAC; - Restart-Intermediate -NoRegister; - return; - } - - Clear-SetupRegistration; - Disable-OneShotListener; - } - - Set-UserStage ([UserStage]::Configure); - } - } - (([UserStage]::Configure)) { - $displayName = Get-UserConfig -UserName $name "displayName"; - - $userArguments = @{ - name = $name; - }; - - if ($displayName) { - $userArguments.fullName = $displayName; - } - - $adminGroup = @{ - SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null); - }; - - Set-LocalUser @userArguments; - Deploy-SoftwareAction -Action ([InstallerAction]::ConfigureUser); - Remove-LocalGroupMember -Member $name @adminGroup -ErrorAction SilentlyContinue; - - foreach ($group in Get-UserConfig -UserName $name "groups") { - Add-LocalGroupMember -Member $name -Name "$group"; - } - - if (-not $msAccount) { - net user $name /logonpasswordchg:yes; - } - - Set-UserStage ([UserStage]::Cleanup); - } - ([UserStage]::Cleanup) { - $user = Get-SetupUser; - Enable-LocalUser $user; - Set-AutologinUser $user; - Unregister-WslDistribution; - Set-UserStage ([UserStage]::Completed); + if ($msAccount) { + logoff; + } else { Restart-Intermediate; exit; } + + exit; + } else { + if ($msAccount) { + if (-not (Test-Admin)) { + Invoke-OneShot DisableUAC; + Restart-Intermediate -NoRegister; + return; + } + + Clear-SetupRegistration; + Disable-OneShotListener; + } + + Set-UserStage ([UserStage]::Configure); } } - } + (([UserStage]::Configure)) { + $displayName = Get-UserConfig -UserName $name "displayName"; - Set-IsFinished $true; + $userArguments = @{ + name = $name; + }; + + if ($displayName) { + $userArguments.fullName = $displayName; + } + + $adminGroup = @{ + SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null); + }; + + Set-LocalUser @userArguments; + Deploy-SoftwareAction -Action ([InstallerAction]::ConfigureUser); + Remove-LocalGroupMember -Member $name @adminGroup -ErrorAction SilentlyContinue; + + foreach ($group in Get-UserConfig -UserName $name "groups") { + Add-LocalGroupMember -Member $name -Name "$group"; + } + + if (-not $msAccount) { + net user $name /logonpasswordchg:yes; + } + + Set-UserStage ([UserStage]::Cleanup); + } + ([UserStage]::Cleanup) { + $user = Get-SetupUser; + Enable-LocalUser $user; + Set-AutologinUser $user; + Unregister-WslDistribution; + Set-UserStage ([UserStage]::Completed); + Restart-Intermediate; + } + } } } + + Set-IsFinished $true; } } }