Compare commits

...

135 commits

Author SHA1 Message Date
Manuel Thalmann 984fd09352 Add a script for managing backups 2024-08-27 21:05:51 +02:00
Manuel Thalmann 4452df19bd Add tools for managing aliae 2024-08-27 18:58:33 +02:00
Manuel Thalmann 3f5221f0ed Fix non-functioning aliae installation 2024-08-27 18:55:12 +02:00
Manuel Thalmann d55b65fc7a Create dedicated script for creating users 2024-08-27 17:04:17 +02:00
Manuel Thalmann d260fdff34 Create dedicated script for installing software 2024-08-27 16:41:08 +02:00
Manuel Thalmann 34253ab705 Prevent reading nix config multiple times 2024-08-27 14:35:04 +02:00
Manuel Thalmann 0f443eed85 Ensure only one user is enabled at once 2024-08-27 14:11:31 +02:00
Manuel Thalmann bcc5ee58cd Prevent unnecessary file creation 2024-08-27 14:06:56 +02:00
Manuel Thalmann 8b56d67a29 Execute OneShot tasks in any operation 2024-08-27 14:05:16 +02:00
Manuel Thalmann ef66d1d9c8 Use /mnt as mount directory 2024-08-27 04:30:12 +02:00
Manuel Thalmann 33910c5b25 Force the use of the managed distribution 2024-08-27 04:26:25 +02:00
Manuel Thalmann 48bc56d965 Initialize operation for all users 2024-08-27 04:24:29 +02:00
Manuel Thalmann 301f3adbc6 Handle initialization in operation code 2024-08-27 04:15:37 +02:00
Manuel Thalmann bc0cd0514a Execute script non-interactive during OneShot tasks 2024-08-27 03:50:08 +02:00
Manuel Thalmann f1841f765b Exit script after running OneShot task 2024-08-27 03:45:44 +02:00
Manuel Thalmann 91e8340deb Modify user after first login 2024-08-27 03:27:54 +02:00
Manuel Thalmann c0d5d11c56 Rearm Windows Activation before creating MSAcc 2024-08-27 03:25:19 +02:00
Manuel Thalmann fd2cacd985 Register MSAcc logon script early 2024-08-27 03:24:37 +02:00
Manuel Thalmann 3443a5d7d8 Allow rebooting without registering setup 2024-08-27 03:11:35 +02:00
Manuel Thalmann b01bef20fd Prevent reboots during installation 2024-08-27 02:18:01 +02:00
Manuel Thalmann c704e85e5f Fix non-functioning NoProfile argument 2024-08-27 02:09:04 +02:00
Manuel Thalmann 2abdc9909f Prevent unnecessary installation actions 2024-08-27 01:57:46 +02:00
Manuel Thalmann 3c2b9d3a53 Only install PowerShell module if necessary 2024-08-27 01:25:32 +02:00
Manuel Thalmann d35cfe83b8 Streamline PowerShell installation 2024-08-27 00:45:46 +02:00
Manuel Thalmann 24e1596e68 Add further functionality to the WSL script 2024-08-27 00:38:46 +02:00
Manuel Thalmann 3695642120 Create a separate script for WSL interaction 2024-08-26 23:33:46 +02:00
Manuel Thalmann 455e8b9d71 Fix recursive configuration 2024-08-25 03:58:28 +02:00
Manuel Thalmann a567de8ddc Fix malformed module 2024-08-24 18:35:43 +02:00
Manuel Thalmann 4bb860b149 Keep Windows fixes separate 2024-08-24 16:56:29 +02:00
Manuel Thalmann 16603c647e Remove WSL after operation 2024-08-24 16:52:41 +02:00
Manuel Thalmann 9b90f750c4 Make distribution name unique 2024-08-24 16:41:05 +02:00
Manuel Thalmann 3d34053c75 Streamline WSL distribution name 2024-08-24 16:27:34 +02:00
Manuel Thalmann d81d2dcf23 Remove unused resources after user setup 2024-08-24 16:15:10 +02:00
Manuel Thalmann d1ab409527 Print update logs properly 2024-08-24 14:47:51 +02:00
Manuel Thalmann 6e64156dac Allow overriding Windows settings 2024-08-24 14:20:22 +02:00
Manuel Thalmann bd31916782 Update incorrect path 2024-08-24 14:11:38 +02:00
Manuel Thalmann 061abd1c8f Simplify osu!lazer installation 2024-08-24 14:10:02 +02:00
Manuel Thalmann 076bfbe66e Determine name of setup user properly 2024-08-24 14:01:05 +02:00
Manuel Thalmann d7a407f29d Make OMP configuration platform independent 2024-08-24 13:27:48 +02:00
Manuel Thalmann bbcddf286c Fix incorrect character in OMP theme 2024-08-24 13:27:35 +02:00
Manuel Thalmann 0febeada6a Remove unnecessary code 2024-08-24 04:25:07 +02:00
Manuel Thalmann 6c4994f825 Remove unnecessary loop 2024-08-24 04:24:55 +02:00
Manuel Thalmann 1243ccc5cb Add missing module 2024-08-24 04:24:37 +02:00
Manuel Thalmann 4607fca566 Add nextcloud to the module list 2024-08-24 04:18:57 +02:00
Manuel Thalmann 71f80b7cfc Add a function for creating shortcuts 2024-08-24 04:18:33 +02:00
Manuel Thalmann 25f5eab8bb Configure nextcloud syncs 2024-08-24 04:07:47 +02:00
Manuel Thalmann ba56022b6a Allow configuring nextcloud syncs 2024-08-24 04:07:35 +02:00
Manuel Thalmann aa0173680e Create separate option holding win users 2024-08-24 03:25:28 +02:00
Manuel Thalmann 63de8c576d Rename Nextcloud installer 2024-08-24 01:50:07 +02:00
Manuel Thalmann 02bedaafc8 Add file system driver for dual boot 2024-08-24 01:41:09 +02:00
Manuel Thalmann 7b46901a16 Prevent unnecessary config evaluation 2024-08-24 01:31:39 +02:00
Manuel Thalmann cecb4ace13 Fix non-functioning installer 2024-08-24 01:27:26 +02:00
Manuel Thalmann 08b494065f Install vscode extensions by default 2024-08-24 01:16:56 +02:00
Manuel Thalmann d31f9e916e Load theme file from WSL properly 2024-08-24 00:59:59 +02:00
Manuel Thalmann 23a6dce4cc Update aliae configuration script 2024-08-24 00:42:57 +02:00
Manuel Thalmann a74f78ed67 Strip duplicate variables and aliases 2024-08-24 00:08:58 +02:00
Manuel Thalmann 6adcd58ba5 Install posh theme automatically 2024-08-23 23:53:48 +02:00
Manuel Thalmann a27feaddc7 Export missing function 2024-08-23 23:50:13 +02:00
Manuel Thalmann d2332a7931 Install aliae by default 2024-08-23 23:46:23 +02:00
Manuel Thalmann b4816b0206 Add scripts for changing aliae config 2024-08-23 23:44:51 +02:00
Manuel Thalmann ec890ac844 Fix compatibility with mixed new line characters 2024-08-23 23:44:23 +02:00
Manuel Thalmann ce7687ddfb Add a script for installing aliae 2024-08-23 22:38:28 +02:00
Manuel Thalmann f3ee868609 Add desired posh theme 2024-08-23 19:43:06 +02:00
Manuel Thalmann cc9bf27479 Make option names more clear 2024-08-23 19:42:27 +02:00
Manuel Thalmann 3a478dbdb2 Allow configuring oh-my-posh 2024-08-23 19:39:18 +02:00
Manuel Thalmann e206ff8f50 Fetch config from proper section 2024-08-23 19:24:49 +02:00
Manuel Thalmann 74c870b5d9 Adjust configuration accordingly 2024-08-23 19:14:09 +02:00
Manuel Thalmann 3f5c4f38e6 Refactor option descriptions 2024-08-23 19:02:06 +02:00
Manuel Thalmann 74bad2938e Clean up the Windows configuration 2024-08-23 18:59:49 +02:00
Manuel Thalmann 1fd664b6f3 Clean up the users.nix file 2024-08-23 18:51:54 +02:00
Manuel Thalmann 773b5205da Create dedicated rclone module 2024-08-23 18:48:30 +02:00
Manuel Thalmann 4ba9db4227 Move git module to separate directory 2024-08-23 18:42:16 +02:00
Manuel Thalmann fea1c5b253 Move git options to separate module 2024-08-23 18:40:24 +02:00
Manuel Thalmann 5683637d1c Fix inheritance of user config 2024-08-23 18:28:20 +02:00
Manuel Thalmann 1859613c84 Allow OS specific settings 2024-08-23 18:11:48 +02:00
Manuel Thalmann 0b4552acab Update archiso 2024-08-23 14:19:56 +02:00
Manuel Thalmann 29fcbc315a Set user info during git setup 2024-08-23 02:01:16 +02:00
Manuel Thalmann b1e66c38a3 Make all config scripts platform independent 2024-08-23 01:57:53 +02:00
Manuel Thalmann 3a5921d024 Allow leaving aliases unspecified 2024-08-23 01:52:25 +02:00
Manuel Thalmann f5a604d259 Make scripts platform independent 2024-08-23 01:52:04 +02:00
Manuel Thalmann 50253d0fc1 Add scripts for configuring git 2024-08-23 01:43:26 +02:00
Manuel Thalmann e523454345 Configure software implicitly 2024-08-23 01:41:32 +02:00
Manuel Thalmann 1d1b9cb8cb Skip profile creation for PinnedItem 2024-08-22 23:55:41 +02:00
Manuel Thalmann f85f2109e1 Allow skipping powershell module registration 2024-08-22 23:55:00 +02:00
Manuel Thalmann fc68ad833d Add profiles to the flake 2024-08-22 23:37:53 +02:00
Manuel Thalmann 358e10b018 Remove user profile of OneShot user 2024-08-22 23:12:11 +02:00
Manuel Thalmann d72b79f786 Add missing OneShotTask declaration 2024-08-22 20:41:30 +02:00
Manuel Thalmann 0c390653d1 Fix infinite loop 2024-08-22 20:41:17 +02:00
Manuel Thalmann 98b06f95ee Fix incorrect variable name 2024-08-22 20:34:16 +02:00
Manuel Thalmann 169c521b89 Fix handling empty error messages 2024-08-22 20:12:18 +02:00
Manuel Thalmann c847cb8fd1 Add choco to the profile of the setup user 2024-08-22 13:46:55 +02:00
Manuel Thalmann fb4e85a924 Fix incorrect typings 2024-08-22 11:11:12 +02:00
Manuel Thalmann 954caeeb2b Fix permission issues when enabling Win hack 2024-08-22 11:11:00 +02:00
Manuel Thalmann f5aa3bac17 Register setup script as admin 2024-08-22 11:10:39 +02:00
Manuel Thalmann bbf53e1333 Execute the entire installer using live scripts 2024-08-21 23:21:32 +02:00
Manuel Thalmann 15eb8ba308 Streamline the creation of users 2024-08-21 18:34:18 +02:00
Manuel Thalmann 1cf1cbf872 Replace osk with cmd during debugging 2024-08-21 18:33:41 +02:00
Manuel Thalmann 3b95d40a7f Prevent pauses in OneShot tasks 2024-08-21 18:28:50 +02:00
Manuel Thalmann 8ec473e6ad Print commands in debug mode 2024-08-21 18:28:08 +02:00
Manuel Thalmann 3d4868b01d Run OneShot tasks with dedicated user 2024-08-21 18:27:47 +02:00
Manuel Thalmann 80ac0a2a37 Add function for generating startup command 2024-08-21 18:26:58 +02:00
Manuel Thalmann 52e924d62c Allow registering startup script for the default user 2024-08-21 18:20:11 +02:00
Manuel Thalmann 42cbaff30a Prevent unnecessary errors during WSL execution 2024-08-21 14:08:26 +02:00
Manuel Thalmann 896656eab0 Register WSL before running OneShot tasks 2024-08-21 03:37:44 +02:00
Manuel Thalmann ef65871af5 Overwrite broken module 2024-08-21 03:20:37 +02:00
Manuel Thalmann d38944e245 Prevent initialization of nested operations 2024-08-21 03:18:31 +02:00
Manuel Thalmann 5283e7bb7f Improve log messages of OneShot tasks 2024-08-21 02:02:30 +02:00
Manuel Thalmann 704d3d9542 Retry Linux path conversion for errors 2024-08-20 00:20:33 +02:00
Manuel Thalmann 1d3c4d894a Fix typo 2024-08-20 00:20:07 +02:00
Manuel Thalmann e1fad768db Fix broken signature of Restart-Intermediate 2024-08-19 12:07:26 +02:00
Manuel Thalmann 6902d80781 Report unexpected path conversions 2024-08-19 02:50:41 +02:00
Manuel Thalmann d00568421e Load missing path 2024-08-19 02:50:19 +02:00
Manuel Thalmann 52eb40f350 Ensure error file can be read from 2024-08-19 02:24:45 +02:00
Manuel Thalmann f225c17124 Streamline OneShot task handler 2024-08-19 02:24:30 +02:00
Manuel Thalmann e56d01241f Simplify script registration 2024-08-19 02:24:13 +02:00
Manuel Thalmann fa161667de Fix broken regedit paths 2024-08-19 01:38:25 +02:00
Manuel Thalmann 8d94fac5ae Allow registering reboots for users 2024-08-19 01:37:14 +02:00
Manuel Thalmann 22ce60d3be Prevent users from being excluded 2024-08-19 01:10:29 +02:00
Manuel Thalmann 329e7d4b68 Force copying of Linux users to Windows 2024-08-19 00:54:13 +02:00
Manuel Thalmann 5a769e9497 Improve log messages of updates 2024-08-18 12:20:21 +02:00
Manuel Thalmann 7320fa5093 Remove unnecessary command 2024-08-18 10:24:15 +02:00
Manuel Thalmann d9ae8c2da0 Fix time for QEMU VMs 2024-08-18 09:35:16 +02:00
Manuel Thalmann 9143f92069 Remove unnecessary desktop icons 2024-08-18 09:25:23 +02:00
Manuel Thalmann f24149d7ca Add a timeout for the reWASD downloader 2024-08-18 09:05:04 +02:00
Manuel Thalmann 80e049353f Allow setting a timeout for clicking download buttons 2024-08-18 09:04:42 +02:00
Manuel Thalmann c25c9931c3 Emit errors concerning WSL commands 2024-08-17 13:51:10 +02:00
Manuel Thalmann cc2c0863d8 Emit errors using Write-Error 2024-08-17 13:49:21 +02:00
Manuel Thalmann 778e88154d Convert Argument to string explicitly 2024-08-16 23:03:19 +02:00
Manuel Thalmann 294c4b0f43 Ignore unfinished browser downloads 2024-08-16 17:57:22 +02:00
Manuel Thalmann 19b7ac92bf Install powershell modules for all users 2024-08-16 16:43:30 +02:00
Manuel Thalmann afa88efdb0 Fix typos 2024-08-16 16:10:09 +02:00
Manuel Thalmann 31920069f9 Install AutoHotkey as preparation 2024-08-16 15:22:09 +02:00
Manuel Thalmann 645571e313 Allow running live scripts in debug mode 2024-08-16 15:21:41 +02:00
Manuel Thalmann 392e717f92 Generate env variables using shorthand scripts 2024-08-16 15:16:56 +02:00
Manuel Thalmann db13a4a93a Allow running installation in debug mode 2024-08-16 15:16:28 +02:00
69 changed files with 2485 additions and 993 deletions

