using namespace System.Management.Automation.Host; $null = New-Module { . "$PSScriptRoot/Scripting.ps1"; . "$PSScriptRoot/SoftwareManagement.ps1"; . "$PSScriptRoot/../Windows/lib/Constants.ps1"; . "$PSScriptRoot/../Windows/lib/PowerManagement.ps1"; . "$PSScriptRoot/../Windows/lib/Registry.ps1"; . "$PSScriptRoot/../Windows/lib/Security.ps1"; . "$PSScriptRoot/../Windows/lib/SoftwareManagement.ps1"; . "$PSScriptRoot/../Windows/lib/System.ps1"; . "$PSScriptRoot/../Windows/lib/Tasks.ps1"; . "$PSScriptRoot/../Windows/lib/WSL.ps1"; <# .SYNOPSIS Gets the PowerShell modules required for operating. #> function Get-RequiredModules { $modules = @( @("PSScriptAnalyzer") ) + (& { if (-not $IsWindows) { @(); } else { @( @("KnownFolders"), @("PSWindowsUpdate"), @("LocalAccounts", $true), @("NuGet") ); } }); for ($i = 0; $i -lt $modules.Count; $i++) { if ($modules[$i] -is [string]) { $modules[$i] = @($modules[$i]); } } return $modules; } function Start-Operation { param( [switch] $NonInteractive, [switch] $NoImplicitCleanup, [scriptblock] $Action ) $cleanup = { }; $taskPending = $false; if (-not $Global:InOperation) { if ($env:DEBUG) { Set-PSDebug -Trace 1; } if ($IsWindows -and ($null -ne (Get-OneShotTask))) { $taskPending = $true; [switch] $NonInteractive = $true; } $Global:InOperation = $true; $Global:NonInteractive = $NonInteractive; $Global:ErrorActionPreference = $NonInteractive.IsPresent ? 'Continue' : 'Inquire'; if ($IsWindows) { $env:WSLENV = "CONFIG_NAME:VALHALLA_FLAKE_ROOT"; Backup-PowerScheme; } if (-not $NoImplicitCleanup.IsPresent) { $cleanup = { Remove-Variable -Scope Global -Name "InOperation"; Clear-OperationResources; }; } & { $initialized = $false; # Ping digitalcourage DNS server # https://digitalcourage.de/ Write-Host "Waiting for internet connection…"; while ((Test-Connection -Count 1 5.9.164.112).Status -ne 'Success') { Start-Sleep 0.1; } while (-not $initialized) { if ($IsWindows) { if (-not ((Test-Command "choco") -and (Test-Command "refreshenv"))) { # Install chocolatey Write-Host "Installing 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")) { Write-Host "Installing PowerShell Core…"; 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) { $liveScriptOption = "LiveScripts"; if (($null -eq (Get-SetupOption $liveScriptOption)) -and (Test-Qemu)) { $result = $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); Set-SetupOption $liveScriptOption $result; if ($result -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 @("INSTALLER_SCRIPT")) { $variable = Get-Item "Env:\$name"; $path = Join-Path ` "Z:\" ` ([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.exe")) { Install-ChocoPackage gsudo; refreshenv; continue; } function global:Invoke-Sudo { param( $u, [Parameter(ValueFromRemainingArguments, Position = 0)] [string[]] $ArgumentList ) $params = @(); if ($u) { $params = @("-u", $u); } elseif ($ArgumentList[0] -eq "-u") { $user = $ArgumentList[1]; $ArgumentList = $ArgumentList | Select-Object -Skip 2; $params = @("-u", $user); } gsudo @params { $command = $args[0]; $flags = ($args | Select-Object -Skip 1); & $command @flags; } -args $ArgumentList; } New-Alias -Force "sudo" -Scope Global Invoke-Sudo; if ($env:DEBUG) { & { $sys32 = "$env:WINDIR/System32"; $osk = (Get-Item "$sys32/osk.exe").FullName; $cmd = (Get-Item "$sys32/cmd.exe").FullName; if ((Get-FileHash $osk).Hash -ne (Get-FileHash $cmd).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/Main.ps1"; continue; } if (-not (Test-Command "git")) { Install-WingetPackage Git.Git; refreshenv; continue; } if (-not (Test-Command "7z")) { Install-ChocoPackage 7zip.portable; refreshenv; continue; } if (-not (Test-Command "yq")) { Install-ChocoPackage "yq"; refreshenv; continue; } if (-not (Test-Wsl)) { Install-Wsl; Restart-Intermediate; return; } if (-not (Test-WslDistribution)) { if (-not (Test-Path (Get-WslDistributionDisk))) { Install-WslDistribution; } Register-WslDistribution; continue; } if (-not (Test-Nix)) { Install-Nix; continue; } if (-not (Test-PSPackage Selenium.WebDriver)) { Write-Host "Installing browser automation tools…"; $null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.24.0 -SkipDependencies; continue; } Install-ChocoPackage selenium-gecko-driver firefox; Install-WingetPackage AutoHotkey.AutoHotkey; . "$PSScriptRoot/../Windows/Software/pinned-item/Main.ps1"; } Write-Host "Installing PowerShell Modules…"; foreach ($module in (Get-RequiredModules)) { $parameters = @{ }; if ($module -is [string]) { $module = @($module); } if ($module[1]) { $parameters = @("-AllowPrerelease"); } if (-not (Test-PSModule $module[0])) { sudo pwsh -Command Install-Module -Scope AllUsers -AcceptLicense -Force -AllowClobber $module[0] @parameters; Import-Module $module[0]; } } if (-not $env:CONFIG_NAME) { Show-ProfileNamePrompt; } $initialized = $true; } }; } if ($taskPending) { Start-OneShot; } else { & $Action; } & $cleanup; } <# .SYNOPSIS Clears resources allocated during the operation. #> function Clear-OperationResources { if ($IsWindows) { Uninstall-WslDistribution; $null = Uninstall-Package Selenium.WebDriver -ErrorAction Continue; Uninstall-ChocoPackage 7zip.portable gsudo selenium-gecko-driver yq; Uninstall-WingetPackage AutoHotkey.AutoHotkey; Restore-PowerScheme; } foreach ($module in (Get-RequiredModules)) { Remove-Module -Force $module[0] -ErrorAction SilentlyContinue; Uninstall-Module -Force -Name $module[0] -ErrorAction SilentlyContinue; } } };