View file

@ -23,7 +23,7 @@ automated_script() {
sleep 1
done
printf '%s: downloading %s\n' "$0" "${script}"
curl "${script}" --location --retry-connrefused --retry 10 -s -o /tmp/startup_script
curl "${script}" --location --retry-connrefused --retry 10 --fail -s -o /tmp/startup_script
rt=$?
else
cp "${script}" /tmp/startup_script

View file

@ -1,8 +1,8 @@
diff --git a/airootfs/root/.zlogin b/airootfs/root/.zlogin
index bf6bc8f..76e5893 100755
index bf6bc8f..a0dae7b 100755
--- a/airootfs/root/.zlogin
+++ b/airootfs/root/.zlogin
@@ -4,3 +4,18 @@ if grep -Fqa 'accessibility=' /proc/cmdline &> /dev/null; then
@@ -4,3 +4,19 @@ if grep -Fqa 'accessibility=' /proc/cmdline &> /dev/null; then
fi
~/.automated_script.sh
@ -16,13 +16,14 @@ index bf6bc8f..76e5893 100755
+
+git diff -p -R --no-ext-diff --no-color --diff-filter=M \
+ | grep -E "^(diff|(old|new) mode)" --color=never \
+ | sed "/^diff/{ x; d; }; x; /./{ p; z; }; x;" \
+ | git apply
+
+popd > /dev/null
+
+loadkeys de_CH-latin1
diff --git a/packages.x86_64 b/packages.x86_64
index 9e876e7..b89ab30 100755
index 9e876e7..c5db92a 100755
--- a/packages.x86_64
+++ b/packages.x86_64
@@ -30,8 +30,10 @@ ethtool
@ -36,7 +37,15 @@ index 9e876e7..b89ab30 100755
gnu-netcat
gpart
gpm
@@ -75,6 +77,7 @@ nbd
@@ -45,6 +47,7 @@ irssi
iw
iwd
jfsutils
+jq
kitty-terminfo
ldns
less
@@ -75,6 +78,7 @@ nbd
ndisc6
nfs-utils
nilfs-utils

View file

@ -6,7 +6,7 @@
flake-utils.url = "github:numtide/flake-utils?ref=b1d9ab70662946ef0850d488da1c9019f3a9752a";
};
outputs = { self, flake-utils, nixpkgs }: flake-utils.lib.eachDefaultSystem (
outputs = { self, flake-utils, nixpkgs }: (flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
@ -32,5 +32,11 @@
packages = {
archiso = pkgs.archiso;
};
});
})) // {
valhalla = {
"DerGeret Windows" = import ./profiles/DerGeret/config.nix;
"der-geret Arch Linux" = import ./profiles/DerGeret/Arch/config.nix;
"manu-surface Arch Linux" = import ./profiles/ManuSurface/Arch/config.nix;
};
};
}

View file

@ -1,7 +0,0 @@
{ lib, ... }: {
options = {
valhalla = {
git = (import ./git/options.nix) { inherit lib; };
};
};
}

View file

@ -1,33 +0,0 @@
{ lib, ... }:
let
inherit (lib)
mkOption
types
;
in {
defaultBranch = mkOption {
type = types.nullOr types.str;
description = "The name of the default branch in git.";
default = null;
};
flow = {
mainBranch = mkOption {
type = types.nullOr types.str;
description = "The name of the stable branch in git flow.";
default = null;
};
devBranch = mkOption {
type = types.nullOr types.str;
description = "The name of the development branch in git flow.";
default = null;
};
};
aliases = mkOption {
type = types.attrsOf types.str;
description = "Git command aliases to install.";
default = {};
};
}

52
lib/modules/os.nix Normal file
View file

@ -0,0 +1,52 @@
{ lib, ... }:
let
inherit (lib)
mkOption
types
;
in {
options = {
valhalla = mkOption {
type = types.submodule (
{ extendModules, ... }:
let
osVariant = extendModules {
modules = [
({ config, ... }: {
options = {
config = mkOption {
type = types.attrs;
description = "The configuration of the Operating System.";
default = builtins.removeAttrs config ["_module" "config" "linux" "windows"];
visible = false;
};
};
})
];
};
linuxVariant = osVariant.extendModules { };
windowsVariant = osVariant.extendModules { };
in {
options = {
linux = mkOption {
inherit (linuxVariant) type;
description = "The options for setting up Linux.";
default = {};
visible = "shallow";
};
windows = mkOption {
inherit (windowsVariant) type;
description = "The options for setting up Windows.";
default = {};
visible = "shallow";
};
};
});
description = "Configuration for PortValhalla.";
default = {};
};
};
}

View file

@ -0,0 +1,59 @@
{ lib, ... }:
let
inherit (lib)
mkOption
types
;
gitType = types.submodule (
{ ... }: {
options = {
defaultBranch = mkOption {
type = types.nullOr types.str;
description = "The name of the default branch in newly created repositories.";
default = null;
};
flow = {
mainBranch = mkOption {
type = types.nullOr types.str;
description = "The name of the stable branch in git flow.";
default = null;
};
devBranch = mkOption {
type = types.nullOr types.str;
description = "The name of the development branch in git flow.";
default = null;
};
};
aliases = mkOption {
type = types.attrsOf types.str;
description = "The git command aliases to install.";
default = {};
};
};
});
gitOption = mkOption {
type = gitType;
description = "The git related options.";
default = {};
};
in {
options = {
valhalla = {
git = gitOption;
users = mkOption {
type = types.attrsOf (types.submodule (
{ ... }: {
options = {
git = gitOption;
};
}));
};
};
};
}

View file

@ -0,0 +1,44 @@
{ lib, ... }:
let
inherit (lib)
mkEnableOption
mkOption
types
;
syncType = types.submodule (
{ ... }: {
options = {
remotePath = mkOption {
type = types.str;
description = "The path to the folder on the cloud to sync.";
};
localPath = mkOption {
type = types.str;
description = "The path to sync the cloud content to.";
};
virtualFiles = (mkEnableOption "virtual file support") // {
default = true;
};
};
});
in {
options = {
valhalla.windows.users = mkOption {
type = types.attrsOf (types.submodule (
{ ... }: {
options = {
nextcloud = {
folderSyncs = mkOption {
type = types.listOf syncType;
description = "The folders to synchronize.";
default = [];
};
};
};
}));
};
};
}

View file

@ -0,0 +1,60 @@
{ lib, ... }:
let
inherit (lib)
mkOption
types
;
themeType = types.submodule (
{ config, ... }: {
options = {
source = mkOption {
type = types.nullOr types.path;
description = "The path to the oh-my-posh theme to use.";
default = null;
};
name = mkOption {
type = types.nullOr types.str;
description = "The name of the theme.";
default = if (config.source != null)
then
lib.strings.removeSuffix ".omp" (lib.strings.removeSuffix ".json" (builtins.baseNameOf config.source))
else
null;
};
};
});
ompType = types.submodule (
{ config, ... }: {
options = {
theme = mkOption {
type = types.either types.str themeType;
description = "The default theme.";
default = {};
};
additionalThemes = mkOption {
type = types.listOf themeType;
description = "A set of additional themes to install.";
default = [];
};
};
});
in {
options = {
valhalla.users = mkOption {
type = types.attrsOf (types.submodule (
{ ... }: {
options = {
oh-my-posh = mkOption {
type = ompType;
description = "The Oh My Posh configuration to apply.";
default = {};
};
};
}));
};
};
}

View file

@ -0,0 +1,40 @@
{ lib, ... }:
let
inherit (lib)
mkOption
types
;
syncType = types.submodule (
{ ... }: {
options = {
dirName = mkOption {
type = types.str;
description = "The name of the directory to sync the remote files to.";
};
cacheDuration = mkOption {
type = types.nullOr types.str;
description = "The amount of time to keep cached files.";
default = null;
};
};
});
in {
options = {
valhalla.linux.users = mkOption {
type = types.attrsOf (types.submodule (
{ ... }: {
options = {
rclone = {
configurations = mkOption {
type = types.attrsOf syncType;
description = "The configurations of the rclone mounts.";
default = {};
};
};
};
}));
};
};
}

View file

@ -1,47 +1,13 @@
{ config, lib, ... }:
{ lib, ... }:
let
inherit (lib)
mkOption
types
;
cfg = config.valhalla;
capitalize = (import ../text.nix { inherit lib; }).capitalize;
linuxOptions = {
defaultShell = mkOption {
type = types.nullOr types.str;
description = "The default shell of the user.";
default = null;
};
rclone = {
configurations = mkOption {
type = types.attrsOf syncType;
description = "The configurations of the rclone mounts.";
default = {};
};
};
};
syncType = types.submodule (
{ ... }: {
options = {
dirName = mkOption {
type = types.str;
description = "The name of the directory to sync the remote files to.";
};
cacheDuration = mkOption {
type = types.nullOr types.str;
description = "The amount of time to keep cached files.";
default = null;
};
};
});
mkUserType = { options }: (
types.submodule (
userType = types.submodule (
{ ... } : {
options = {
displayName = mkOption {
@ -61,16 +27,22 @@
description = "The additional groups of the user.";
default = [];
};
git = (import ./git/options.nix) { inherit lib; };
} // options;
}));
userType = mkUserType {
options = linuxOptions;
};
});
winUserType = mkUserType {
linuxUserType = types.submodule (
{ ... }: {
options = {
defaultShell = mkOption {
type = types.nullOr types.str;
description = "The default shell of the user.";
default = null;
};
};
});
winUserType = types.submodule (
{ ... }: {
options = {
microsoftAccount = mkOption {
type = types.bool;
@ -78,7 +50,7 @@
default = false;
};
};
};
});
in {
options = {
valhalla = {
@ -88,25 +60,33 @@
default = {};
};
windows.users = mkOption {
linux.users = mkOption {
type = types.attrsOf linuxUserType;
};
windows = mkOption {
type = types.submoduleWith {
modules = [
({ config, options, ... }: {
options = {
users = mkOption {
type = types.attrsOf winUserType;
description = "The users to create on the Windows machine.";
};
winUsers = mkOption {
type = options.users.type;
description = "Blablabla";
default = (lib.attrsets.concatMapAttrs (
name: options:
if builtins.elem name (builtins.attrNames linuxOptions)
then {}
else {
${capitalize name} = (lib.attrsets.concatMapAttrs (
name: value:
if builtins.elem name (builtins.attrNames linuxOptions)
then {}
else {
${name} = value;
}
) options) // {
name: options: {
${capitalize name} = options // {
groups = [];
};
}) cfg.users);
}) config.users);
};
};
})
];
};
};
};
};

View file

@ -6,9 +6,13 @@
;
in {
imports = [
./git.nix
./packages/git.nix
./packages/nextcloud.nix
./packages/oh-my-posh.nix
./packages/rclone.nix
./hardware.nix
./i18n.nix
./os.nix
./partition.nix
./software.nix
./users.nix

View file

@ -1,24 +1,18 @@
{ lib, config, ... }:
let
inherit (lib)
mkOption
mkDefault
mkEnableOption
mkIf
mkOption
types
;
setupUser = config.valhalla.setupUser.name;
capitalize = (import ../text.nix { inherit lib; }).capitalize;
winType = types.submodule (
{ config, ... }: {
in {
options = {
setupUser = mkOption {
type = types.str;
description = "The name of the user for setting up Windows.";
default = capitalize setupUser;
};
valhalla = {
windows = {
dualboot = {
enable = mkEnableOption "dual boot";
@ -41,19 +35,13 @@
dynamicLighting = mkEnableOption "dynamic lighting";
adware = mkEnableOption "adware"; # Fuck you for displaying ads on an OS I fricking paid for!
};
};
};
config = {
dualboot.linuxPercentage = mkIf (!config.dualboot.enable) 0;
};
});
in {
options = {
valhalla = {
windows = mkOption {
type = winType;
description = "The options for setting up Windows.";
default = {};
};
valhalla.windows = {
setupUser.name = mkDefault (capitalize config.valhalla.setupUser.name);
dualboot.linuxPercentage = mkIf (!config.valhalla.windows.dualboot.enable) (mkDefault 0);
};
};
}

View file

@ -11,7 +11,7 @@
linuxPercentage = 30;
};
users.Manuel = {
users.manuel = {
microsoftAccount = true;
groups = ["Administrators"];
};

View file

@ -3,6 +3,7 @@
fs = import ../../lib/modules/partition/fs.nix;
in {
imports = [
../manuel/config.nix
../../lib/modules/valhalla.nix
];
@ -44,7 +45,10 @@
"wheel"
"nix-users"
];
};
};
linux.users.manuel = {
defaultShell = "fish";
rclone = {
@ -58,6 +62,25 @@
};
};
};
windows.users.manuel = {
nextcloud = {
folderSyncs =
let
localPath = "C:/tools/RetroArch-Win64";
remotePath = "/Saved Games/RetroArch";
in [
{
remotePath = "${remotePath}/Saves";
localPath = "${localPath}/saves";
virtualFiles = false;
}
{
remotePath = "${remotePath}/System";
localPath = "${localPath}/system";
}
];
};
};
timeZone = "Europe/Zurich";

View file

@ -0,0 +1,23 @@
{ ... }: {
imports = [
../../lib/modules/valhalla.nix
];
config = {
valhalla = {
users.manuel = {
oh-my-posh = {
theme = {
source = ./manuel.omp.json;
};
};
};
partition = {
os = {
partitions = { };
};
};
};
};
}

View file

@ -0,0 +1,173 @@
{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"version": 2,
"blocks": [
{
"type": "prompt",
"alignment": "left",
"segments": [
{
"type": "os",
"style": "diamond",
"leading_diamond": "\ue0b6",
"trailing_diamond": "\ue0b4",
"background_templates": [
"{{ if eq .OS \"ubuntu\" }}#EA531A{{ end }}",
"{{ if eq .OS \"debian\" }}#D80150{{ end }}",
"{{ if eq .OS \"arch\" }}#1793D1{{ end }}"
],
"foreground": "p:white",
"template": "{{ if ne .OS \"windows\" }}{{ .Icon }} {{ end }}"
},
{
"type": "session",
"style": "diamond",
"leading_diamond": "\ue0b6",
"trailing_diamond": "\ue0b0",
"background": "p:yellow",
"foreground": "p:black",
"properties": {
"display_host": false
},
"template": " {{ if .SSHSession }}\ueb39 {{ end }}{{ .UserName }} "
},
{
"type": "path",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"background": "p:orange",
"foreground": "p:black",
"properties": {
"home_icon": "~",
"style": "folder"
},
"template": " \udb80\ude4b {{ path .Path .Location }} "
},
{
"type": "dotnet",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"foreground": "p:black",
"background": "#00ffff",
"template": " \udb81\ude10 {{ .Full }} "
},
{
"type": "java",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"background": "#4063d8",
"template": " \udb82\udf37 {{ .Full }} "
},
{
"type": "python",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"background": "#906cff",
"template": " \udb80\udf20 {{ .Full }} "
},
{
"type": "git",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"trailing_diamond": "\ue0b4",
"background": "p:green",
"background_templates": [
"{{ if or (.Working.Changed) (.Staging.Changed) }}p:yellow{{ end }}",
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:red{{ end }}",
"{{ if gt .Ahead 0 }}#49416D{{ end }}",
"{{ if gt .Behind 0 }}#7A306C{{ end }}"
],
"foreground": "p:black",
"foreground_templates": [
"{{ if or (.Working.Changed) (.Staging.Changed) }}p:black{{ end }}",
"{{ if and (gt .Ahead 0) (gt .Behind 0) }}p:white{{ end }}",
"{{ if gt .Ahead 0 }}p:white{{ end }}"
],
"properties": {
"branch_max_length": 25,
"fetch_stash_count": true,
"fetch_status": true,
"fetch_upstream_icon": true,
"upstream_icons": {
"codeberg.org": "\uf330 ",
"git.nuth.ch": "\uf335",
"git.jonascosta.ch": "\uf339 ",
"git.romhackersworld.eu": "\uf339 ",
"aur.archlinux.org": "\uf303 "
}
},
"templates": [
"{{ if .UpstreamURL }} {{ url .UpstreamIcon .UpstreamURL }}{{ end }}",
" {{ .HEAD }} ",
"{{ if .BranchStatus }}{{ .BranchStatus }} {{ end }}",
"{{ if .Working.Changed }} \uf044 {{ .Working.String }} {{ end }}",
"{{ if and (.Working.Changed) (or (.Staging.Changed) (gt .StashCount 0)) }} | {{ end }}",
"{{ if .Staging.Changed }} \uf046 {{ .Staging.String }} {{ end }}",
"{{ if and (.Staging.Changed) (gt .StashCount 0) }} | {{ end }}",
"{{ if gt .StashCount 0 }} \udb80\udd93 {{ .StashCount }}{{ end }} "
]
},
{
"type": "node",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"background": "#6ca35e",
"foreground": "p:white",
"properties": {
"fetch_version": true
},
"template": " \udb80\udf99 {{ if .PackageManagerIcon }}{{ .PackageManagerIcon }} {{ end }}{{ .Full }} "
},
{
"type": "root",
"style": "powerline",
"powerline_symbol": "\ue0b0",
"background": "p:yellow",
"foreground": "p:white",
"properties": {
"root_icon": "\uf0e7"
}
},
{
"type": "executiontime",
"style": "plain",
"background": "#83769c",
"foreground": "p:white",
"properties": {
"always_enabled": true
},
"template": "<transparent>\ue0b0</> \udb81\udead {{ .FormattedMs }}\u2800"
},
{
"type": "text",
"style": "diamond",
"background": "p:blue",
"trailing_diamond": "\ue0b4",
"background_templates": [
"{{ if gt .Code 0 }}p:red{{ end }}"
],
"foreground": "p:white",
"properties": {
"always_enabled": true
},
"template": "<parentBackground>\ue0b0</> {{ if gt .Code 0 }}\uf00d{{ else }}\uf00c{{ end }} "
}
]
}
],
"transient_prompt": {
"background": "transparent",
"foreground": "p:black",
"template": "<p:yellow,transparent>\ue0b6</><,p:yellow> {{ .Folder }} </><p:yellow,transparent>\ue0b0</> "
},
"final_space": true,
"palette": {
"black": "#262B44",
"blue": "#4B95E9",
"green": "#59C9A5",
"orange": "#F07623",
"red": "#D81E5B",
"white": "#E0DEF4",
"yellow": "#F3AE35"
}
}

View file

@ -68,8 +68,9 @@ $null = New-Module {
$downloadChecker = {
$files = Get-ChildItem $dir;
if ((@($files)).Count -gt 0) {
foreach ($file in $files) {
if ((@($files)).Count -eq 1) {
$file = $files[0];
try {
$stream = [System.IO.File]::Open($file.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None);
@ -80,7 +81,6 @@ $null = New-Module {
catch {
return $true;
}
}
return $false;
} else {
@ -110,7 +110,7 @@ $null = New-Module {
$result;
}
catch {
throw $Error;
Write-Error $Error;
}
}
}
@ -127,12 +127,16 @@ $null = New-Module {
.PARAMETER OutDir
The directory to download the file to.
.PARAMETER Timeout
The number of seconds to wait before clicking the download button.
#>
function Start-BrowserDownload {
param(
[string] $URL,
[string] $ButtonSelector,
[string] $OutDir = $null
[string] $OutDir = $null,
[double] $Timeout = 0
)
Start-CustomBrowserDownload @PSBoundParameters -Action {
@ -153,10 +157,14 @@ $null = New-Module {
}
}
if ($Timeout -gt 0) {
Start-Sleep $Timeout;
}
if ($element) {
$Browser.FindElement([OpenQA.Selenium.By]::CssSelector($ButtonSelector)).Click();
$Browser.FindElement($selector).Click();
} else {
throw "Unable to find download button!";
Write-Error "Unable to find download button!";
}
};
}

View file

@ -4,17 +4,24 @@ using namespace System.Security.Principal;
enum SetupStage {
Idle
Initialize
OneShot
Configure
Install
CreateUser
ConfigureUser
}
enum UserStage {
Create
Configure
Cleanup
Completed
}
$null = New-Module {
[string] $configRoot = "HKLM:\Software\PortValhalla";
[string] $stageOption = "Stage";
[string] $userOption = "SetupUser";
[string] $userStageOption = "UserStage";
[string] $accountOption = "MSAccount";
[string] $finishedOption = "Finished";
[RegistryKey] $key = $null;
@ -30,6 +37,11 @@ $null = New-Module {
[string] $Path
)
& {
$ErrorActionPreference = 'Continue';
$completed = $false;
while (-not $completed) {
$job = Start-Job {
$env:Value = Resolve-Path $Using:Path;
$env:WSLENV = "Value/p";
@ -37,7 +49,24 @@ $null = New-Module {
wsl -e printf "%q" "$result";
};
Receive-Job -Wait $job;
$result = Receive-Job -Wait $job;
if ((Split-Path -Leaf $Path) -ne (Split-Path -Leaf $result)) {
Write-Error "The result of the path conversion of ``$Path`` was unexpected: ``$result``";
continue;
}
if ($job.State -ne ([System.Management.Automation.JobState]::Completed)) {
Write-Error "An error occurred while converting ``$Path`` to a Linux path.`nOutput: ``$result``";
continue;
}
$completed = $true;
}
$result;
};
}
<#
@ -79,6 +108,8 @@ $null = New-Module {
$scriptPath = "$PSScriptRoot/../../Common/Scripts/config.fish";
if ($env:CONFIG_MODULE) {
$output = & {
if (-not $IsWindows) {
$escapedPath = (fish -c 'string escape $argv' "$scriptPath");
fish -c ". $escapedPath; $Script";
@ -87,11 +118,23 @@ $null = New-Module {
wsl --shell-type login -- nix --extra-experimental-features "nix-command flakes" run nixpkgs`#fish -- $args
}
fish -c ". $(ConvertTo-LinuxPath $scriptPath); $Script" | ConvertFrom-Json;
}
$output = fish -c ". $(ConvertTo-LinuxPath $scriptPath); $Script";
if (-not $?) {
throw "The configuration could not be retrieved!";
Write-Error "The configuration could not be retrieved!";
} else {
$output;
}
}
}
if (-not ($output | Test-Json)) {
Write-Error "The value ``$output`` is not valid JSON.";
} else {
$output | ConvertFrom-Json;
}
} else {
$null;
}
}
@ -112,6 +155,22 @@ $null = New-Module {
Invoke-ConfigScript "getConfig $Name --json $ArgumentList";
}
<#
.SYNOPSIS
Gets the name of the config root.
#>
function Get-ConfigRootName {
return "valhalla.$($IsWindows ? "windows" : "linux")";
}
<#
.SYNOPSIS
Gets the name of the user root.
#>
function Get-UserRootName {
return "$(Get-ConfigRootName).$($IsWindows ? "winUsers" : "users")";
};
<#
.SYNOPSIS
Gets a user configuration.
@ -124,13 +183,13 @@ $null = New-Module {
#>
function Get-UserConfig {
param(
[string] $UserName = $env:UserName,
[string] $UserName = ($IsWindows ? $env:UserName : $env:USER),
[Parameter(Mandatory, Position = 0)]
[string] $Name
)
if ((Get-Users) -contains $UserName) {
Get-Config "valhalla.windows.users.$UserName.$Name";
Get-Config "$(Get-UserRootName).$UserName.$Name";
} else {
return $null;
}
@ -158,7 +217,7 @@ $null = New-Module {
function Get-Users {
[OutputType([string[]])]
param()
Get-Attributes "valhalla.windows.users";
Get-Attributes "$(Get-UserRootName)";
}
<#
@ -168,7 +227,7 @@ $null = New-Module {
function Get-SetupUser {
[OutputType([string])]
param()
Get-Config "valhalla.windows.setupUser";
Get-Config "$(Get-ConfigRootName).setupUser.name";
}
<#
@ -245,12 +304,91 @@ $null = New-Module {
$null = Set-SetupOption $stageOption $Name;
}
<#
.SYNOPSIS
Gets the current user to set up.
#>
function Get-CurrentUser {
return (Get-SetupOption $userOption) ?? 0;
}
<#
.SYNOPSIS
Sets the index of the current user to set up.
.PARAMETER Value
The index of the user to set up.
#>
function Set-CurrentUser {
param(
[int] $Value
)
Set-SetupOption $userOption $value;
}
<#
.SYNOPSIS
Gets the name of the current stage of the user setup.
#>
function Get-UserStage {
$stage = Get-SetupOption $userStageOption;
if ($null -ne $stage) {
$stage = [UserStage]$stage;
}
return $stage;
}
<#
.SYNOPSIS
Sets the current stage of the user setup.
.PARAMETER Name
The name of the stage to set.
#>
function Set-UserStage {
param(
$Name
)
if (-not (($null -eq $Name) -or ($Name -is [string]))) {
$Name = ([UserStage]$Name).ToString();
}
$null = Set-SetupOption $userStageOption $Name;
}
<#
.SYNOPSIS
Gets the name of the microsoft account to create.
#>
function Get-MSAccountName {
return Get-SetupOption $accountOption;
}
<#
.SYNOPSIS
Sets the name of the microsoft account to create.
.PARAMETER Name
The name of the microsoft account to create.
#>
function Set-MSAccountName {
param(
[string] $Name
)
Set-SetupOption $accountOption $Name;
}
<#
.SYNOPSIS
Gets a value indicating whether the setup has finished.
#>
function Get-IsFinished {
return [bool] (((Get-Stage) -eq ([SetupStage]::Idle)) -or (Get-SetupOption $finishedOption));
return [bool](Get-SetupOption $finishedOption);
}
<#
@ -277,7 +415,15 @@ $null = New-Module {
[string] $Name
)
Get-Config "valhalla.software.$Name";
Get-Config "$(Get-ConfigRootName).software.$Name";
}
<#
.SYNOPSIS
Checks whether the running system is a QEMU virtual machine.
#>
function Test-Qemu {
((Get-WmiObject win32_computersystem).Manufacturer) -eq "QEMU";
}
<#
@ -285,7 +431,7 @@ $null = New-Module {
Checks whether the current user is the setup user.
#>
function Test-SetupUser {
$env:UserName -eq (Get-Config "valhalla.windows.setupUser");
($IsWindows ? $env:UserName : $env:USER) -eq (Get-SetupUser);
}
<#

View file

@ -1,7 +1,11 @@
using namespace System.Management.Automation.Host;
. "$PSScriptRoot/Config.ps1";
. "$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/../Types/OneShotTask.ps1";
@ -12,6 +16,10 @@ $null = New-Module {
# ToDo: Store "ProgramData/PortValhalla" path somewhere as const
$errorPath = "$env:ProgramData/PortValhalla/error.txt";
$getUserName = {
"$(Get-SetupUser)OneShot";
};
$taskSetter = {
param([OneShotTask] $Task)
Set-SetupOption $taskOption ([string]$Task);
@ -19,10 +27,22 @@ $null = New-Module {
function Start-Operation {
param(
[switch] $NonInteractive = ($null -ne (Get-OneShotTask)),
[switch] $NoImplicitCleanup,
[scriptblock] $Action
)
$Global:ErrorActionPreference = 'Inquire';
$cleanup = { };
if (-not $Global:InOperation) {
if ($env:DEBUG) {
Set-PSDebug -Trace 1;
}
$Global:InOperation = $true;
$Global:ErrorActionPreference = $NonInteractive.IsPresent ? 'Continue' : 'Inquire';
if ($IsWindows) {
$env:WSLENV = "CONFIG_MODULE/p";
if ($env:CONFIG_MODULE) {
@ -34,15 +54,202 @@ $null = New-Module {
}
New-Alias -Force "sudo" gsudo;
}
if (-not $NoImplicitCleanup.IsPresent) {
$cleanup = {
Clear-OperationResources;
};
}
& {
$initialized = $false;
while (-not $initialized) {
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;
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/../Software/winget/Manage.ps1";
continue;
}
if (-not (Test-Command "git")) {
Install-WingetPackage Git.Git;
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 (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 $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;
$initialized = $true;
}
}
}
}
if ((Get-OneShotTask)) {
Start-OneShot;
} else {
& $Action;
}
& $cleanup;
}
<#
.SYNOPSIS
Gets the current OneShot task.
#>
function Get-OneShotTask {
[OneShotTask](Get-SetupOption $taskOption);
$task = Get-SetupOption $taskOption;
if ($task) {
return [OneShotTask]$task;
} else {
return $null;
}
}
<#
@ -51,12 +258,23 @@ $null = New-Module {
#>
function Enable-OneShotListener {
$tempTask = "PortValhalla Temp";
$action = New-ScheduledTaskAction -Execute "pwsh" -Argument (Get-StartupArguments);
$user = & $getUserName;
$password = [string]([guid]::NewGuid());
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
$null = New-LocalUser -Name $user -Password (ConvertTo-SecureString -AsPlainText $password);
Add-LocalGroupMember -Member $user @adminGroup;
$path = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList";
$null = New-Item -Force -ErrorAction SilentlyContinue $path;
Set-ItemProperty $path -Name $user -Value 0;
$action = New-ScheduledTaskAction -Execute "pwsh" -Argument "-Command & { $([string](Get-StartupCommand)) } 2>&1 | Tee-Object -FilePath `$env:ProgramData/PortValhalla/OneShotTask.log";
schtasks /Create /SC ONEVENT /EC $logName /MO "*[System[Provider[@Name='$logName'] and EventID=$($oneShotTrigger)]]" /TR cmd.exe /TN $tempTask;
$trigger = (Get-ScheduledTask $tempTask).Triggers;
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest;
$task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger;
$null = Register-ScheduledTask -Force $oneShotTaskName -InputObject $task;
$null = Register-ScheduledTask -Force $oneShotTaskName -Action $action -Trigger $trigger -RunLevel Highest -User $user -Password $password;
$null = Unregister-ScheduledTask -Confirm:$false $tempTask;
}
@ -66,6 +284,10 @@ $null = New-Module {
#>
function Disable-OneShotListener {
Unregister-ScheduledTask -Confirm:$false $oneShotTaskName;
$user = Get-LocalUser (& $getUserName);
[string] $sid = $user.SID;
Remove-LocalUser $user;
Get-CimInstance Win32_UserProfile | Where-Object { $_.SID -eq $sid } | Remove-CimInstance;
}
<#
@ -80,8 +302,6 @@ $null = New-Module {
[OneShotTask] $Task
)
$currentStage = Get-Stage;
Set-Stage ([SetupStage]::OneShot);
& $taskSetter $Task;
& {
@ -104,16 +324,19 @@ $null = New-Module {
};
Write-EventLog -LogName $logName -Source $logName -EventId $oneShotTrigger -Message "Starting OneShot task ``$(Get-OneShotTask)``";
Remove-Event -EventIdentifier (Wait-Event -SourceIdentifier $identifier).EventIdentifier;
$null = Wait-Event -SourceIdentifier $identifier;
};
Set-Stage $currentStage;
for ($i = 0; $i -lt 2; $i++) {
Remove-Event -EventIdentifier (Wait-Event -SourceIdentifier $identifier).EventIdentifier;
}
};
if (Test-Path $errorPath) {
$errorMessage = Get-Content $errorPath;
Remove-Item $errorPath;
throw $errorMessage;
if ($errorMessage) {
Write-Error $errorMessage;
}
}
}
@ -124,19 +347,36 @@ $null = New-Module {
Executes the specified action and notifies the OneShot task executor.
#>
function Start-OneShot {
param(
[scriptblock] $Action
)
try {
Start-Operation @PSBoundParameters;
Write-Host "Running OneShot task ``$(Get-OneShotTask)``";
Start-Operation {
switch (Get-OneShotTask) {
([OneShotTask]::InitializeMSAccount) {
Initialize-UserCreation;
}
catch {
Set-Content -Path $errorPath -Value $Error;
}
finally {
Set-Stage ([SetupStage]::Idle);
Write-EventLog -LogName $logName -Source $logName -EventId $oneShotTrigger -Message "The OneShot task ``$(Get-OneShotTask)`` finished.";
([OneShotTask]::DisableUAC) {
Disable-UAC;
Register-Setup;
}
}
};
}
catch {
Set-Content -Path $errorPath -Value $Error;
Set-UserPermissions $errorPath;
}
finally {
& $taskSetter $null;
Write-EventLog -LogName $logName -Source $logName -EventId $oneShotTrigger -Message "The OneShot task ``$(Get-OneShotTask)`` finished.";
}
}
<#
.SYNOPSIS
Clears resources allocated during the operation.
#>
function Clear-OperationResources {
Uninstall-WslDistribution;
}
};

View file

@ -51,6 +51,7 @@ function Write-PSScript {
Import-Module PSScriptAnalyzer;
$dirName = Split-Path -Parent $FileName;
$Script = ($Script -split "\r?\n") -join [System.Environment]::NewLine;
$content = Invoke-Formatter -ScriptDefinition $Script;
$exists = Test-Path -PathType Leaf $FileName;

View file

@ -241,20 +241,21 @@ $null = New-Module {
Write-Host "Installing $Name";
& $Installer @argumentList;
}
& $installHandler @argumentList -Action ([InstallerAction]::Configure);
if ($UserConfigurator -and (-not (Test-SetupUser))) {
& $installHandler @argumentList -Action ([InstallerAction]::ConfigureUser);
}
# ToDo: Automatically configure after installation
} elseif ($Action -eq ([InstallerAction]::Configure)) {
if ($Configurator) {
Write-Host "Configuring $Name";
& $Configurator @argumentList;
}
if (-not (Test-SetupUser)) {
$argumentList.Add("action", [InstallerAction]::ConfigureUser);
& $installHandler @argumentList;
}
} elseif ($Action -eq ([InstallerAction]::ConfigureUser)) {
if ((-not $Arguments.ContainsKey($userArgument)) -or (-not $Arguments[$userArgument])) {
$Arguments.Add($userArgument, ($env:UserName));
$Arguments.Add($userArgument, ($IsWindows ? $env:UserName : $env:USER));
}
if ($UserConfigurator) {

View file

@ -103,3 +103,18 @@ function Test-PSPackage {
[bool] (Get-Package $Name -ErrorAction SilentlyContinue);
}
<#
.SYNOPSIS
Checks whether a module with the specified name is installed.
.PARAMETER Name
The name of the module to check.
#>
function Test-PSModule {
param(
[string] $Name
)
[bool](Get-Module -ListAvailable $Name -ErrorAction SilentlyContinue);
}

View file

@ -30,6 +30,27 @@ function Remove-DesktopIcon {
}
}
<#
.SYNOPSIS
Adds a new shortcut to the start menu.
.PARAMETER Name
The name of the icon to create.
.PARAMETER Target
The file to link to.
#>
function Add-StartMenuIcon {
param(
[string] $Name,
[string] $Target
)
Import-Module KnownFolders;
Import-Module "$env:ChocolateyInstall/helpers/chocolateyInstaller.psm1";
Install-ChocolateyShortcut -ShortcutFilePath "$((Get-KnownFolder "Common Programs").Path)/$Name.lnk" -TargetPath ((Get-Item $Target).FullName);
}
<#
.SYNOPSIS
Removes icons from the task bar.

View file

@ -3,18 +3,12 @@ param (
[hashtable] $Arguments
)
. "$PSScriptRoot/../aliae/Manage.ps1";
. "$PSScriptRoot/../PowerShell/Profile.ps1";
. "$PSScriptRoot/../../Scripts/Software.ps1";
. "$PSScriptRoot/../../Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
Add-PowerShellProfileStatement `
-System `
@ -25,4 +19,39 @@ Start-SoftwareInstaller @PSBoundParameters `
(Get-ScriptInitializer "oh-my-posh init pwsh"),
(Get-ScriptInitializer "oh-my-posh completion powershell")
) -join [System.Environment]::NewLine)
} `
-UserConfigurator {
param(
[hashtable] $Arguments
)
$theme = Get-UserConfig "oh-my-posh.theme";
if ($theme) {
$varName = "POSH_THEME";
if ($theme -isnot [string]) {
$root = "$($IsWindows ? $env:AppData : "~/.config")/oh-my-posh";
$path = Join-Path $root "$($theme.name).omp.json";
$null = New-Item -Force -ItemType Directory $root;
Set-Content $path (
& {
if ($IsWindows) {
wsl cat $theme.source
} else {
cat $theme.source
}
});
$theme = [string] $path;
}
if ($IsWindows) {
[System.Environment]::SetEnvironmentVariable($varName, $path, "User");
} else {
. "$PSScriptRoot/../aliae/Manage.ps1";
Add-EnvironmentVariable -User $Arguments.Name $varName $path;
}
}
};

View file

@ -8,13 +8,6 @@ param (
. "$PSScriptRoot/../../Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
[string] $globalDir = $null;
$indicator = "# Profile Files";

View file

@ -8,11 +8,18 @@ $null = New-Module {
.PARAMETER Name
The name of the module to install.
.PARAMETER NativeOnly
A value indicating whether the module is installed in Windows PowerShell only.
.PARAMETER NoProfile
A value indicating whether the module is not added to the profile script of users.
#>
function Get-ModuleInstallerComponents {
param(
[string] $Name,
[switch] $NativeOnly
[switch] $NativeOnly,
[switch] $NoProfile
)
@{
@ -27,7 +34,14 @@ $null = New-Module {
)
$env:PENDING_MODULE_NAME = $Arguments.Name;
$installAction = { Install-Module -Scope AllUsers -Force $env:PENDING_MODULE_NAME @args };
$installAction = {
$module = $env:PENDING_MODULE_NAME;
if (-not (Get-Module -ListAvailable $module -ErrorAction SilentlyContinue)) {
Install-Module -Scope AllUsers -Force $module @args;
}
};
if (-not $Arguments.NativeOnly) {
& $installAction -AcceptLicense;
@ -41,7 +55,7 @@ $null = New-Module {
& $Installer -Action ([InstallerAction]::Configure) @PSBoundParameters;
};
configurator = {
configurator = ($NoProfile.IsPresent) ? { } : {
param(
[hashtable] $Arguments
)

View file

@ -0,0 +1,15 @@
<#
.SYNOPSIS
Gets a powershell expression which points to the global `aliae` configuration.
#>
function Get-GlobalConfigExpression {
return "`"$($IsWindows ? "`$env:ProgramData" : "/etc")/aliae/aliae.yml`"";
}
<#
.SYNOPSIS
Gets the path to the global `aliae` configuration.
#>
function Get-GlobalConfigPath {
return & ([scriptblock]::Create((Get-GlobalConfigExpression)));
}

View file

@ -0,0 +1,50 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/Constants.ps1";
. "$PSScriptRoot/../PowerShell/Profile.ps1";
. "$PSScriptRoot/../../Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Configurator {
. "$PSScriptRoot/Constants.ps1";
$pathExpression = Get-GlobalConfigExpression;
$path = Get-GlobalConfigPath;
$null = New-Item -Force -ItemType Directory (Split-Path -Parent $path);
Copy-Item -Force "$PSScriptRoot/aliae.yml" $path;
Add-PowerShellProfileStatement `
-System `
-Category "aliae" `
-Script (
@(
{
#aliae
},
"`$globalPath = $pathExpression",
{
$userPath = & {
if ($env:ALIAE_CONFIG) {
$env:ALIAE_CONFIG;
} else {
"~/aliae.yaml";
}
};
if (Test-Path $globalPath) {
& ([scriptblock]::Create((aliae init pwsh --config $globalPath)));
}
if (Test-Path $userPath) {
& ([scriptblock]::Create((aliae init pwsh)));
}
aliae completion powershell | Out-String | Invoke-Expression;
}
) -join [System.Environment]::NewLine)
} `
-UserConfigurator {
Copy-Item -Force "$PSScriptRoot/aliae.yml" ~/.aliae.yml;
};

View file

@ -0,0 +1,98 @@
$null = New-Module {
. "$PSScriptRoot/Constants.ps1";
<#
.SYNOPSIS
Adds an alias to an existing `aliae` configuration.
.PARAMETER Name
The name of the alias to add.
.PARAMETER Value
The script the alias should point to.
.PARAMETER User
The user to add the alias to.
#>
function Add-Alias {
param(
[string] $Name,
[string] $Value,
[string] $User
)
Edit-Config `
-Variables @{
Name = "$Name";
Value = "$Value";
} `
".alias |= [((. // [])[] | select(.name != env.Name))] + [{ name: env.Name, value: env.Value }]" `
-User $User;
}
<#
.SYNOPSIS
Adds an environment variable to an existing `aliae` configuration.
.PARAMETER Name
The name of the variable to add.
.PARAMETER Value
The value of the variable.
#>
function Add-EnvironmentVariable {
param(
[string] $Name,
[string] $Value,
[string] $User
)
Edit-Config `
-Variables @{
Name = "$Name";
Value = "$Value";
} `
".env |= [((. // [])[] | select(.name != env.Name))] + [{ name: env.Name, value: env.Value }]" `
-User $User;
}
<#
.SYNOPSIS
Edits the underlying `aliae` configuration.
.PARAMETER Script
The yq script to run over the configuration.
.PARAMETER User
The user to edit the configuration for.
#>
function Edit-Config {
param(
[string] $Script,
[hashtable] $Variables,
[string] $User
)
if ($User) {
$path = "$($IsWindows ? "~" : "$(sudo -u $User bash -c "realpath ~")")/.aliae.yaml";
} else {
$path = Get-GlobalConfigPath;
}
Start-Job {
$file = New-TemporaryFile;
$variables = $using:Variables;
foreach ($key in $variables.Keys) {
Set-Item "Env:\$key" $variables[$key];
}
sudo -u $using:User cp $using:path $file;
yq -yi $using:Script $file;
sudo -u $using:User cp $file $using:path;
Remove-Item $file;
} | Receive-Job -Wait;
}
Export-ModuleMember -Function Add-Alias,Add-EnvironmentVariable;
};

View file

@ -1,22 +1,4 @@
alias:
- name: totsch
value: git
env:
- name: POSH_THEME
value: '{{ if eq .OS "windows" }}{{ .Home }}/Nextcloud/.omp{{ else }}/usr/local/share/oh-my-posh/themes{{ end }}/manuel.omp.json'
alias: []
env: []
path: []
script:
- value: |
# Profile Files
$profileRoot = Split-Path -Parent $PROFILE;
$profilePaths = @(
"$profileRoot/conf.d/*.ps1",
"{{ if eq .OS "windows" }}$env:ProgramData{{ else }}/etc{{ end }}/powershell/conf.d/*.ps1"
);
foreach ($profilePath in $profilePaths) {
if (Test-Path $profilePath) {
Get-Item $profilePath | ForEach-Object { . $_; };
}
}
if: match .Shell "pwsh"
script: []

View file

@ -10,28 +10,35 @@ begin
function configureSW -V dir
source "$dir/../bash/profile.fish"
source "$dir/../fish/profile.fish"
set -l file /etc/aliae/aliae.yml
echo "export ALIAE_CONFIG=$(string escape "$file")" | sudo tee /etc/profile.d/aliae.sh > /dev/null
set -l file (pwsh -CommandWithArgs '. $args[0]; Get-GlobalConfigPath' "$dir/Constants.ps1");
sudo install -Dm644 "$dir/aliae.yml" "$file"
begin
printf %s\n \
"# aliae" \
"if [ -f $(string escape $file) ]" \
'then' \
" eval \"\$(aliae init bash --config $(string escape $file))\"" \
'fi' \
'' \
'if [ -n "$ALIAE_CONFIG" ] && [ -f "$ALIAE_CONFIG" ] || [ -f ~/.aliae.yaml ]' \
'then' \
' eval "$(aliae init bash)"' \
'fi' \
'' \
'eval "$(aliae completion bash)"'
end | installBashProfile "aliae" "aliae"
begin
printf %s\n "" \
"# aliae" \
'eval "$(aliae init bash)"' \
'eval "$(aliae completion bash)"'
end | sudo tee /etc/skel/.bashrc > /dev/null
if type -q fish
begin
printf %s\n \
"aliae init fish | source" \
"if [ -f $(string escape $file) ]" \
" eval \"\$(aliae init bash --config $(string escape $file))\"" \
'end' \
'' \
'if [ -n "$ALIAE_CONFIG" ] && [ -f "$ALIAE_CONFIG" ] || [ -f ~/.aliae.yaml ]' \
' aliae init fish | source' \
'end' \
'' \
"aliae completion fish | source"
end | installFishProfile "aliae" "aliae"
end

View file

@ -4,15 +4,123 @@ param (
)
. "$PSScriptRoot/../../Scripts/Software.ps1";
. "$PSScriptRoot/../../Scripts/System.ps1";
. "$PSScriptRoot/../../Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
$null = New-Module {
param(
[scriptblock] $Installer
[hashtable] $Parameters
)
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
$configure = {
param(
[string] $User
)
$root = "valhalla";
if ($User) {
$root = "$root$($IsWindows ? ".windows" : '').users.$User";
$sudoArgs = @("-u", $User);
$configArgs = @("--global");
} else {
$sudoArgs = @();
$configArgs = @("--system");
}
<#
.SYNOPSIS
Gets the specified git configuration.
.PARAMETER Name
THe name of the configuration to get.
#>
function Get-GitConfig {
param(
[string] $Name
)
Get-Config "$root.git.$Name";
}
<#
.SYNOPSIS
Sets a configuration option in git.
#>
function Set-GitConfig {
sudo @sudoArgs git config @configArgs $args;
}
if ((-not $IsWindows) -or $User) {
$branch = Get-GitConfig "defaultBranch";
if ($branch) {
Set-GitConfig "init.defaultBranch" $branch;
}
}
if ($User) {
$displayName = Get-UserConfig "displayName";
$mailAddress = Get-UserConfig "mailAddress";
if ($displayName) {
Set-GitConfig "user.name" $displayName;
}
if ($mailAddress) {
Set-GitConfig "user.email" $mailAddress;
}
}
# Git Flow
. {
$dir = New-TemporaryDirectory;
$key = "flow";
$mainBranch = Get-GitConfig "$key.mainBranch";
$devBranch = Get-GitConfig "$key.devBranch";
& {
git -C "$dir" init;
git -C "$dir" config user.name "PortValhalla";
git -C "$dir" config user.email "no-reply@valhal.la";
git -C "$dir" commit --allow-empty -m "Initial commit";
git -C "$dir" branch master;
git -C "$dir" branch dev;
git -C "$dir" flow init --defaults;
} | Out-Null;
if ($mainBranch) {
git -C "$dir" branch $mainBranch | Out-Null;;
sudo @sudoArgs git -C "$dir" flow config set @configArgs master $mainBranch;
}
if ($devBranch) {
git -C "$dir" branch $devBranch | Out-Null;
sudo @sudoArgs git -C "$dir" flow config set @configArgs develop $devBranch;
}
Remove-Item -Recurse -Force $dir;
};
# Aliases
[PSCustomObject] $aliases = Get-GitConfig "aliases";
if ($aliases) {
foreach ($alias in ($aliases | Get-Member -MemberType Properties)) {
Set-GitConfig "alias.$($alias.Name)" $aliases.$($alias.Name);
}
}
};
Start-SoftwareInstaller @Parameters `
-Configurator {
& $configure @PSBoundParameters;
} `
-UserConfigurator {
param(
[hashtable] $Arguments
)
& $configure -User $Arguments.Name;
};
} $PSBoundParameters;

View file

@ -0,0 +1,26 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/SoftwareManagement.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-UserConfigurator {
param(
$Arguments
)
$bins = @("codium", "codium-insiders", "code", "code-insiders");
$extensions = @("zokugun.sync-settings", "zokugun.vsix-manager");
$user = $Arguments.Name;
foreach ($bin in $bins) {
if (Test-Command "$bin") {
foreach ($extension in $extensions) {
sudo -u "$user" "$bin" --install-extension "$extension";
}
}
}
};

View file

@ -2,19 +2,9 @@
begin
set -l dir (status dirname)
source "$dir/../../Scripts/software.fish"
source "$dir/../../../Common/Software/aliae/main.fish"
function userConfig -a name
set -l bins codium codium-insiders code code-insiders
set -l extensions zokugun.{sync-settings,vsix-manager}
for bin in $bins
if type -q "$bin"
for extension in $extensions
sudo -u "$name" "$bin" --install-extension "$extension"
end
end
end
function userConfig -V dir -a name
pwsh "$dir/Main.ps1" ConfigureUser;
end
runInstaller $argv

View file

@ -1,3 +1,4 @@
enum OneShotTask {
InitializeMSAccount
DisableUAC
}

View file

@ -2,6 +2,7 @@
using namespace System.Security.Principal;
. "$PSScriptRoot/../../../scripts/Windows/Scripts/Prerequisites.ps1";
. "$PSScriptRoot/../../../scripts/Windows/Scripts/WSL.ps1";
. "$PSScriptRoot/../../Common/Scripts/Context.ps1";
. "$PSScriptRoot/../Scripts/Security.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1";
@ -9,6 +10,7 @@ using namespace System.Security.Principal;
. "$PSScriptRoot/User/Install.ps1";
$null = New-Module {
. "$PSScriptRoot/../Scripts/Deployment.ps1";
. "$PSScriptRoot/../Scripts/Hooks.ps1";
. "$PSScriptRoot/../Scripts/PowerManagement.ps1";
. "$PSScriptRoot/../Scripts/Registry.ps1";
@ -26,7 +28,7 @@ $null = New-Module {
Finishes the installation of a running Windows machine.
#>
function Start-WindowsInstallation {
Start-Operation {
Start-Operation -NoImplicitCleanup {
Start-InstallationLoop;
};
}
@ -36,124 +38,13 @@ $null = New-Module {
Starts the installation loop.
#>
function Start-InstallationLoop {
$wslLocation = "$env:ProgramData\PortValhalla\Ubuntu";
while (-not (Get-IsFinished)) {
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
[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-Command "gsudo")) {
Install-ChocoPackage gsudo;
refreshenv;
continue;
}
if (-not (Test-Command "git")) {
Install-ChocoPackage git;
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 (-not (Test-Winget)) {
. "$PSScriptRoot/../Software/winget/Manage.ps1";
continue;
}
if (-not (& { $null = wsl --status; $?; })) {
wsl --install --no-launch;
Restart-Intermediate;
return;
}
if (-not (& { $null = wsl -l; $?; })) {
$wslRoot = Split-Path -Parent $wslLocation;
if (-not (Test-Path $wslRoot)) {
$null = New-Item -ItemType Directory $wslRoot;
}
Copy-Item -Recurse (Get-AppxPackage "*Ubuntu*").InstallLocation $wslLocation;
Set-UserPermissions $wslLocation;
& "$wslLocation\ubuntu.exe" install --root;
continue;
}
if (-not (wsl --shell-type login type -t nix)) {
wsl -- sh `<`(curl -L https://nixos.org/nix/install`) --daemon --yes;
wsl --shutdown;
continue;
}
if (-not (Test-PSPackage Selenium.WebDriver)) {
Write-Host "Installing browser automation tools…";
Install-Module -AcceptLicense -Force NuGet;
Import-Module NuGet;
$null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies;
continue;
}
Install-ChocoPackage selenium-gecko-driver firefox;
Invoke-Hook "Install-PSModules" -Fallback {
Install-Module -AcceptLicense -Force PSWindowsUpdate;
Install-Module -AcceptLicense -Force PSScriptAnalyzer;
. "$PSScriptRoot/../Software/PinnedItem/Manage.ps1";
};
Set-Stage ([SetupStage]::Configure);
break;
}
([SetupStage]::OneShot) {
Write-Host "Running a OneShot task";
Start-OneShot {
Write-Host "task is-a running!";
switch (Get-OneShotTask) {
([OneShotTask]::DisableUAC) {
Disable-UAC;
Register-Setup;
}
}
};
break;
}
default {
if (-not (& { $null = wsl -l; $? })) {
wsl --import-in-place "PortValhalla" "$wslLocation/ext4.vhdx";
wsl --set-default "PortValhalla";
}
if (Test-Admin) {
$null = Import-Module PSWindowsUpdate;
@ -167,290 +58,13 @@ $null = New-Module {
}
}
<#
.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 = $null;
$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/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 ($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 `
;
}
}
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 "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/Manage.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"
Install-WingetPackage Ytmdesktop.Ytmdesktop;
Remove-DesktopIcon "Youtube Music*";
}
}
if (Test-Collection "coding") {
if ($install) {
Install-ChocoPackage vscode -ArgumentList "--params","/NoDesktopIcon";
Install-ChocoPackage vscodium -ArgumentList "--params","/NoDesktopIcon /AssociateWithFiles";
Install-ChocoPackage `
gh `
github-desktop `
ida-free `
HxD `
docker-desktop `
imhex `
dotpeek `
;
Remove-DesktopIcon "IDA *";
Remove-DesktopIcon "GitHub*";
Remove-DesktopIcon "Docker*";
}
& "$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 (Get-Stage) {
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";
@ -478,85 +92,7 @@ $null = New-Module {
Set-Stage ([SetupStage]::CreateUser);
}
([SetupStage]::CreateUser) {
Start-ValhallaUserSetup;
Set-Stage ([SetupStage]::ConfigureUser);
}
([SetupStage]::ConfigureUser) {
$userOption = "CurrentUser";
function Get-CurrentUser {
(Get-SetupOption $userOption) ?? 0;
}
function Set-CurrentUser {
param([int] $Value)
Set-SetupOption $userOption $Value;
}
[string[]] $users = Get-Users;
$currentUser = Get-CurrentUser;
if (Test-Admin) {
Disable-BootMessage;
}
if ($currentUser -lt $users.Count) {
$user = Get-LocalUser $users[$currentUser];
$msAccount = Get-UserConfig -UserName "$user" -Name "microsoftAccount";
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
Add-LocalGroupMember `
@adminGroup `
$user `
-ErrorAction SilentlyContinue;
if ($env:UserName -ne "$user") {
Disable-LocalUser $env:UserName;
Enable-LocalUser $user;
if ($msAccount) {
Enable-UAC;
Disable-Autologin;
Enable-OneShotListener;
Set-BootMessage -Caption "Please Log In" -Message "Please log in using your new Microsoft Account ``$user``.";
} else {
Set-AutologinUser "$user";
}
Restart-Intermediate -DefaultUser;
return;
} else {
$configure = {
Deploy-SoftwareAction -Action ([InstallerAction]::ConfigureUser);
Remove-LocalGroupMember -Member "$user" @adminGroup -ErrorAction SilentlyContinue;
foreach ($group in Get-UserConfig "groups") {
Add-LocalGroupMember -Member "$user" -Name "$group";
}
}
if ($msAccount) {
if (-not (Test-Admin)) {
Invoke-OneShot DisableUAC;
Restart-Computer;
return;
} else {
& $configure;
Clear-SetupRegistration;
Disable-OneShotListener;
}
} else {
& $configure;
}
}
Set-CurrentUser ($currentUser + 1);
continue;
}
Install-ValhallaUsers;
Set-IsFinished $true;
}
}

View file

@ -224,12 +224,13 @@ function Start-Setup {
foreach ($xpath in @("./ua:AutoLogon/ua:Username",
"./ua:UserAccounts/ua:LocalAccounts/ua:LocalAccount/ua:Name",
"./ua:UserAccounts/ua:LocalAccounts/ua:LocalAccount/ua:DisplayName")) {
$oobeSettings.SelectSingleNode($xpath, $namespace).InnerText = $valhallaConfig.setupUser;
$oobeSettings.SelectSingleNode($xpath, $namespace).InnerText = $valhallaConfig.setupUser.name;
}
Add-StartupCommand `
-Script (
"powershell -Command " +
($env:DEBUG ? "`$env:DEBUG = $([int]$env:DEBUG);" : "") +
"`$env:PWSH_PATH = $(Get-PathInjection $env:PWSH_PATH);" +
"`$env:INSTALLER_SCRIPT = $(Get-ScriptPathInjection $env:SETUP_SCRIPT_NAME);" +
"`$env:CONFIG_MODULE = $(Get-ScriptPathInjection $env:CONFIG_MODULE);" +

View file

@ -206,12 +206,6 @@
</SynchronousCommand> -->
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<RequiresUserInput>true</RequiresUserInput>
<CommandLine>cmd /C wmic useraccount where name="Admin" set PasswordExpires=false</CommandLine>
<Description>Password Never Expires</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<RequiresUserInput>false</RequiresUserInput>
<CommandLine>powershell -Command "Set-ExecutionPolicy -Force Bypass"</CommandLine>
<Description>Allow PowerShell scripts from anywhere.</Description>

View file

@ -0,0 +1,293 @@
. "$PSScriptRoot/../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1";
. "$PSScriptRoot/../../Common/Types/InstallerAction.ps1";
<#
.SYNOPSIS
Deploys an action for each software selected for installation.
.PARAMETER
The action to execute.
#>
function Deploy-SoftwareAction {
param(
[System.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;
}
};
& {
$softwarePath = "$PSScriptRoot/../Software";
$commonSoftware = "$PSScriptRoot/../../Common/Software";
# Windows Config
& "$softwarePath/Windows/Manage.ps1" @arguments;
if (Get-Config "valhalla.hardware.logitechG") {
& "$softwarePath/LGHub/Manage.ps1" @arguments;
}
# Essentials
if (Test-Collection "essential") {
& "$softwarePath/aliae/Main.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-Icon/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 `
;
}
}
# Common Software
if (Test-Collection "common") {
& "$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 "*HWMonior*";
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*";
# When installing Jellyfin Media Player after iCUE, Jellyfin will try to reboot automatically
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) {
& "$softwarePath/vscode/Main.ps1" @arguments;
Install-ChocoPackage `
gh `
github-desktop `
ida-free `
HxD `
docker-desktop `
imhex `
dotpeek `
;
Remove-DesktopIcon "IDA *";
Remove-DesktopIcon "GitHub*";
Remove-DesktopIcon "Docker*";
}
& "$softwarePath/VisualStudio/Manage.ps1" @arguments;
# Node.js
& "$softwarePath/NVS/Manage.ps1" @arguments;
}
# Gaming
if (Test-Collection "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;
}
};
}

View file

@ -26,7 +26,7 @@ $null = New-Module {
[string] $path = $null;
if ($UserKey) {
$path = "$($UserKey.PSPath)\$runOncePath";
$path = Join-Path ($UserKey.PSPath) $runOncePath;
} else {
$path = $systemRunOncePath;
}
@ -43,22 +43,16 @@ $null = New-Module {
Generates a script for executing the installer.
#>
function Get-StartupScript {
"pwsh " + (Get-StartupArguments);
"pwsh -Command " + (Get-StartupCommand);
}
<#
.SYNOPSIS
Generates arguments for running the installer using `pwsh`.
Generates a command for running the installer using `pwsh`.
#>
function Get-StartupArguments {
"-Command " +
(& {
if ($env:PWSH_PATH) {
"`$env:PWSH_PATH = $(ConvertTo-Injection $env:PWSH_PATH);"
} else {
""
}
}) +
function Get-StartupCommand {
($env:PWSH_PATH ? "`$env:PWSH_PATH = $(ConvertTo-Injection $env:PWSH_PATH);" : "") +
($env:DEBUG ? "`$env:DEBUG = $([int]$env:DEBUG);" : "") +
"`$env:INSTALLER_SCRIPT = $(ConvertTo-Injection (Resolve-Path $env:INSTALLER_SCRIPT));" +
"`$env:CONFIG_MODULE = $(ConvertTo-Injection (Resolve-Path $env:CONFIG_MODULE));" +
"& `$env:INSTALLER_SCRIPT;";
@ -75,6 +69,8 @@ $null = New-Module {
param(
[Parameter(ParameterSetName="System")]
[switch] $System,
[Parameter(ParameterSetName="DefaultUser", Mandatory)]
[switch] $DefaultUser,
[Parameter(ParameterSetName="User", Mandatory)]
[switch] $User,
[Parameter(ParameterSetName="User")]
@ -82,6 +78,18 @@ $null = New-Module {
[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:\";
@ -158,21 +166,22 @@ $null = New-Module {
#>
function Restart-Intermediate {
param(
[switch] $DefaultUser
[Parameter(ParameterSetName="None")]
[switch] $NoRegister,
[Parameter(ParameterSetName="Default", Mandatory)]
[switch] $DefaultUser,
[Parameter(ParameterSetName="Current", Mandatory)]
[switch] $CurrentUser
)
$register = { param($UserKey) Register-Setup @PSBoundParameters; };
if ($DefaultUser) {
Edit-DefaultUserKey {
param(
[RegistryKey] $Key
)
& $register $Key;
}
if (-not $NoRegister.IsPresent) {
if ($DefaultUser.IsPresent) {
Register-Setup -DefaultUser;
} elseif ($CurrentUser.IsPresent) {
Register-Setup -User;
} else {
& $register;
Register-Setup;
}
}
Restart-Computer -Force;

View file

@ -0,0 +1,119 @@
. "$PSScriptRoot/../../Common/Scripts/System.ps1";
$null = New-Module {
$pathResolver = {
param(
[string] $User,
[string] $Path
)
[string] $result = $null;
if ($User) {
$result = "Users/$User";
} else {
$result = "System";
}
$result = Join-Path $result $Path;
return $result;
};
<#
.SYNOPSIS
Gets the name of the variable holding the path to the backup archive of the current machine.
#>
function Get-ArchiveVariableName {
return "BACKUP_ARCHIVE";
}
<#
.SYNOPSIS
Gets the path to the backup archive of the current machine.
#>
function Get-ValhallaBackupArchive {
(Get-Item "Env:\$(Get-ArchiveVariableName)").Value;
}
<#
.SYNOPSIS
Sets the path to the backup archive of the current machine.
.PARAMETER Path
The path to set.
#>
function Set-ValhallaBackupArchive {
param(
[string] $Path
)
Set-Item "Env:\$(Get-ArchiveVariableName)" $Path;
}
<#
.SYNOPSIS
Adds files to the backup archive.
.PARAMETER User
The user to add the files to.
.PARAMETER Source
The file or directory to add to the backup archive.
.PARAMETER Path
The path to the location to store the file or directory at.
.PARAMETER ArgumentList
The arguments to pass to the `7z` command.
#>
function Add-BackupArtifacts {
param(
[string] $User,
[string] $Source,
[string] $Path,
[Parameter(ValueFromRemainingArguments)]
[string[]] $ArgumentList
)
$dir = New-TemporaryDirectory;
$targetPath = & $pathResolver @PSBoundParameters;
$targetPath = Join-Path $dir $targetPath;
$null = New-Item -ItemType Directory -Force $targetPath;
Copy-Item -Force -Recurse $Source $targetPath;
7z a (Get-ValhallaBackupArchive) "$dir/*" @ArgumentList;
Remove-Item -Recurse -Force $dir;
}
<#
.SYNOPSIS
Extracts the specified backup artifacts to the specified target path.
.PARAMETER User
The user to restore the files for.
.PARAMETER Path
The path to restore the files from.
.PARAMETER Target
The path to restore the files to.
.PARAMETER ArgumentList
The arguments to pass to `7z`.
#>
function Expand-BackupArtifacts {
param(
[string] $User,
[string] $Path,
[string] $Target,
[Parameter(ValueFromRemainingArguments)]
[string[]] $ArgumentList
)
$dir = New-TemporaryDirectory;
$sourcePath = & $pathResolver @PSBoundParameters;
7z x "-o$dir" (Get-ValhallaBackupArchive) $sourcePath @ArgumentList;
Copy-Item -Recurse (Join-Path $dir $sourcePath) $Target;
Remove-Item -Recurse -Force $dir;
}
};

View file

@ -55,7 +55,13 @@ $null = New-Module {
[FileSystemAccessRule]::new(
[SecurityIdentifier]::new([WellKnownSidType]::BuiltinUsersSid, $null),
[FileSystemRights]::FullControl,
[InheritanceFlags]::ObjectInherit -bor [InheritanceFlags]::ContainerInherit,
(& {
if (Test-Path -PathType Container $Path) {
[InheritanceFlags]::ObjectInherit -bor [InheritanceFlags]::ContainerInherit
} else {
0
}
}),
[PropagationFlags]::InheritOnly,
[AccessControlType]::Allow));

View file

@ -7,12 +7,14 @@ function Update-WindowsInstallation {
Runs the Windows update loop.
#>
function Start-UpdateLoop {
Write-Host "Preparing for Windows Update";
$null = Import-Module PSWindowsUpdate;
$hasUpdates = $false;
Write-Host "Searching for updates…";
while (((Get-WindowsUpdate -IgnoreReboot).Count -gt 0)) {
Write-Host "There are updates available.";
Write-Host "Installing updates";
$hasUpdates = $true;
try {
$null = Install-WindowsUpdate -AcceptAll -IgnoreReboot -ErrorAction "SilentlyContinue";
@ -20,14 +22,18 @@ function Update-WindowsInstallation {
catch { }
if ((Get-WURebootStatus -Silent)) {
Write-Information "A Reboot is Required!";
Write-Information "Windows will reboot now and the installation will be continued automatically.";
Write-Host "A Reboot is Required!";
Write-Host "Windows will reboot now and the installation will be continued automatically.";
return;
} else {
Write-Information "Updating Windows finished successfully!";
Write-Host "Updating Windows finished successfully!";
return;
}
}
if (-not $hasUpdates) {
Write-Host "There are no updates available.";
}
}
Start-UpdateLoop;

View file

@ -1,15 +1,122 @@
using namespace System.Management.Automation.Host;
using namespace System.Security.Principal;
$null = New-Module {
. "$PSScriptRoot/../Scripts/Deployment.ps1";
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
[string] $userOption = "SetupUser";
. "$PSScriptRoot/../../Common/Scripts/Operations.ps1";
$loggedInUserOption = "LoggedInUser";
<#
.SYNOPSIS
Creates the configured users.
Installs all pending users to the system.
#>
function Start-ValhallaUserSetup {
[string[]] $users = Get-Users;
function Install-ValhallaUsers {
$users = @(Get-Users);
$i = Get-CurrentUser;
for (; $i -lt $users.Count; $i++) {
Set-CurrentUser $i;
if (Test-Admin) {
Disable-BootMessage;
}
while ((Get-UserStage) -ne ([UserStage]::Completed)) {
switch (Get-UserStage) {
($null) {
Set-UserStage ([UserStage]::Create);
break;
}
([UserStage]::Create) {
$msAccount = Get-UserConfig -UserName $name "microsoftAccount";
if ($env:UserName -ne $name) {
New-ValhallaUser @{
name = $name;
msAccount = $msAccount;
}
if ($msAccount) {
logoff;
} else {
Restart-Intermediate;
}
exit;
} else {
if ($msAccount) {
if (-not (Test-Admin)) {
Invoke-OneShot DisableUAC;
Restart-Intermediate -NoRegister;
exit;
}
Clear-SetupRegistration;
Disable-OneShotListener;
}
Set-UserStage ([UserStage]::Configure);
}
}
([UserStage]::Configure) {
$displayName = Get-UserConfig -UserName $name "displayName";
$userInfo = @{
name = $name;
};
if ($displayName) {
$userInfo.fullName = $displayName;
}
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
Set-LocalUser @userInfo;
Deploy-SoftwareAction -Action ConfigureUser;
Remove-LocalGroupMember -Member "$name" @adminGroup -ErrorAction SilentlyContinue;
foreach ($group in Get-UserConfig "groups") {
Add-LocalGroupMember -Member "$name" -Name "$group";
}
Set-UserStage ([UserStage]::Cleanup);
}
([UserStage]::Cleanup) {
$user = Get-SetupUser;
Disable-LocalUser $name;
Enable-LocalUser $user;
Set-AutologinUser $user;
Unregister-WslDistribution;
Set-UserStage ([UserStage]::Completed);
Restart-Intermediate;
}
}
}
}
foreach ($user in $users) {
Enable-LocalUser $user;
}
}
<#
.SYNOPSIS
Creates a new user for the PortValhalla setup.
.PARAMETER Name
The name of the user to create.
.PARAMETER MSAccount
A value indicating whether the user should be created as a Microsoft Account.
#>
function New-ValhallaUser {
param(
[string] $Name,
[switch] $MSAccount
)
function Add-MicrosoftAccount {
param(
@ -26,7 +133,7 @@ $null = New-Module {
"Thus, you have to do it by yourself.",
"So sorry…") -join "`n");
Write-Host "Create a user for ``$Name`` manually (because Windows is too stupid)";
Write-Host "Create a user for ``$Name`` manually (because Windows is too stupid)";
$null = Read-Host "Hit enter once you're done";
$newUsers = @(Get-LocalUser | Where-Object { -not ($currentUsers -contains $_.Name) });
@ -57,7 +164,6 @@ $null = New-Module {
for ($i = 0; $i -lt $newUsers.Count; $i++) {
$name = "$($newUsers[$i])";
[ChoiceDescription]::new("&$($i + 1) - ``$name``", "Your user is ``$name``");
}
}), 0);
@ -74,31 +180,80 @@ $null = New-Module {
}
};
Write-Host "Renaming the new user to ``$Name``";
Rename-LocalUser $newUser $Name;
Set-MSAccountName ([string]$newUser);
}
for ($i = 0; $i -lt $users.Count; $i++) {
Set-SetupOption $userOption $i;
$name = $users[$i];
Write-Host "Creating personal user ``$name``";
$displayName = Get-UserConfig -UserName $name "displayName";
if ($MSAccount) {
if (Test-Admin) {
Write-Host "Preparing environment for creating MS Account";
Register-Setup -DefaultUser;
Enable-OneShotListener;
Enable-UAC;
# Reset Windows activation status
# Otherwise the login won't work - Windows is fricking frustrating.
slmgr /upk;
slmgr /cpky;
slmgr /rearm;
Restart-Intermediate -CurrentUser;
exit;
}
}
Write-Host "Creating personal user ``$Name``";
if ($MSAccount) {
Add-MicrosoftAccount $Name;
Set-SetupOption $loggedInUserOption $env:UserName;
Invoke-OneShot ([OneShotTask]::InitializeMSAccount);
} else {
New-LocalUser -NoPassword @userArguments;
Initialize-UserCreation;
}
}
<#
.SYNOPSIS
Prepares the first login for initializing the current user under configuration.
#>
function Initialize-UserCreation {
$name = (@(Get-Users))[(Get-CurrentUser)];
$msAccount = Get-UserConfig -UserName $name "microsoftAccount";
Write-Host "Initializing user ``$name``";
$userArguments = @{
name = $name;
};
if ($displayName) {
$userArguments.fullName = $displayName;
}
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
if (Get-UserConfig -UserName $name "microsoftAccount") {
Add-MicrosoftAccount $name;
} else {
New-LocalUser -Disabled -NoPassword @userArguments;
if ($msAccount) {
$accountName = Get-MSAccountName;
Write-Host "Renaming ``$accountName`` to ``$name``"
Rename-LocalUser $accountName $name;
}
Set-LocalUser @userArguments;
if ($msAccount) {
Disable-LocalUser (Get-SetupOption $loggedInUserOption);
} else {
Disable-LocalUser $env:UserName;
}
Add-LocalGroupMember `
@adminGroup `
$name `
-ErrorAction SilentlyContinue;
if ($msAccount) {
Disable-Autologin;
Set-BootMessage -Caption "Please Log In" -Message "Please log in using your new Microsoft Account ``$name``.";
} else {
Set-AutologinUser "$name";
}
}
};

View file

@ -0,0 +1,115 @@
. "$PSScriptRoot/../Scripts/Security.ps1";
<#
.SYNOPSIS
Gets the name of the WSL distribution used for managing the configuration.
#>
function Get-WslDistributionName {
return "ValhallaUbuntu";
}
<#
.SYNOPSIS
Gets the path to the directory containing the WSL distribution.
#>
function Get-WslDistributionPath {
return "$env:ProgramData/PortValhalla/$(Get-WslDistributionName)";
}
<#
.SYNOPSIS
Gets the path to the virtual hard disk of the WSL distribution.
#>
function Get-WslDistributionDisk {
return "$(Get-WslDistributionPath)/ext4.vhdx";
}
<#
.SYNOPSIS
Checks whether `wsl` is installed properly.
#>
function Test-Wsl {
& { $null = wsl --status; $?; };
}
<#
.SYNOPSIS
Checks whether any WSL distributions are installed for the current user.
#>
function Test-WslDistributions {
& { $null = wsl -l; $?; };
}
<#
.SYNOPSIS
Checks whether the managed distribution is installed.
#>
function Test-WslDistribution {
& { $null = wsl -d (Get-WslDistributionName) -e true; $?; };
}
<#
.SYNOPSIS
Installs `wsl` on the system.
#>
function Install-Wsl {
wsl --install --no-launch;
}
<#
.SYNOPSIS
Installs a Ubuntu distribution to a shared directory.
#>
function Install-WslDistribution {
$dir = Get-WslDistributionPath;
$root = Split-Path -Parent $dir;
$registryPath = "HKCU:/Software/Microsoft/Windows/CurrentVersion/Lxss";
$key = Get-Item $registryPath;
if ($key) {
$key = $keyx | Rename-Item -NewName "$(Split-Path -Leaf $key)_" -PassThru;
}
if (-not (Test-Path $root)) {
$null = New-Item -ItemType Directory $root;
}
Copy-Item -Recurse (Get-AppxPackage "*Ubuntu*").InstallLocation $dir;
Set-UserPermissions $dir;
& "$dir\ubuntu.exe" install --root;
wsl --shutdown;
Remove-Item -Recurse -Force $registryPath;
if ($key) {
Move-Item $key.PSPath $registryPath;
}
}
<#
.SYNOPSIS
Uninstalls the managed WSL distribution.
#>
function Uninstall-WslDistribution {
wsl --unregister (Get-WslDistributionName);
}
<#
.SYNOPSIS
Registers the managed WSL distribution.
#>
function Register-WslDistribution {
wsl --import-in-place (Get-WslDistributionName) (Get-WslDistributionDisk);
wsl --set-default (Get-WslDistributionName);
}
<#
.SYNOPSIS
Unregisters the managed WSL distribution.
#>
function Unregister-WslDistribution {
$wslDisk = Get-WslDistributionDisk;
wsl --shutdown;
$tempDisk = Rename-Item $wslDisk "ext4_.vhdx" -PassThru;
Uninstall-WslDistribution;
Move-Item $tempDisk $wslDisk;
}

View file

@ -0,0 +1,12 @@
param (
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-SetupPackage "https://github.com/bobranten/Ext4Fsd/releases/download/v0.71/Ext2Fsd-0.71-setup.exe";
};

View file

@ -13,7 +13,6 @@ Start-SoftwareInstaller @PSBoundParameters `
)
Install-ChocoPackage firefox;
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
Write-Host "Making Firefox the default browser…";

View file

@ -12,7 +12,6 @@ Start-SoftwareInstaller @PSBoundParameters `
)
Install-ChocoPackage MSEdgeRedirect;
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
$configPath = "HKLM:\SOFTWARE\Robert Maehl Software\MSEdgeRedirect";

View file

@ -22,7 +22,6 @@ Start-SoftwareInstaller @PSBoundParameters `
refreshenv;
Set-UserPermissions $env:NVS_HOME;
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
nvs add latest;

View file

@ -0,0 +1,125 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../Scripts/PowerManagement.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
& {
param($Parameters)
<#
.SYNOPSIS
Gets the path to the Nextcloud configuration file.
#>
function Get-ConfigFile {
return "$env:APPDATA/Nextcloud/nextcloud.cfg";
}
<#
.SYNOPSIS
Adds a new nextcloud sync to the current user.
#>
function Add-NextcloudSync {
param(
[string] $RemotePath,
[string] $LocalPath,
[switch] $VirtualFiles
)
Write-Host "Adding a Nextcloud sync";
Write-Host "$RemotePath <=> $LocalPath";
$configName = "Folders";
$virtualName = "WithPlaceholders";
$LocalPath = $LocalPath.Replace("\", "/");
$RemotePath = $RemotePath.Replace("\", "/");
$oldContent = Get-Content (Get-ConfigFile);
$additionalSettings = @();
$pattern = "^\d+\\$configName(?:$virtualName)?\\(\d+)";
$folderID = (
$oldContent | `
Where-Object { $_ -match "$pattern" } | `
ForEach-Object { $_ -replace "$pattern.*$","`$1" } | `
Sort-Object -Unique | `
Measure-Object -Maximum).Maximum + 1;
if ($VirtualFiles.IsPresent) {
$configName += $virtualName;
$additionalSettings = @("0\$configName\$folderID\virtualFilesMode=wincfapi");
}
$newSettings = (
@(
"0\$configName\$folderID\localPath=$LocalPath",
"0\$configName\$folderID\targetPath=$RemotePath"
) + $additionalSettings
) -join "`n";
& {
$accountSectionEntered = $false;
$accountSectionLeft = $false;
for ($i = 0; $i -lt $oldContent.Count; $i++) {
$line = $oldContent[$i];
if ($line -eq "[Accounts]") {
$accountSectionEntered = $true;
}
if ($line -eq "" -and $accountSectionEntered) {
$accountSectionLeft = $true;
$newSettings;
}
$line;
if (
(-not $accountSectionLeft) -and
($i -eq ($oldContent.Count - 1))) {
$newSettings;
}
}
} | Set-Content (Get-ConfigFile);
}
Start-SoftwareInstaller @Parameters `
-Installer {
Install-ChocoPackage nextcloud-client -ArgumentList "-y","--params='/KeepUpdateCheck'";
} `
-UserConfigurator {
param($Arguments)
$user = $Arguments.Name;
& {
$syncs = Get-UserConfig -UserName $user "nextcloud.folderSyncs";
$configExists = { (Test-Path (Get-ConfigFile) ) };
if ($syncs.Count -gt 0) {
if (-not (& $configExists)) {
while (-not (& $configExists)) {
Read-Host "Please log in to the Nextcloud app and hit enter to continue";
if (-not (& $configExists)) {
Write-Error -ErrorAction Continue "The login seems to have failed. Please try again.";
}
}
}
Write-Host "Stopping Nextcloud process";
$nextcloudProcess = Get-Process nextcloud;
$nextcloudPath = [string]$nextcloudProcess[0].Path;
$nextcloudProcess | Stop-Process -Force;
foreach ($sync in $syncs) {
Add-NextcloudSync -LocalPath $sync.localPath -RemotePath $sync.remotePath -VirtualFiles:$sync.virtualFiles;
}
Write-Host "Restarting Nextcloud";
Start-Process $nextcloudPath;
}
};
};
} $PSBoundParameters;

View file

@ -1,32 +0,0 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage nextcloud-client -ArgumentList "-y","--params='/KeepUpdateCheck'";
} `
-UserConfigurator {
if (-not (Test-Path $context.GetNextcloudConfigFile())) {
Write-Information "Setting up Nextcloud configuration";
Write-Information "Ensuring all Let's Encrypt certificates are cached";
$null = Invoke-WebRequest https://valid-isrgrootx1.letsencrypt.org/;
while (-not (Test-Path $context.GetNextcloudConfigFile())) {
Write-Host "Nextcloud has been installed!";
Read-Host "Please log in in the Nextcloud app and hit enter to continue";
if (-not (Test-Path $context.GetNextcloudConfigFile())) {
Write-Error "The login seems to have failed. Please try again.";
}
}
$context.Reboot();
exit;
}
};

View file

@ -6,16 +6,18 @@ param (
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& {
param($Parameters)
$base = "$PSScriptRoot/../../../Common/Software/Oh My Posh/Manage.ps1";
Start-SoftwareInstaller @Parameters `
-Installer {
Install-WingetPackage JanDeDobbeleer.OhMyPosh -ArgumentList "--scope","machine";
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
. "$PSScriptRoot/../../../Common/Software/Oh My Posh/Manage.ps1" `
-Action ([InstallerAction]::Configure);
. $base -Action ([InstallerAction]::Configure);
} `
-UserConfigurator {
. $base -Action ([InstallerAction]::ConfigureUser);
};
} $PSBoundParameters;

View file

@ -8,13 +8,6 @@ param(
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
Set-Service ssh-agent -StartupType AutomaticDelayedStart;
};

View file

@ -6,7 +6,7 @@ param (
. "$PSScriptRoot/../../../Common/Software/PowerShell/Module.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
$parameters = Get-ModuleInstallerComponents "PinnedItem" -NativeOnly;
$parameters = Get-ModuleInstallerComponents "PinnedItem" -NativeOnly -NoProfile;
foreach ($key in $PSBoundParameters.Keys) {
$parameters.Add($key, $PSBoundParameters.TryGetValue($key));
@ -21,12 +21,15 @@ Start-SoftwareInstaller @parameters -Installer {
[hashtable] $Arguments
)
$module = $Arguments.Name;
& $Arguments.Installer @PSBoundParameters;
if (-not (& { powershell -Command "Import-Module $module"; $?; })) {
$feature = "NetFx3";
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
if ((Get-WindowsOptionalFeature -Online -NoRestart -FeatureName $feature).State -ne "Enabled") {
Write-Host "Enabling ``$feature`` feature…";
choco install --source windowsFeatures -y $feature;
}
& $Arguments.Installer @PSBoundParameters;
}
}

View file

@ -7,13 +7,6 @@ param (
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
. "$PSScriptRoot/../../../Common/Software/PowerShell/Manage.ps1" `
-Action ([InstallerAction]::Configure);

View file

@ -4,12 +4,14 @@ param(
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage retroarch;
# ToDo: Add start menu shortcut
# ToDo: Add function for this purpose
} `
-Configurator {
Add-StartMenuIcon "RetroArch" "C:\tools\RetroArch-Win64\retroarch.exe";
};
# ToDo: Add restoration

View file

@ -15,7 +15,6 @@ Start-SoftwareInstaller @PSBoundParameters `
)
Install-ChocoPackage thunderbird -ArgumentList "--params",'"/NoTaskbarShortcut /NoDesktopShortcut"'
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
Write-Host "Making Thunderbird the default mail program…";

View file

@ -12,10 +12,10 @@ Start-SoftwareInstaller @PSBoundParameters `
Write-Information "Enabling the ``$feature`` feature…";
choco install --source windowsFeatures -y $feature;
}
}
Install-WingetPackage Nadeo.TrackManiaNationsForever;
Remove-DesktopIcon "*TmNationsForever*";
}
};
# ToDo: Add restoration

View file

@ -11,12 +11,7 @@ param(
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
Install-ChocoPackage winscp;
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
Remove-DesktopIcon "WinSCP*";

View file

@ -12,13 +12,6 @@ param(
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
$dir = New-TemporaryDirectory;
Push-Location $dir;

View file

@ -0,0 +1,23 @@
param (
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
& {
param($Parameters)
$base = "$PSScriptRoot/../../../Common/Software/aliae/Manage.ps1";
Start-SoftwareInstaller @Parameters `
-Installer {
Install-WingetPackage JanDeDobbeleer.Aliae;
} `
-Configurator {
. $base -Action ([InstallerAction]::Configure);
} `
-UserConfigurator {
. $base -Action ([InstallerAction]::ConfigureUser);
};
} $PSBoundParameters;

View file

@ -8,13 +8,6 @@ param(
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
[string] $backup = $null;
$nativeProfile = powershell -c '$PROFILE';

View file

@ -7,58 +7,33 @@ param (
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Config.ps1";
$null = New-Module {
& {
param(
[hashtable] $Parameters
)
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
<#
.SYNOPSIS
Gets a configuration value related to git.
.PARAMETER Name
The name of the configuration to get.
.PARAMETER User
The name of the user to get the configuration for.
#>
function Get-GitOption {
param(
[Parameter(Mandatory)]
[string] $Name,
[string] $User
)
$config = "git.$Name";
if ($User) {
Get-UserConfig -UserName $User -Name $config;
} else {
Get-Config $config;
}
}
$base = "$PSScriptRoot/../../../Common/Software/git/Manage.ps1";
Start-SoftwareInstaller @Parameters `
-Installer {
param(
[scriptblock] $Installer
)
$params = "/WindowsTerminalProfile";
$defaultBranch = Get-GitOption "defaultBranch";
$defaultBranch = Get-Config "valhalla.git.defaultBranch";
if ($defaultBranch) {
$params += " /DefaultBranchName:`"$defaultBranch`"";
}
Install-ChocoPackage git -ArgumentList "--params",$params;
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
& "$PSScriptRoot/../../../Common/Software/git/Manage.ps1" @Parameters;
};
& $base ([InstallerAction]::Configure);
} `
-UserConfigurator {
param(
$Arguments
)
Export-ModuleMember -Function @();
} -ArgumentList $PSBoundParameters
& $base ([InstallerAction]::ConfigureUser) @PSBoundParameterrs;
};
} $PSBoundParameters;

View file

@ -8,23 +8,7 @@ param(
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
$file = "osu!lazer.exe";
$processName = "osu!";
$dir = New-TemporaryDirectory;
Push-Location $dir;
Invoke-WebRequest "https://github.com/ppy/osu/releases/latest/download/install.exe" -OutFile $file;
Start-Process -FilePath $file;
while (-not (Get-Process -ErrorAction SilentlyContinue $processName)) {
Start-Sleep 1;
}
Start-Sleep 10;
Get-Process $processName | Stop-Process -Force;
Pop-Location;
Remove-Item -Recurse $dir;
Install-WingetPackage "ppy.osu";
Remove-DesktopIcon "*osu*";
};

View file

@ -11,7 +11,7 @@ Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Write-Host "Downloading reWASD…";
$dir = New-TemporaryDirectory;
$file = Start-BrowserDownload -URL "https://rewasd.com/" -ButtonSelector 'a.btn-default[href="#"]' -OutDir $dir;
$file = Start-BrowserDownload -URL "https://rewasd.com/" -ButtonSelector 'a.btn-default[href="#"]' -OutDir $dir -Timeout 1;
Write-Host "Installing reWASD…";
Start-Process -Wait -FilePath $($file.FullName) -ArgumentList "/S";

View file

@ -0,0 +1,28 @@
param(
$Action,
[hashtable] $Arguments
)
& {
param (
[hashtable] $Parameters
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
$base = "$PSScriptRoot/../../../Common/Software/vscode/Main.ps1";
Start-SoftwareInstaller @Parameters `
-Installer {
Install-ChocoPackage vscode -ArgumentList "--params","/NoDesktopIcon";
Install-ChocoPackage vscodium -ArgumentList "--params","/NoDesktopIcon /AssociateWithFiles";
refreshenv;
} `
-UserConfigurator {
param(
$Arguments
)
& $base ([InstallerAction]::ConfigureUser) @PSBoundParameters;
};
} $PSBoundParameters;

View file

@ -14,7 +14,6 @@ Start-SoftwareInstaller @PSBoundParameters `
Install-ChocoPackage zoxide;
Install-WingetPackage junegunn.fzf;
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
Add-PowerShellProfileStatement `

View file

@ -13,9 +13,10 @@ begin
sed "s/\//\\\\/g"
end
argparse --name (status filename) -x "iso,usb" "iso" "usb" -- $argv
argparse --name (status filename) -x "iso,usb" "iso" "usb" "debug" -- $argv
or exit 1
set -l mountDir "/mnt"
set -l setupLabel "winiso-valhalla"
set -l projectPath "PortValhalla"
set -l systemDrivePath "sources/\$OEM\$/\$1"
@ -23,9 +24,9 @@ begin
set -l localProjectPath "$systemDrivePath/$projectPath"
set -l cacheDir ~/.cache/winiso-valhalla
set -l winpe "$cacheDir/winpe.iso"
set -l winPath "/media/win"
set -l winpePath "/media/winpe"
set -l valhallaPath "/media/winiso-valhalla"
set -l winPath "$mountDir/win"
set -l winpePath "$mountDir/winpe"
set -l valhallaPath "$mountDir/winiso-valhalla"
set -l winpeOverlay (mktemp -d)
set -l winOverlay (mktemp -d)
set -l upperDir (mktemp -d)
@ -134,6 +135,13 @@ begin
"$git[5]\\bin"
) \
"set SETUP_LABEL=$setupLabel" \
(
begin
if [ -n "$_flag_debug" ]
echo "set DEBUG=1"
end
end
) \
"set PWSH_PATH=$(echo "$pwshPath" | mkWinPath)" \
"set LOCAL_PROJECT_PATH=$(echo "$localProjectPath" | mkWinPath)" \
"set REMOTE_PROJECT_PATH=$(echo "$projectPath" | mkWinPath)" \
@ -195,7 +203,7 @@ begin
find "$projectPath/profiles" -type f -name "*.nix" | while read -l file
set -l CONFIG_MODULE "$file"
getConfig "valhalla.windows" --json > "$file.json"
getConfig "valhalla.windows.config" --json > "$file.json"
end
end
@ -221,8 +229,8 @@ begin
-output "$isoFile" \
"$valhallaPath"
else
set -l bootPath "/media/boot"
set -l dataPath "/media/data"
set -l bootPath "$mountDir/boot"
set -l dataPath "$mountDir/data"
set -a mountPaths \
"$bootPath" \