Compare commits

...

229 commits

Author SHA1 Message Date
Manuel Thalmann 822393bef3 Create a separate script for WSL interaction 2024-08-26 23:33:46 +02:00
Manuel Thalmann dccc531fbb Fix recursive configuration 2024-08-25 03:58:28 +02:00
Manuel Thalmann 17a0eb1f8b Fix malformed module 2024-08-24 18:35:43 +02:00
Manuel Thalmann f3480ce6f4 Keep Windows fixes separate 2024-08-24 16:56:29 +02:00
Manuel Thalmann 1ebd2d7b0d Remove WSL after operation 2024-08-24 16:52:41 +02:00
Manuel Thalmann 7cf5ecaa06 Make distribution name unique 2024-08-24 16:41:05 +02:00
Manuel Thalmann 957fe77eda Streamline WSL distribution name 2024-08-24 16:27:34 +02:00
Manuel Thalmann 48edcc443c Remove unused resources after user setup 2024-08-24 16:15:10 +02:00
Manuel Thalmann 068858d683 Print update logs properly 2024-08-24 14:47:51 +02:00
Manuel Thalmann 4e2bde01fe Allow overriding Windows settings 2024-08-24 14:20:22 +02:00
Manuel Thalmann ad4e548cb6 Update incorrect path 2024-08-24 14:11:38 +02:00
Manuel Thalmann 83a55f9f63 Simplify osu!lazer installation 2024-08-24 14:10:02 +02:00
Manuel Thalmann 50f820f0ed Determine name of setup user properly 2024-08-24 14:01:05 +02:00
Manuel Thalmann 99b89fc2f7 Make OMP configuration platform independent 2024-08-24 13:27:48 +02:00
Manuel Thalmann 8051db7194 Fix incorrect character in OMP theme 2024-08-24 13:27:35 +02:00
Manuel Thalmann fb6ec523fc Remove unnecessary code 2024-08-24 04:25:07 +02:00
Manuel Thalmann f0e9e2e6fc Remove unnecessary loop 2024-08-24 04:24:55 +02:00
Manuel Thalmann fb9f1f2b73 Add missing module 2024-08-24 04:24:37 +02:00
Manuel Thalmann 905aa08a51 Add nextcloud to the module list 2024-08-24 04:18:57 +02:00
Manuel Thalmann 4ff78ef57f Add a function for creating shortcuts 2024-08-24 04:18:33 +02:00
Manuel Thalmann e9f439f880 Configure nextcloud syncs 2024-08-24 04:07:47 +02:00
Manuel Thalmann 2366505747 Allow configuring nextcloud syncs 2024-08-24 04:07:35 +02:00
Manuel Thalmann 28b62123d8 Create separate option holding win users 2024-08-24 03:25:28 +02:00
Manuel Thalmann 8bed546ccc Rename Nextcloud installer 2024-08-24 01:50:07 +02:00
Manuel Thalmann f4dfd3e22d Add file system driver for dual boot 2024-08-24 01:41:09 +02:00
Manuel Thalmann c67f006b26 Prevent unnecessary config evaluation 2024-08-24 01:31:39 +02:00
Manuel Thalmann 4ced7916b3 Fix non-functioning installer 2024-08-24 01:27:26 +02:00
Manuel Thalmann 585c3ba323 Install vscode extensions by default 2024-08-24 01:16:56 +02:00
Manuel Thalmann ba8b72bf9c Load theme file from WSL properly 2024-08-24 00:59:59 +02:00
Manuel Thalmann a1da5c64a1 Update aliae configuration script 2024-08-24 00:42:57 +02:00
Manuel Thalmann ff6e9d252c Strip duplicate variables and aliases 2024-08-24 00:08:58 +02:00
Manuel Thalmann 37a877d6e5 Install posh theme automatically 2024-08-23 23:53:48 +02:00
Manuel Thalmann 3b1162c1ed Export missing function 2024-08-23 23:50:13 +02:00
Manuel Thalmann b1ccdd73f7 Install aliae by default 2024-08-23 23:46:23 +02:00
Manuel Thalmann 315ffb66bf Add scripts for changing aliae config 2024-08-23 23:44:51 +02:00
Manuel Thalmann 91ff5e69c6 Fix compatibility with mixed new line characters 2024-08-23 23:44:23 +02:00
Manuel Thalmann 3758592e23 Add a script for installing aliae 2024-08-23 22:38:28 +02:00
Manuel Thalmann 3673b8e910 Add desired posh theme 2024-08-23 19:43:06 +02:00
Manuel Thalmann 5192922b85 Make option names more clear 2024-08-23 19:42:27 +02:00
Manuel Thalmann 30c79164c4 Allow configuring oh-my-posh 2024-08-23 19:39:18 +02:00
Manuel Thalmann 4e693da84d Fetch config from proper section 2024-08-23 19:24:49 +02:00
Manuel Thalmann c640fe10cb Adjust configuration accordingly 2024-08-23 19:14:09 +02:00
Manuel Thalmann 5f4c7ace0a Refactor option descriptions 2024-08-23 19:02:06 +02:00
Manuel Thalmann ec0823df14 Clean up the Windows configuration 2024-08-23 18:59:49 +02:00
Manuel Thalmann a2919452b2 Clean up the users.nix file 2024-08-23 18:51:54 +02:00
Manuel Thalmann 645b31b795 Create dedicated rclone module 2024-08-23 18:48:30 +02:00
Manuel Thalmann d5ae24b487 Move git module to separate directory 2024-08-23 18:42:16 +02:00
Manuel Thalmann 9cf600fb62 Move git options to separate module 2024-08-23 18:40:24 +02:00
Manuel Thalmann 54cabbcdc8 Fix inheritance of user config 2024-08-23 18:28:20 +02:00
Manuel Thalmann 58f32346bb Allow OS specific settings 2024-08-23 18:11:48 +02:00
Manuel Thalmann 95408e47b6 Update archiso 2024-08-23 14:19:56 +02:00
Manuel Thalmann 66430773a0 Set user info during git setup 2024-08-23 02:01:16 +02:00
Manuel Thalmann e351108288 Make all config scripts platform independent 2024-08-23 01:57:53 +02:00
Manuel Thalmann e2707152d4 Allow leaving aliases unspecified 2024-08-23 01:52:25 +02:00
Manuel Thalmann 8f841ba449 Make scripts platform independent 2024-08-23 01:52:04 +02:00
Manuel Thalmann 12ce6e8cab Add scripts for configuring git 2024-08-23 01:43:26 +02:00
Manuel Thalmann ea2f616a28 Configure software implicitly 2024-08-23 01:41:32 +02:00
Manuel Thalmann 539e9fb661 Skip profile creation for PinnedItem 2024-08-22 23:55:41 +02:00
Manuel Thalmann 2aac92dfc7 Allow skipping powershell module registration 2024-08-22 23:55:00 +02:00
Manuel Thalmann e8ec44c021 Add profiles to the flake 2024-08-22 23:37:53 +02:00
Manuel Thalmann 9b5a8382b7 Remove user profile of OneShot user 2024-08-22 23:12:11 +02:00
Manuel Thalmann ae4947fbef Add missing variable 2024-08-22 21:14:52 +02:00
Manuel Thalmann 0ad40548e9 Add missing OneShotTask declaration 2024-08-22 20:41:30 +02:00
Manuel Thalmann a88543d40f Fix infinite loop 2024-08-22 20:41:17 +02:00
Manuel Thalmann 836ec6ce78 Fix incorrect variable name 2024-08-22 20:34:16 +02:00
Manuel Thalmann 1a81aa9db7 Fix handling empty error messages 2024-08-22 20:12:18 +02:00
Manuel Thalmann d38dec6c66 Add choco to the profile of the setup user 2024-08-22 13:46:55 +02:00
Manuel Thalmann 4e78728b76 Add functions for handling options for creating users 2024-08-22 11:11:37 +02:00
Manuel Thalmann 335a13e258 Fix incorrect typings 2024-08-22 11:11:12 +02:00
Manuel Thalmann d1a2fcdef0 Fix permission issues when enabling Win hack 2024-08-22 11:11:00 +02:00
Manuel Thalmann e1dc26b3c2 Register setup script as admin 2024-08-22 11:10:39 +02:00
Manuel Thalmann 55eb62d1ff Execute the entire installer using live scripts 2024-08-21 23:21:32 +02:00
Manuel Thalmann 1d8f7c6ea7 Streamline the creation of users 2024-08-21 18:34:18 +02:00
Manuel Thalmann febfd16df2 Replace osk with cmd during debugging 2024-08-21 18:33:41 +02:00
Manuel Thalmann 73cc50943e Prevent pauses in OneShot tasks 2024-08-21 18:28:50 +02:00
Manuel Thalmann a487e86d37 Print commands in debug mode 2024-08-21 18:28:08 +02:00
Manuel Thalmann 6cd880c7a6 Run OneShot tasks with dedicated user 2024-08-21 18:27:47 +02:00
Manuel Thalmann 77edbb51a6 Add function for generating startup command 2024-08-21 18:26:58 +02:00
Manuel Thalmann 3aa46f61c6 Allow registering startup script for the default user 2024-08-21 18:20:11 +02:00
Manuel Thalmann c46a540599 Prevent unnecessary errors during WSL execution 2024-08-21 14:08:26 +02:00
Manuel Thalmann c97bebefb3 Register WSL before running OneShot tasks 2024-08-21 03:37:44 +02:00
Manuel Thalmann 70b452f140 Overwrite broken module 2024-08-21 03:20:37 +02:00
Manuel Thalmann 5009b0d97a Prevent initialization of nested operations 2024-08-21 03:18:31 +02:00
Manuel Thalmann 42a448ec8e Improve log messages of OneShot tasks 2024-08-21 02:02:30 +02:00
Manuel Thalmann 26406e33fc Retry Linux path conversion for errors 2024-08-20 00:20:33 +02:00
Manuel Thalmann ff0a13fb30 Fix typo 2024-08-20 00:20:07 +02:00
Manuel Thalmann 22f312b3ed Fix broken signature of Restart-Intermediate 2024-08-19 12:07:26 +02:00
Manuel Thalmann 29d7fa30be Report unexpected path conversions 2024-08-19 02:50:41 +02:00
Manuel Thalmann 9d020f94f7 Load missing path 2024-08-19 02:50:19 +02:00
Manuel Thalmann 407a4d3fab Ensure error file can be read from 2024-08-19 02:24:45 +02:00
Manuel Thalmann 935fc4dab4 Streamline OneShot task handler 2024-08-19 02:24:30 +02:00
Manuel Thalmann bb5427f255 Simplify script registration 2024-08-19 02:24:13 +02:00
Manuel Thalmann 0c68b92380 Fix broken regedit paths 2024-08-19 01:38:25 +02:00
Manuel Thalmann 5b86da8697 Allow registering reboots for users 2024-08-19 01:37:14 +02:00
Manuel Thalmann 476b76f581 Prevent users from being excluded 2024-08-19 01:10:29 +02:00
Manuel Thalmann 7b26f113da Force copying of Linux users to Windows 2024-08-19 00:54:13 +02:00
Manuel Thalmann aa21ac9115 Improve log messages of updates 2024-08-18 12:20:21 +02:00
Manuel Thalmann 8873a97412 Remove unnecessary command 2024-08-18 10:24:15 +02:00
Manuel Thalmann 93049868b6 Fix time for QEMU VMs 2024-08-18 09:35:16 +02:00
Manuel Thalmann 5dd5ec4839 Remove unnecessary desktop icons 2024-08-18 09:25:23 +02:00
Manuel Thalmann bd23cfd358 Add a timeout for the reWASD downloader 2024-08-18 09:05:04 +02:00
Manuel Thalmann b0f21037cc Allow setting a timeout for clicking download buttons 2024-08-18 09:04:42 +02:00
Manuel Thalmann 6860d9ac8e Emit errors concerning WSL commands 2024-08-17 13:51:10 +02:00
Manuel Thalmann baa4d6e201 Emit errors using Write-Error 2024-08-17 13:49:21 +02:00
Manuel Thalmann 89025560dd Convert Argument to string explicitly 2024-08-16 23:03:19 +02:00
Manuel Thalmann 46dbec234e Ignore unfinished browser downloads 2024-08-16 17:57:22 +02:00
Manuel Thalmann 03e16767e5 Install powershell modules for all users 2024-08-16 16:43:30 +02:00
Manuel Thalmann 338d672a32 Fix typos 2024-08-16 16:10:09 +02:00
Manuel Thalmann 714cf21e90 Install AutoHotkey as preparation 2024-08-16 15:22:09 +02:00
Manuel Thalmann 77bd653839 Allow running live scripts in debug mode 2024-08-16 15:21:41 +02:00
Manuel Thalmann d38e6a24fd Generate env variables using shorthand scripts 2024-08-16 15:16:56 +02:00
Manuel Thalmann 4ad3cfd5d8 Allow running installation in debug mode 2024-08-16 15:16:28 +02:00
Manuel Thalmann c40d39173f Redirect winiso exit code properly 2024-08-16 15:13:53 +02:00
Manuel Thalmann d87be04660 Allow specifying winiso build type 2024-08-16 15:13:33 +02:00
Manuel Thalmann c1d1fbc7e2 Refactor winget check for rare issue 2024-08-16 15:04:37 +02:00
Manuel Thalmann 1b33fd0696 Disable Windows Update reboot only as admin 2024-08-16 14:35:35 +02:00
Manuel Thalmann 793aa59db0 Add a function for queueing startup commands 2024-08-15 18:34:48 +02:00
Manuel Thalmann ab8d89e7a3 Hide output of DISM commands 2024-08-15 13:57:15 +02:00
Manuel Thalmann f7346d838a Ensure website is loaded before download 2024-08-15 02:42:00 +02:00
Manuel Thalmann 337a89120f Prevent Jellyfin from rebooting 2024-08-15 02:22:07 +02:00
Manuel Thalmann 25d7fa6ab1 Improve handling of slow websites 2024-08-14 18:47:29 +02:00
Manuel Thalmann ef1bf5ebf8 Fix potential CRC errors 2024-08-14 18:46:42 +02:00
Manuel Thalmann cd5d45bff3 Ensure auto reboot is disabled properly 2024-08-12 21:32:53 +02:00
Manuel Thalmann 68d3a4ab17 Disable auto reboot by default 2024-08-12 01:27:50 +02:00
Manuel Thalmann 804e30f267 Add methods for managing auto restart feature 2024-08-12 01:23:42 +02:00
Manuel Thalmann c8670d1fea Install Wave Link first 2024-08-11 18:27:16 +02:00
Manuel Thalmann e880d939a2 Throw an error when failing to load config 2024-08-11 18:27:06 +02:00
Manuel Thalmann 8378b3b1c0 Fix incorrect script path 2024-08-10 20:37:10 +02:00
Manuel Thalmann e5b5083fd4 Allow leaving install action unspecified 2024-08-10 19:27:56 +02:00
Manuel Thalmann feeefa0a10 Retrieve registry value properly 2024-08-10 19:26:53 +02:00
Manuel Thalmann a35f82d131 Add scripts for installing git 2024-08-10 15:28:10 +02:00
Manuel Thalmann 24d8642ec3 Remove unnecessary code 2024-08-10 15:24:15 +02:00
Manuel Thalmann 2aeac879d4 Add a function for removing the RunOnce key 2024-08-10 15:24:04 +02:00
Manuel Thalmann 3c14daea72 Set user groups properly 2024-08-10 15:23:38 +02:00
Manuel Thalmann da45d50898 Configure MS accounts properly 2024-08-10 15:21:13 +02:00
Manuel Thalmann fb65d630e3 Queue next user after configuration finished 2024-08-10 15:20:36 +02:00
Manuel Thalmann e45ed64b06 Disable UAC after logging in MS account 2024-08-10 15:19:14 +02:00
Manuel Thalmann b84acea51a Enable OneShot listener for MS accounts 2024-08-10 15:18:10 +02:00
Manuel Thalmann f7e13a6c07 Set timezone automatically 2024-08-10 15:17:21 +02:00
Manuel Thalmann 7174c2d772 Prevent variable overwrite 2024-08-10 15:16:57 +02:00
Manuel Thalmann a13997aab0 Register installer script after disabling UAG 2024-08-10 15:16:27 +02:00
Manuel Thalmann 4c8b4a0385 Redirect user for configuration properly 2024-08-10 15:16:00 +02:00
Manuel Thalmann 4b18b15230 Fix broken redirection of arguments 2024-08-10 15:15:40 +02:00
Manuel Thalmann 3f8dfdab2c Determine installer action properly 2024-08-10 15:15:21 +02:00
Manuel Thalmann c22f48e592 Redirect arguments to chocolatey properly 2024-08-10 15:13:46 +02:00
Manuel Thalmann 15cba6ebc9 Fix non-functioning OneShot script 2024-08-10 15:13:20 +02:00
Manuel Thalmann 7fd185b5c1 Fix oneshot task execution 2024-08-10 06:11:55 +02:00
Manuel Thalmann ca5ac7a203 Allow removing the OneShot listener 2024-08-10 05:19:24 +02:00
Manuel Thalmann ffb2fd565c Remove duplicate code 2024-08-10 05:17:08 +02:00
Manuel Thalmann 181ca03e3a Fix typo 2024-08-10 03:57:37 +02:00
Manuel Thalmann f2c2582310 Fix copy paste error 2024-08-10 03:57:26 +02:00
Manuel Thalmann 56803b42d6 Allow skipping the User parameter 2024-08-10 03:40:37 +02:00
Manuel Thalmann 6f98557062 Fix incorrect script path 2024-08-10 03:13:13 +02:00
Manuel Thalmann c57294bde8 Fix broken scripts 2024-08-10 01:50:52 +02:00
Manuel Thalmann 8e3c017699 Remove unnecessary confirmation dialogue 2024-08-10 00:23:47 +02:00
Manuel Thalmann 069aec8271 Add a task for disabling UAC 2024-08-10 00:23:37 +02:00
Manuel Thalmann d809ed112c Force creation of sudo alias 2024-08-10 00:22:46 +02:00
Manuel Thalmann a7d6cc444e Allow execution of OneShot tasks 2024-08-10 00:22:30 +02:00
Manuel Thalmann 9be293b799 Ensure CONFIG_MODULE is resolved 2024-08-09 23:23:55 +02:00
Manuel Thalmann 012f5d5fdb Add dedicated functions for creating startup scripts 2024-08-09 23:23:29 +02:00
Manuel Thalmann f38f0e68ca Change login message 2024-08-09 22:11:12 +02:00
Manuel Thalmann ed0db7af27 Set up shared WSL 2024-08-09 16:02:33 +02:00
Manuel Thalmann f23f35da73 Install updates only as admin 2024-08-09 16:02:24 +02:00
Manuel Thalmann 51eb97e435 Disable boot message only as admin 2024-08-09 16:02:00 +02:00
Manuel Thalmann 07d3a2378d Add a function for allowing user access 2024-08-09 15:56:16 +02:00
Manuel Thalmann 4a7d5db510 Fix broken reboot registration 2024-08-09 15:49:36 +02:00
Manuel Thalmann 3db1c587dd Ensure the script path is detected properly 2024-08-09 14:45:50 +02:00
Manuel Thalmann a3dd1af30b Allow automatic script execution for MS accounts 2024-08-09 14:45:29 +02:00
Manuel Thalmann db31a862cf Reorder winget arguments 2024-08-09 14:45:05 +02:00
Manuel Thalmann 24c3bd1d11 Allow registering reboot for the default user 2024-08-09 14:44:57 +02:00
Manuel Thalmann 8e155a00d5 Add a dedicated function for disabling boot message 2024-08-09 13:35:12 +02:00
Manuel Thalmann cac1df3027 Implement root install loop using a switch 2024-08-09 13:34:46 +02:00
Manuel Thalmann 3b79053455 Force computer reboots 2024-08-09 04:42:55 +02:00
Manuel Thalmann 16a8f8d499 Add scripts for controlling UAC 2024-08-09 04:29:26 +02:00
Manuel Thalmann 44d8223cd5 Set displayname of all users 2024-08-09 04:20:00 +02:00
Manuel Thalmann 797fde65af Login to users for configuration 2024-08-09 04:19:49 +02:00
Manuel Thalmann fc95d4c76d Skip PWSH_PATH if undefined 2024-08-09 04:08:22 +02:00
Manuel Thalmann c5ccae9b35 Fix typo 2024-08-09 03:38:10 +02:00
Manuel Thalmann 8efc752218 Add missing setup stage 2024-08-09 03:02:25 +02:00
Manuel Thalmann 79098f5efb Make Get-Users output explicit 2024-08-09 03:02:17 +02:00
Manuel Thalmann 86374baf2f Allow displaying a boot message 2024-08-09 02:59:06 +02:00
Manuel Thalmann 5ad857320d Disable users by default 2024-08-09 02:58:01 +02:00
Manuel Thalmann 05ad26763a Add a stage for configuring users 2024-08-09 02:27:24 +02:00
Manuel Thalmann c08afd1221 Detect installation properly 2024-08-09 02:24:59 +02:00
Manuel Thalmann bc4055d760 Remove unnecessary icon 2024-08-09 02:23:56 +02:00
Manuel Thalmann 65c2d8e714 Add Predator Z301C to the hardware list 2024-08-09 02:23:41 +02:00
Manuel Thalmann 5b084342c5 Add support for the sudo command 2024-08-09 02:22:45 +02:00
Manuel Thalmann 245af3c2a0 Fix renaming user 2024-08-09 02:20:27 +02:00
Manuel Thalmann aeeedd02ee Make specifying PWSH_PATH optional 2024-08-09 02:12:27 +02:00
Manuel Thalmann bb3de634f9 Show error properly 2024-08-09 02:00:18 +02:00
Manuel Thalmann b16094f8f7 Fix typo 2024-08-09 01:53:59 +02:00
Manuel Thalmann 9e37f99036 Remove code duplication 2024-08-09 01:33:04 +02:00
Manuel Thalmann 116d6d9676 Remove unnecessary console output 2024-08-09 01:22:51 +02:00
Manuel Thalmann 3d67480a80 Fix incorrect file paths 2024-08-09 00:17:05 +02:00
Manuel Thalmann c79bec479d Fix incorrect hardware name 2024-08-09 00:03:45 +02:00
Manuel Thalmann 39abd90b34 Reorder installation steps 2024-08-08 23:03:10 +02:00
Manuel Thalmann 540481e966 Suppress unnecessary output 2024-08-08 22:24:41 +02:00
Manuel Thalmann a25e743047 Refactor the wsl installation check 2024-08-08 22:21:49 +02:00
Manuel Thalmann f9562472fe Ensure WSL Ubuntu is installed 2024-08-08 22:08:13 +02:00
Manuel Thalmann 1532fbbc9e Make config script platform independent 2024-08-08 18:21:16 +02:00
Manuel Thalmann 8f6195c958 Leave groups unspecified 2024-08-08 17:50:32 +02:00
Manuel Thalmann 0ed1f9e218 Add users during installation 2024-08-08 17:49:43 +02:00
Manuel Thalmann eecea60f1c Fix incorrect user conversion 2024-08-08 17:16:51 +02:00
Manuel Thalmann 32be282910 Keep Windows groups separate 2024-08-08 15:33:55 +02:00
Manuel Thalmann 3daf4ee8e7 Remove unnecessary options from Win users 2024-08-08 15:32:05 +02:00
Manuel Thalmann c7fd9676ce Inherit Windows users from linux 2024-08-08 15:28:29 +02:00
Manuel Thalmann dbef105780 Add functions for retrieving attributes 2024-08-08 14:45:34 +02:00
Manuel Thalmann 493847e727 Install Oh My Posh system wide 2024-08-08 14:23:15 +02:00
Manuel Thalmann e0869665dc Fix typo 2024-08-08 14:22:22 +02:00
Manuel Thalmann 7e24603c95 Skip scope argument by default 2024-08-08 14:22:13 +02:00
Manuel Thalmann f0b5e181a5 Fix incorrect file paths 2024-08-08 14:21:55 +02:00
Manuel Thalmann d97854ec55 Configure NVS after installation 2024-08-08 14:09:20 +02:00
Manuel Thalmann 0a04b12497 Refactor app association script 2024-08-08 14:09:07 +02:00
Manuel Thalmann b8e81d1458 Fix typo 2024-08-08 14:08:48 +02:00
Manuel Thalmann bbcaca2c84 Apply the error action globally 2024-08-08 14:08:38 +02:00
Manuel Thalmann 324e8bee7e Move PinnedItem script to proper location 2024-08-08 14:04:51 +02:00
Manuel Thalmann 0764d16d35 Add notes to installation script 2024-08-08 14:03:15 +02:00
Manuel Thalmann 98df4f242c Add a script for installing LGHub 2024-08-08 13:25:21 +02:00
Manuel Thalmann e2536d91a5 Reorder installation steps 2024-08-08 13:17:14 +02:00
Manuel Thalmann 00ae67d304 Reload env after installing git 2024-08-08 12:18:04 +02:00
Manuel Thalmann 7690248a55 Enure features for PinnedItem are installed 2024-08-08 05:21:21 +02:00
Manuel Thalmann 990a42bfb4 Install features using chocolatey 2024-08-08 05:20:58 +02:00
Manuel Thalmann a044612a5e Ensure git is installed 2024-08-08 05:14:31 +02:00
Manuel Thalmann 0c7e9a0959 Fix broken XML document creation 2024-08-08 05:04:59 +02:00
Manuel Thalmann c08378e7ed Fix incorrect parameter access 2024-08-08 05:03:24 +02:00
Manuel Thalmann 5f64e299aa Fix incorrect path 2024-08-08 05:01:45 +02:00
Manuel Thalmann 180379cb3a Add a dedicated user option for windows 2024-08-08 04:45:27 +02:00
Manuel Thalmann d87dee8072 Add a stage for creating users 2024-08-08 04:38:40 +02:00
Manuel Thalmann 3a0643348f Add scripts for all remaining apps 2024-08-08 04:36:35 +02:00
83 changed files with 3232 additions and 583 deletions

View file

@ -23,7 +23,7 @@ automated_script() {
sleep 1 sleep 1
done done
printf '%s: downloading %s\n' "$0" "${script}" 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=$? rt=$?
else else
cp "${script}" /tmp/startup_script cp "${script}" /tmp/startup_script

View file

@ -1,8 +1,8 @@
diff --git a/airootfs/root/.zlogin b/airootfs/root/.zlogin diff --git a/airootfs/root/.zlogin b/airootfs/root/.zlogin
index bf6bc8f..76e5893 100755 index bf6bc8f..a0dae7b 100755
--- a/airootfs/root/.zlogin --- a/airootfs/root/.zlogin
+++ b/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 fi
~/.automated_script.sh ~/.automated_script.sh
@ -16,13 +16,14 @@ index bf6bc8f..76e5893 100755
+ +
+git diff -p -R --no-ext-diff --no-color --diff-filter=M \ +git diff -p -R --no-ext-diff --no-color --diff-filter=M \
+ | grep -E "^(diff|(old|new) mode)" --color=never \ + | grep -E "^(diff|(old|new) mode)" --color=never \
+ | sed "/^diff/{ x; d; }; x; /./{ p; z; }; x;" \
+ | git apply + | git apply
+ +
+popd > /dev/null +popd > /dev/null
+ +
+loadkeys de_CH-latin1 +loadkeys de_CH-latin1
diff --git a/packages.x86_64 b/packages.x86_64 diff --git a/packages.x86_64 b/packages.x86_64
index 9e876e7..b89ab30 100755 index 9e876e7..c5db92a 100755
--- a/packages.x86_64 --- a/packages.x86_64
+++ b/packages.x86_64 +++ b/packages.x86_64
@@ -30,8 +30,10 @@ ethtool @@ -30,8 +30,10 @@ ethtool
@ -36,7 +37,15 @@ index 9e876e7..b89ab30 100755
gnu-netcat gnu-netcat
gpart gpart
gpm 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 ndisc6
nfs-utils nfs-utils
nilfs-utils nilfs-utils

View file

@ -6,7 +6,7 @@
flake-utils.url = "github:numtide/flake-utils?ref=b1d9ab70662946ef0850d488da1c9019f3a9752a"; 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: system:
let let
pkgs = import nixpkgs { pkgs = import nixpkgs {
@ -32,5 +32,11 @@
packages = { packages = {
archiso = pkgs.archiso; 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

@ -5,21 +5,7 @@
types types
; ;
syncType = types.submodule ( capitalize = (import ../text.nix { inherit lib; }).capitalize;
{ ... }: {
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;
};
};
});
userType = types.submodule ( userType = types.submodule (
{ ... } : { { ... } : {
@ -41,21 +27,27 @@
description = "The additional groups of the user."; description = "The additional groups of the user.";
default = []; default = [];
}; };
};
});
linuxUserType = types.submodule (
{ ... }: {
options = {
defaultShell = mkOption { defaultShell = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
description = "The default shell of the user."; description = "The default shell of the user.";
default = null; default = null;
}; };
git = (import ./git/options.nix) { inherit lib; };
rclone = {
configurations = mkOption {
type = types.attrsOf syncType;
description = "The configurations of the rclone mounts.";
default = {};
}; };
});
winUserType = types.submodule (
{ ... }: {
options = {
microsoftAccount = mkOption {
type = types.bool;
description = "A value indicating whether this user is a Microsoft Account.";
default = false;
}; };
}; };
}); });
@ -67,6 +59,35 @@
description = "The users to create on the machine."; description = "The users to create on the machine.";
default = {}; default = {};
}; };
linux.users = mkOption {
type = types.attrsOf linuxUserType;
};
windows = mkOption {
type = types.submoduleWith {
modules = [
({ config, options, ... }: {
options = {
users = mkOption {
type = types.attrsOf winUserType;
};
winUsers = mkOption {
type = options.users.type;
description = "Blablabla";
default = (lib.attrsets.concatMapAttrs (
name: options: {
${capitalize name} = options // {
groups = [];
};
}) config.users);
};
};
})
];
};
};
}; };
}; };
} }

View file

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

View file

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

9
lib/text.nix Normal file
View file

@ -0,0 +1,9 @@
{ lib, ... }: {
capitalize = text:
let
chars = lib.strings.stringToCharacters text;
in lib.strings.concatStrings (
[(lib.strings.toUpper (builtins.elemAt chars 0))] ++
(lib.lists.drop 1 chars)
);
}

View file

@ -10,6 +10,11 @@
enable = true; enable = true;
linuxPercentage = 30; linuxPercentage = 30;
}; };
users.manuel = {
microsoftAccount = true;
groups = ["Administrators"];
};
}; };
partition.os.partitions = { partition.os.partitions = {
@ -28,6 +33,7 @@
hardware = { hardware = {
components = [ components = [
"ROG Zenith Extreme Alpha" "ROG Zenith Extreme Alpha"
"Predator Z301C"
]; ];
eyeX = true; eyeX = true;

View file

@ -3,6 +3,7 @@
fs = import ../../lib/modules/partition/fs.nix; fs = import ../../lib/modules/partition/fs.nix;
in { in {
imports = [ imports = [
../manuel/config.nix
../../lib/modules/valhalla.nix ../../lib/modules/valhalla.nix
]; ];
@ -44,7 +45,10 @@
"wheel" "wheel"
"nix-users" "nix-users"
]; ];
};
};
linux.users.manuel = {
defaultShell = "fish"; defaultShell = "fish";
rclone = { 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"; 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 = { $downloadChecker = {
$files = Get-ChildItem $dir; $files = Get-ChildItem $dir;
if ((@($files)).Count -gt 0) { if ((@($files)).Count -eq 1) {
foreach ($file in $files) { $file = $files[0];
try { try {
$stream = [System.IO.File]::Open($file.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None); $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 { catch {
return $true; return $true;
} }
}
return $false; return $false;
} else { } else {
@ -90,6 +90,12 @@ $null = New-Module {
$browser = [OpenQA.Selenium.Firefox.FirefoxDriver]::new($options); $browser = [OpenQA.Selenium.Firefox.FirefoxDriver]::new($options);
$browser.Navigate().GoToUrl($URL); $browser.Navigate().GoToUrl($URL);
while (-not ($browser.ExecuteScript("return document.readyState;") -eq "complete")) {
Start-Sleep 0.1;
}
try {
$null = & $downloadAction -Browser $browser; $null = & $downloadAction -Browser $browser;
while (& $downloadChecker) { while (& $downloadChecker) {
@ -103,6 +109,10 @@ $null = New-Module {
Remove-Item -Recurse $dir; Remove-Item -Recurse $dir;
$result; $result;
} }
catch {
Write-Error $Error;
}
}
} }
<# <#
@ -117,12 +127,16 @@ $null = New-Module {
.PARAMETER OutDir .PARAMETER OutDir
The directory to download the file to. The directory to download the file to.
.PARAMETER Timeout
The number of seconds to wait before clicking the download button.
#> #>
function Start-BrowserDownload { function Start-BrowserDownload {
param( param(
[string] $URL, [string] $URL,
[string] $ButtonSelector, [string] $ButtonSelector,
[string] $OutDir = $null [string] $OutDir = $null,
[double] $Timeout = 0
) )
Start-CustomBrowserDownload @PSBoundParameters -Action { Start-CustomBrowserDownload @PSBoundParameters -Action {
@ -130,7 +144,28 @@ $null = New-Module {
[OpenQA.Selenium.Firefox.FirefoxDriver] $Browser [OpenQA.Selenium.Firefox.FirefoxDriver] $Browser
) )
$Browser.FindElement([OpenQA.Selenium.By]::CssSelector($ButtonSelector)).Click(); $selector = [OpenQA.Selenium.By]::CssSelector($ButtonSelector);
[OpenQA.Selenium.IWebElement] $element = $null;
for ($i = 0; $i -lt 5; $i++) {
$element = $Browser.FindElement($selector);
if ($element) {
break;
} else {
Start-Sleep 1;
}
}
if ($Timeout -gt 0) {
Start-Sleep $Timeout;
}
if ($element) {
$Browser.FindElement($selector).Click();
} else {
Write-Error "Unable to find download button!";
}
}; };
} }
}; };

View file

@ -3,14 +3,27 @@ using namespace System.Security.AccessControl;
using namespace System.Security.Principal; using namespace System.Security.Principal;
enum SetupStage { enum SetupStage {
Idle
Initialize Initialize
OneShot
Configure Configure
Install Install
CreateUser
}
enum UserStage {
Create
Configure
Cleanup
Completed
} }
$null = New-Module { $null = New-Module {
[string] $configRoot = "HKLM:\Software\PortValhalla"; [string] $configRoot = "HKLM:\Software\PortValhalla";
[string] $stageOption = "Stage"; [string] $stageOption = "Stage";
[string] $userOption = "SetupUser";
[string] $userStageOption = "UserStage";
[string] $accountOption = "MSAccount";
[string] $finishedOption = "Finished"; [string] $finishedOption = "Finished";
[RegistryKey] $key = $null; [RegistryKey] $key = $null;
@ -26,6 +39,11 @@ $null = New-Module {
[string] $Path [string] $Path
) )
& {
$ErrorActionPreference = 'Continue';
$completed = $false;
while (-not $completed) {
$job = Start-Job { $job = Start-Job {
$env:Value = Resolve-Path $Using:Path; $env:Value = Resolve-Path $Using:Path;
$env:WSLENV = "Value/p"; $env:WSLENV = "Value/p";
@ -33,7 +51,24 @@ $null = New-Module {
wsl -e printf "%q" "$result"; 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;
};
} }
<# <#
@ -75,11 +110,34 @@ $null = New-Module {
$scriptPath = "$PSScriptRoot/../../Common/Scripts/config.fish"; $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";
} else {
function fish { function fish {
wsl --shell-type login -- nix --extra-experimental-features "nix-command flakes" run nixpkgs`#fish -- $args 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 $?) {
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;
}
} }
<# <#
@ -91,10 +149,67 @@ $null = New-Module {
#> #>
function Get-Config { function Get-Config {
param( param(
[string] $Name,
[Parameter(ValueFromRemainingArguments)]
[string[]] $ArgumentList
)
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.
.PARAMETER UserName
The name of the user to get the configuration for.
.PARAMETER Name
The name of the configuration to get.
#>
function Get-UserConfig {
param(
[string] $UserName = ($IsWindows ? $env:UserName : $env:USER),
[Parameter(Mandatory, Position = 0)]
[string] $Name [string] $Name
) )
Invoke-ConfigScript "getConfig $Name --json"; if ((Get-Users) -contains $UserName) {
Get-Config "$(Get-UserRootName).$UserName.$Name";
} else {
return $null;
}
}
<#
.SYNOPSIS
Gets the attributes of a configuration object.
.PARAMETER Name
The name of the configuration to get the attributes of.
#>
function Get-Attributes {
param(
[string] $Name
)
Invoke-ConfigScript "getAttributes $Name";
} }
<# <#
@ -102,7 +217,19 @@ $null = New-Module {
Gets the names of the users to create. Gets the names of the users to create.
#> #>
function Get-Users { function Get-Users {
Invoke-ConfigScript "getUsers"; [OutputType([string[]])]
param()
Get-Attributes "$(Get-UserRootName)";
}
<#
.SYNOPSIS
Gets the name of the setup user.
#>
function Get-SetupUser {
[OutputType([string])]
param()
Get-Config "$(Get-ConfigRootName).setupUser.name";
} }
<# <#
@ -179,12 +306,91 @@ $null = New-Module {
$null = Set-SetupOption $stageOption $Name; $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 .SYNOPSIS
Gets a value indicating whether the setup has finished. Gets a value indicating whether the setup has finished.
#> #>
function Get-IsFinished { function Get-IsFinished {
return [bool] (Get-SetupOption $finishedOption); return [bool] (((Get-Stage) -eq ([SetupStage]::Idle)) -or (Get-SetupOption $finishedOption));
} }
<# <#
@ -211,7 +417,15 @@ $null = New-Module {
[string] $Name [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";
} }
<# <#
@ -219,7 +433,7 @@ $null = New-Module {
Checks whether the current user is the setup user. Checks whether the current user is the setup user.
#> #>
function Test-SetupUser { function Test-SetupUser {
$env:UserName -eq (Get-Config "valhalla.windows.setupUser"); ($IsWindows ? $env:UserName : $env:USER) -eq (Get-SetupUser);
} }
<# <#

View file

@ -1,14 +1,199 @@
. "$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";
$oneShotTaskName = "PortValhalla OneShot";
$logName = "Application";
$oneShotTrigger = 1337;
$taskOption = "OneShotTask";
# 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);
};
function Start-Operation { function Start-Operation {
param( param(
[switch] $NonInteractive,
[switch] $NoImplicitCleanup,
[scriptblock] $Action [scriptblock] $Action
) )
$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"; $env:WSLENV = "CONFIG_MODULE/p";
if ($env:CONFIG_MODULE) { if ($env:CONFIG_MODULE) {
$env:CONFIG_MODULE = Resolve-Path $env:CONFIG_MODULE; $env:CONFIG_MODULE = Resolve-Path $env:CONFIG_MODULE;
} }
& $Action; if (Test-Admin) {
Disable-WindowsUpdateAutoRestart;
} }
New-Alias -Force "sudo" gsudo;
}
if (-not $NoImplicitCleanup.IsPresent) {
$cleanup = {
Clear-OperationResources;
};
}
}
& $Action;
& $cleanup;
}
<#
.SYNOPSIS
Gets the current OneShot task.
#>
function Get-OneShotTask {
[OneShotTask](Get-SetupOption $taskOption);
}
<#
.SYNOPSIS
Registers a task for listening to OneShot invocations.
#>
function Enable-OneShotListener {
$tempTask = "PortValhalla Temp";
$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;
$null = Register-ScheduledTask -Force $oneShotTaskName -Action $action -Trigger $trigger -RunLevel Highest -User $user -Password $password;
$null = Unregister-ScheduledTask -Confirm:$false $tempTask;
}
<#
.SYNOPSIS
Removes the OneShot task.
#>
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;
}
<#
.SYNOPSIS
Invokes a one-shot task.
.PARAMETER Task
The task to run.
#>
function Invoke-OneShot {
param(
[OneShotTask] $Task
)
$currentStage = Get-Stage;
Set-Stage ([SetupStage]::OneShot);
& $taskSetter $Task;
& {
$identifier = "EventLog$oneShotTrigger";
$log = [System.Diagnostics.EventLog]::new($logName);
$log.EnableRaisingEvents = $true;
$null = Register-ObjectEvent -InputObject $log -EventName EntryWritten -Action {
$entry = $Event.SourceEventArgs.Entry;
$trigger = $Event.MessageData.Trigger;
$identifier = $Event.MessageData.Identifier;
if ($entry.EventID -eq $trigger) {
$null = New-Event -SourceIdentifier $identifier;
}
} `
-MessageData @{
Trigger = $oneShotTrigger;
Identifier = $identifier;
};
Write-EventLog -LogName $logName -Source $logName -EventId $oneShotTrigger -Message "Starting OneShot task ``$(Get-OneShotTask)``";
for ($i = 0; $i -lt 2; $i++) {
Remove-Event -EventIdentifier (Wait-Event -SourceIdentifier $identifier).EventIdentifier;
}
};
Set-Stage $currentStage;
if (Test-Path $errorPath) {
$errorMessage = Get-Content $errorPath;
Remove-Item $errorPath;
if ($errorMessage) {
Write-Error $errorMessage;
}
}
}
# ToDo: Store Run-OneShot and Receive-OneShot somewhere else in Windows folder
<#
.SYNOPSIS
Executes the specified action and notifies the OneShot task executor.
#>
function Start-OneShot {
param(
[scriptblock] $Action
)
try {
Start-Operation -NonInteractive @PSBoundParameters;
}
catch {
Set-Content -Path $errorPath -Value $Error;
Set-UserPermissions $errorPath;
}
finally {
Set-Stage ([SetupStage]::Idle);
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 {
wsl --unregister (Get-DistributionName);
}
};

View file

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

View file

@ -42,7 +42,7 @@ $null = New-Module {
} }
if ($Names.Count -ge 1) { if ($Names.Count -ge 1) {
choco install -y $ArgumentList $Names; choco install -y @ArgumentList @Names;
} }
} }
@ -72,8 +72,8 @@ $null = New-Module {
winget install ` winget install `
--accept-source-agreements --accept-package-agreements ` --accept-source-agreements --accept-package-agreements `
--source winget ` --source winget `
--scope machine ` $ArgumentList `
--exact --id $name $ArgumentList; --exact --id $name ;
} else { } else {
Write-Host "Package ``$name`` is already installed" Write-Host "Package ``$name`` is already installed"
} }
@ -197,15 +197,15 @@ $null = New-Module {
function Start-SoftwareInstaller { function Start-SoftwareInstaller {
param( param(
[string] $Name, [string] $Name,
[scriptblock] $Installer = { }, [scriptblock] $Installer = $null,
[scriptblock] $Configurator = { }, [scriptblock] $Configurator = $null,
[scriptblock] $UserConfigurator = { }, [scriptblock] $UserConfigurator = $null,
[Nullable[InstallerAction]] $Action, [Nullable[InstallerAction]] $Action,
[hashtable] $Arguments [hashtable] $Arguments
) )
[InstallerAction] $Action = & { [InstallerAction] $Action = & {
if ($Action.HasValue) { if ($null -ne $Action) {
$Action; $Action;
} else { } else {
[InstallerAction]::Install; [InstallerAction]::Install;
@ -237,25 +237,32 @@ $null = New-Module {
}; };
if ($action -eq ([InstallerAction]::Install)) { if ($action -eq ([InstallerAction]::Install)) {
if ($Installer) {
Write-Host "Installing $Name"; Write-Host "Installing $Name";
& $Installer @argumentList; & $Installer @argumentList;
}
& $installHandler @argumentList -Action ([InstallerAction]::Configure);
if ($UserConfigurator -and (-not (Test-SetupUser))) {
& $installHandler @argumentList -Action ([InstallerAction]::ConfigureUser);
}
# ToDo: Automatically configure after installation # ToDo: Automatically configure after installation
} elseif ($Action -eq ([InstallerAction]::Configure)) { } elseif ($Action -eq ([InstallerAction]::Configure)) {
if ($Configurator) {
Write-Host "Configuring $Name"; Write-Host "Configuring $Name";
& $Configurator @argumentList; & $Configurator @argumentList;
if (-not (Test-SetupUser)) {
$argumentList.Add("action", [InstallerAction]::ConfigureUser);
& $installHandler @argumentList;
} }
} elseif ($Action -eq ([InstallerAction]::ConfigureUser)) { } elseif ($Action -eq ([InstallerAction]::ConfigureUser)) {
if ((-not $Arguments.ContainsKey($userArgument)) -or ($null -eq $Arguments[$userArgument])) { if ((-not $Arguments.ContainsKey($userArgument)) -or (-not $Arguments[$userArgument])) {
$argumentList.Add($userArgument, ($env:UserName)); $Arguments.Add($userArgument, ($IsWindows ? $env:UserName : $env:USER));
} }
if ($UserConfigurator) {
Write-Host "Configuring $Name for user ``$($Arguments[$userArgument])``"; Write-Host "Configuring $Name for user ``$($Arguments[$userArgument])``";
& $UserConfigurator @argumentList; & $UserConfigurator @argumentList;
} }
}
}; };
& $installHandler -Action $Action -Arguments $Arguments; & $installHandler -Action $Action -Arguments $Arguments;

View file

@ -79,10 +79,14 @@ function Test-Command {
Checks whether `winget` is working properly. Checks whether `winget` is working properly.
#> #>
function Test-Winget { function Test-Winget {
(Test-Command winget) -and -not ( (Test-Command winget) -and (
[System.Linq.Enumerable]::Any( & {
[string[]](winget source update winget), $output = winget source update winget;
$? -and -not ([System.Linq.Enumerable]::Any(
[string[]]($output),
[System.Func[string,bool]]{ param($line) $line -eq "Cancelled"; })); [System.Func[string,bool]]{ param($line) $line -eq "Cancelled"; }));
});
} }
<# <#

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 .SYNOPSIS
Removes icons from the task bar. Removes icons from the task bar.

View file

@ -8,8 +8,12 @@ function getConfig -S -a property
evalModule "$CONFIG_MODULE" "$property" $argv[2..] evalModule "$CONFIG_MODULE" "$property" $argv[2..]
end end
function getAttributes -S -a property
getConfig "$property" --apply "builtins.attrNames" --json
end
function getUsers -S function getUsers -S
getConfig valhalla.users --apply "builtins.attrNames" --json getAttributes "valhalla.users"
end end
function isSet -S -a property function isSet -S -a property

View file

@ -3,18 +3,12 @@ param (
[hashtable] $Arguments [hashtable] $Arguments
) )
. "$PSScriptRoot/../aliae/Manage.ps1";
. "$PSScriptRoot/../PowerShell/Profile.ps1"; . "$PSScriptRoot/../PowerShell/Profile.ps1";
. "$PSScriptRoot/../../Scripts/Software.ps1"; . "$PSScriptRoot/../../Scripts/Software.ps1";
. "$PSScriptRoot/../../Types/InstallerAction.ps1"; . "$PSScriptRoot/../../Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator { -Configurator {
Add-PowerShellProfileStatement ` Add-PowerShellProfileStatement `
-System ` -System `
@ -25,4 +19,39 @@ Start-SoftwareInstaller @PSBoundParameters `
(Get-ScriptInitializer "oh-my-posh init pwsh"), (Get-ScriptInitializer "oh-my-posh init pwsh"),
(Get-ScriptInitializer "oh-my-posh completion powershell") (Get-ScriptInitializer "oh-my-posh completion powershell")
) -join [System.Environment]::NewLine) ) -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"; . "$PSScriptRoot/../../Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator { -Configurator {
[string] $globalDir = $null; [string] $globalDir = $null;
$indicator = "# Profile Files"; $indicator = "# Profile Files";

View file

@ -8,11 +8,18 @@ $null = New-Module {
.PARAMETER Name .PARAMETER Name
The name of the module to install. 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 { function Get-ModuleInstallerComponents {
param( param(
[string] $Name, [string] $Name,
[switch] $NativeOnly [switch] $NativeOnly,
[switch] $NoProfile
) )
@{ @{
@ -46,12 +53,14 @@ $null = New-Module {
[hashtable] $Arguments [hashtable] $Arguments
) )
if (-not $NoProfile) {
$name = $Arguments.Name; $name = $Arguments.Name;
Add-PowerShellProfileStatement ` Add-PowerShellProfileStatement `
-DefaultUser ` -DefaultUser `
-Category $name ` -Category $name `
-Script "Import-Module `"$name`";"; -Script "Import-Module `"$name`";";
}
}; };
} }
} }

View file

@ -9,7 +9,7 @@ param (
$parameters = Get-ModuleInstallerComponents "Terminal-Icons"; $parameters = Get-ModuleInstallerComponents "Terminal-Icons";
foreach ($key in $PSBoundParameters.Keys) { foreach ($key in $PSBoundParameters.Keys) {
$parameters.Add($key, $PSBoundParameters.TryGetValue($key)); $parameters.Add($key, $PSBoundParameters[$key]);
} }
Start-SoftwareInstaller @parameters; Start-SoftwareInstaller @parameters;

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)));
}
& ([scriptblock]::Create((aliae completion powershell)));
}
) -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: alias: []
- name: totsch env: []
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'
path: [] path: []
script: 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"

View file

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

View file

@ -0,0 +1,126 @@
param (
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../Scripts/Software.ps1";
. "$PSScriptRoot/../../Scripts/System.ps1";
. "$PSScriptRoot/../../Types/InstallerAction.ps1";
$null = New-Module {
param(
[hashtable] $Parameters
)
$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

@ -9,7 +9,7 @@ param (
$parameters = Get-ModuleInstallerComponents "posh-git"; $parameters = Get-ModuleInstallerComponents "posh-git";
foreach ($key in $PSBoundParameters.Keys) { foreach ($key in $PSBoundParameters.Keys) {
$parameters.Add($key, $PSBoundParameters.TryGetValue($key)); $parameters.Add($key, $PSBoundParameters[$key]);
} }
Start-SoftwareInstaller @parameters; Start-SoftwareInstaller @parameters;

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 begin
set -l dir (status dirname) set -l dir (status dirname)
source "$dir/../../Scripts/software.fish" source "$dir/../../Scripts/software.fish"
source "$dir/../../../Common/Software/aliae/main.fish"
function userConfig -a name function userConfig -V dir -a name
set -l bins codium codium-insiders code code-insiders pwsh "$dir/Main.ps1" ConfigureUser;
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
end end
runInstaller $argv runInstaller $argv

View file

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

View file

@ -4,7 +4,7 @@ param(
) )
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1"; . "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Scripts/System.ps1"; . "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @PSBoundParameters `
-Installer { -Installer {

View file

@ -3,7 +3,9 @@ param(
[hashtable] $Arguments [hashtable] $Arguments
) )
$null = New-Module { & {
param($parameters);
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1"; . "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
$softwarePath = "$PSScriptRoot/../../Software"; $softwarePath = "$PSScriptRoot/../../Software";
@ -12,17 +14,17 @@ $null = New-Module {
"$softwarePath/TobiiGameHub/Manage.ps1" "$softwarePath/TobiiGameHub/Manage.ps1"
); );
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @parameters `
-Installer { -Installer {
Install-SetupPackage -Source "https://files.update.tech.tobii.com/Tobii_Eye_Tracking_Core_v2.16.8.214_x86.exe"; Install-SetupPackage -Source "https://files.update.tech.tobii.com/Tobii_Eye_Tracking_Core_v2.16.8.214_x86.exe";
foreach ($script in $appScripts) { foreach ($script in $appScripts) {
. $script @PSBoundParameters; . $script @parameters;
} }
} ` } `
-UserConfigurator { -UserConfigurator {
foreach ($script in $appScripts) { foreach ($script in $appScripts) {
. $script @PSBoundParameters; . $script @parameters;
} }
}; };
}; } $PSBoundParameters;

View file

@ -1,6 +1,11 @@
#!/bin/pwsh #!/bin/pwsh
using namespace System.Management.Automation.Host;
using namespace System.Security.Principal;
. "$PSScriptRoot/../../../scripts/Windows/Scripts/Prerequisites.ps1"; . "$PSScriptRoot/../../../scripts/Windows/Scripts/Prerequisites.ps1";
. "$PSScriptRoot/../../../scripts/Windows/Scripts/WSL.ps1";
. "$PSScriptRoot/../../Common/Scripts/Context.ps1"; . "$PSScriptRoot/../../Common/Scripts/Context.ps1";
. "$PSScriptRoot/../Scripts/Security.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1"; . "$PSScriptRoot/../Software/Firefox/Install.ps1";
. "$PSScriptRoot/Manage.ps1"; . "$PSScriptRoot/Manage.ps1";
. "$PSScriptRoot/User/Install.ps1"; . "$PSScriptRoot/User/Install.ps1";
@ -8,7 +13,10 @@
$null = New-Module { $null = New-Module {
. "$PSScriptRoot/../Scripts/Hooks.ps1"; . "$PSScriptRoot/../Scripts/Hooks.ps1";
. "$PSScriptRoot/../Scripts/PowerManagement.ps1"; . "$PSScriptRoot/../Scripts/PowerManagement.ps1";
. "$PSScriptRoot/../Scripts/Registry.ps1";
. "$PSScriptRoot/../Scripts/Security.ps1";
. "$PSScriptRoot/../Scripts/Update.ps1"; . "$PSScriptRoot/../Scripts/Update.ps1";
. "$PSScriptRoot/../Scripts/Users.ps1";
. "$PSScriptRoot/../../Common/Scripts/Config.ps1"; . "$PSScriptRoot/../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Common/Scripts/Operations.ps1"; . "$PSScriptRoot/../../Common/Scripts/Operations.ps1";
. "$PSScriptRoot/../../Common/Scripts/Software.ps1"; . "$PSScriptRoot/../../Common/Scripts/Software.ps1";
@ -20,7 +28,7 @@ $null = New-Module {
Finishes the installation of a running Windows machine. Finishes the installation of a running Windows machine.
#> #>
function Start-WindowsInstallation { function Start-WindowsInstallation {
Start-Operation { Start-Operation -NoImplicitCleanup {
Start-InstallationLoop; Start-InstallationLoop;
}; };
} }
@ -30,13 +38,21 @@ $null = New-Module {
Starts the installation loop. Starts the installation loop.
#> #>
function Start-InstallationLoop { function Start-InstallationLoop {
$distribution = Get-DistributionName;
$wslLocation = Get-DistributionPath;
$wslDisk = Get-DistributionDisk;
while (-not (Get-IsFinished)) { while (-not (Get-IsFinished)) {
if ($null -eq (Get-Stage)) { switch (Get-Stage) {
($null) {
Set-Stage ([SetupStage]::Initialize); Set-Stage ([SetupStage]::Initialize);
} elseif ((Get-Stage) -eq ([SetupStage]::Initialize)) { break;
}
([SetupStage]::Initialize) {
if (-not ((Test-Command "choco") -and (Test-Command "refreshenv"))) { if (-not ((Test-Command "choco") -and (Test-Command "refreshenv"))) {
Invoke-Hook "Install-Chocolatey" -Fallback { Invoke-Hook "Install-Chocolatey" -Fallback {
# Install chocolatey # Install chocolatey
New-Item -Force $PROFILE;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')); Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
Import-Module $env:ChocolateyInstall/helpers/chocolateyProfile.psm1; Import-Module $env:ChocolateyInstall/helpers/chocolateyProfile.psm1;
@ -46,6 +62,7 @@ $null = New-Module {
continue; continue;
} }
if (-not (Test-ChocoPackage "powershell-core")) { if (-not (Test-ChocoPackage "powershell-core")) {
Invoke-Hook "Install-PowerShellCore" -Fallback { 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"'; 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"';
@ -55,24 +72,110 @@ $null = New-Module {
return; return;
} }
if (Test-Path $env:PWSH_PATH) { if ($env:PWSH_PATH -and (Test-Path $env:PWSH_PATH)) {
attrib "-R" "$env:PWSH_PATH\*" /S /D; attrib "-R" "$env:PWSH_PATH\*" /S /D;
Remove-Item -Recurse -Force $env:PWSH_PATH; Remove-Item -Recurse -Force $env:PWSH_PATH;
continue; continue;
} }
Invoke-Hook "Install-PSModules" -Fallback { if ($env:DEBUG) {
Install-Module -AcceptLicense -Force PSWindowsUpdate; if (
Install-Module -AcceptLicense -Force PSScriptAnalyzer; (Get-Item $env:INSTALLER_SCRIPT).IsReadOnly -and
. "$PSScriptRoot/../../Common/Software/PinnedItem/Manage.ps1"; (Test-Qemu) -and
($Host.UI.PromptForChoice(
"Confirm",
"Do you wish to swap to live scripts?",
[ChoiceDescription[]]@(
[ChoiceDescription]::new("&No", "Use scripts stored in the virtual machine"),
[ChoiceDescription]::new("&Yes", "Use live scripts stored on the host")),
0) -eq 1)) {
Install-ChocoPackage winfsp qemu-guest-agent;
Get-Service VirtioFsSvc | Start-Service -PassThru | Set-Service -StartupType Automatic;
while (-not (Test-Path Z:\)) {
Start-Sleep 0.1;
}
foreach ($name in @("CONFIG_MODULE", "INSTALLER_SCRIPT")) {
$variable = Get-Item "Env:\$name";
$path = Join-Path `
"Z:\Repositories\PortValhalla" `
([System.IO.Path]::GetRelativePath("$PSScriptRoot/../../..", $variable.Value));
Set-Item "Env:\$name" $path;
Write-Host "The new value of ``$name`` is ``$path``";
}
Restart-Intermediate;
exit;
}
}
if (-not (Test-Command "gsudo")) {
Install-ChocoPackage gsudo;
refreshenv;
continue;
}
if ($env:DEBUG) {
& {
$sys32 = "$env:WINDIR/System32";
$osk = (Get-Item "$sys32/osk.exe").FullName;
$cmd = (Get-Item "$sys32/cmd.exe").FullName;
$tmpOsk = New-TemporaryFile;
$tmpCmd = New-TemporaryFile;
gsudo -d copy "$osk" "$tmpOsk";
gsudo -d copy "$cmd" "$tmpCmd";
if ((Get-FileHash $tmpOsk).Hash -ne (Get-FileHash $tmpCmd).Hash) {
Set-MpPreference -ExclusionPath $osk;
gsudo -d --ti move $osk "${osk}_";
gsudo -d -s copy $cmd $osk;
continue;
}
}; };
}
if (-not (Test-Winget)) { if (-not (Test-Winget)) {
. "$PSScriptRoot/../Software/winget/Manage.ps1"; . "$PSScriptRoot/../Software/winget/Manage.ps1";
continue; continue;
} }
if (-not (Test-Command "git")) {
Install-WingetPackage Git.Git;
refreshenv;
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;
wsl --shutdown;
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)) { if (-not (Test-PSPackage Selenium.WebDriver)) {
Write-Host "Installing browser automation tools…";
Install-Module -AcceptLicense -Force NuGet; Install-Module -AcceptLicense -Force NuGet;
Import-Module NuGet; Import-Module NuGet;
$null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies; $null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies;
@ -81,20 +184,46 @@ $null = New-Module {
Install-ChocoPackage selenium-gecko-driver firefox; Install-ChocoPackage selenium-gecko-driver firefox;
if (-not (& { wsl --status; $?; })) { Invoke-Hook "Install-PSModules" -Fallback {
wsl --install --no-launch; Install-Module -Scope AllUsers -AcceptLicense -Force KnownFolders;
Restart-Intermediate; Install-Module -Scope AllUsers -AcceptLicense -Force PSWindowsUpdate;
return; Install-Module -Scope AllUsers -AcceptLicense -Force PSScriptAnalyzer;
} else { Install-Module -Scope AllUsers -AcceptLicense -AllowPrerelease -AllowClobber -Force LocalAccounts;
ubuntu install --root; Import-Module LocalAccounts;
wsl -- sh `<`(curl -L https://nixos.org/nix/install`) --daemon --yes; . "$PSScriptRoot/../Software/PinnedItem/Manage.ps1";
wsl --shutdown; };
Install-WingetPackage AutoHotkey.AutoHotkey;
Set-Stage ([SetupStage]::Configure);
break;
}
default {
if (-not (& { $null = wsl -l; $? })) {
wsl --import-in-place $distribution "$wslDisk";
wsl --set-default $distribution;
} }
if (wsl --shell-type login type -t nix) { switch ($_) {
Set-Stage ([SetupStage]::Configure); ([SetupStage]::OneShot) {
Write-Host "Running OneShot task ``$(Get-OneShotTask)``";
Start-OneShot {
switch (Get-OneShotTask) {
([OneShotTask]::InitializeMSAccount) {
Initialize-UserCreation;
Register-Setup -DefaultUser;
} }
} else { ([OneShotTask]::DisableUAC) {
Disable-UAC;
Register-Setup;
}
}
};
break;
}
default {
if (Test-Admin) {
$null = Import-Module PSWindowsUpdate; $null = Import-Module PSWindowsUpdate;
Invoke-Hook "Invoke-WindowsUpdate" -Fallback { Invoke-Hook "Invoke-WindowsUpdate" -Fallback {
@ -105,6 +234,7 @@ $null = New-Module {
Restart-Intermediate; Restart-Intermediate;
return; return;
} }
}
<# <#
.SYNOPSIS .SYNOPSIS
@ -115,51 +245,25 @@ $null = New-Module {
#> #>
function Deploy-SoftwareAction { function Deploy-SoftwareAction {
param( param(
[InstallerAction] $Action [Nullable[InstallerAction]] $Action = $null
) )
[bool] $install = $false;
$arguments = [hashtable]@{ }; $arguments = [hashtable]@{ };
if ($Action) { if ($null -ne $Action) {
$arguments.Add("action", $Action); $install = ($Action -eq ([InstallerAction]::Install));
$null = $arguments.Add("action", $Action);
} else {
$install = $true;
} }
# Drivers # Drivers
$null = New-Module { & {
$driverPath = "$PSScriptRoot/../Drivers"; $driverPath = "$PSScriptRoot/../Drivers";
$mbPath = "$driverPath/ROG Zenith Extreme Alpha"; $mbPath = "$driverPath/ROG Zenith Extreme Alpha";
foreach ($component in (Get-Config "valhalla.hardware.components")) { if ($install) {
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 (-not $Action -or ($Action -eq ([InstallerAction]::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.corsairLighting") {
Install-ChocoPackage icue;
}
if (Get-Config "valhalla.hardware.elgatoWave") { if (Get-Config "valhalla.hardware.elgatoWave") {
if (-not (Test-ChocoPackage wavelink)) { if (-not (Test-ChocoPackage wavelink)) {
Install-ChocoPackage wavelink -ArgumentList '--install-arguments="/norestart"'; Install-ChocoPackage wavelink -ArgumentList '--install-arguments="/norestart"';
@ -170,55 +274,275 @@ $null = New-Module {
} }
} }
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") { if (Get-Config "valhalla.hardware.eyeX") {
. "$driverPath/Tobii EyeX/Manage.ps1" @arguments; & "$driverPath/Tobii EyeX/Manage.ps1" @arguments;
} }
}; };
$null = New-Module { & {
# Windows Config # Windows Config
$softwarePath = "$PSScriptRoot/../Software"; $softwarePath = "$PSScriptRoot/../Software";
$commonSoftware = "$PSScriptRoot/../../Common/Software"; $commonSoftware = "$PSScriptRoot/../../Common/Software";
. "$softwarePath/Windows/Manage.ps1" @arguments; & "$softwarePath/Windows/Manage.ps1" @arguments;
if (Get-Config "valhalla.hardware.logitechG") {
& "$softwarePath/LGHub/Manage.ps1" @arguments;
}
if (Test-Collection "essential") { if (Test-Collection "essential") {
# Essentials # Essentials
. "$softwarePath/OpenSSH/Manage.ps1" @arguments; & "$softwarePath/aliae/Main.ps1" @arguments;
. "$softwarePath/PowerShell/Manage.ps1" @arguments; & "$softwarePath/OpenSSH/Manage.ps1" @arguments;
. "$softwarePath/chocolatey/Manage.ps1" @arguments; & "$softwarePath/PowerShell/Manage.ps1" @arguments;
. "$commonSoftware/posh-git/Manage.ps1" @arguments; & "$softwarePath/chocolatey/Manage.ps1" @arguments;
. "$commonSoftware/Terminal-Icons/Manage.ps1" @arguments; & "$softwarePath/zoxide/Manage.ps1" @arguments;
. "$commonSoftware/Oh My Posh/Manage.ps1" @arguments; & "$commonSoftware/posh-git/Manage.ps1" @arguments;
& "$commonSoftware/Terminal-Icons/Manage.ps1" @arguments;
& "$softwarePath/Oh My Posh/Manage.ps1" @arguments;
if (Get-Config "valhalla.windows.dualboot") {
& "$softwarePath/Ext4Fsd/Main.ps1" @arguments;
}
if ($install) {
Install-ChocoPackage `
procexp `
procmon `
;
Install-WingetPackage `
KDE.KDEConnect `
;
}
} }
if (Test-Collection "common") { if (Test-Collection "common") {
# Common Software # Common Software
. "$softwarePath/WinSCP/Manage.ps1" @arguments; & "$softwarePath/WinSCP/Manage.ps1" @arguments;
. "$softwarePath/Thunderbird/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 (Test-Collection "desktopExperience") {
if ($install) {
# Fonts
Install-ChocoPackage nerd-fonts-CascadiaCode;
# Internet Access # Internet Access
. "$softwarePath/Firefox/Manage.ps1" @arguments; 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";
Install-ChocoPackage `
gimp `
gpu-z `
windirstat `
winmerge `
handbrake `
hwmonitor `
qbittorrent `
imgburn `
inkscape `
krita `
MetaX `
obs-studio
;
Remove-DesktopIcon "GIMP*";
Remove-DesktopIcon "GPU-Z*";
Remove-DesktopIcon "WinDirStat*";
Remove-DesktopIcon "*HWMonitor*";
Remove-DesktopIcon "ImgBurn*";
Remove-DesktopIcon "InkScape*";
Remove-DesktopIcon "Krita*";
Remove-DesktopIcon "mRemoteNG*";
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") { if (Test-Collection "fileSync") {
. "$softwarePath/Nextcloud/Manage.ps1" @arguments; & "$softwarePath/Nextcloud/Main.ps1" @arguments;
} }
} }
if (Test-Collection "socialMedia") {
if ($install) {
Install-ChocoPackage `
signal `
threema-desktop `
element-desktop `
teamspeak `
;
Remove-DesktopIcon "*Element*";
Remove-DesktopIcon "*TeamSpeak*";
Install-WingetPackage Discord.Discord;
Remove-DesktopIcon "*Discord*";
}
}
if (Test-Collection "media") {
if ($install) {
Install-ChocoPackage `
k-litecodecpackmega `
vlc `
;
Remove-DesktopIcon "VLC*";
Install-ChocoPackage jellyfin-media-player -ArgumentList "--install-args","/norestart";
Remove-DesktopIcon "Jellyfin Media Player*";
Install-WingetPackage Ytmdesktop.Ytmdesktop;
Remove-DesktopIcon "Youtube Music*";
}
}
if (Test-Collection "coding") {
if ($install) {
& "$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;
}
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) { ([SetupStage]::Configure) {
if (Get-Config "valhalla.windows.dualboot.enable") { if (Get-Config "valhalla.windows.dualboot.enable") {
if (-not (Test-Qemu)) {
# Fix synchronization between Linux and Windows clocks. # Fix synchronization between Linux and Windows clocks.
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Value 1 -Type "DWord"; Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Value 1 -Type "DWord";
}
# Force time resynchronization # Force time resynchronization
$timeZoneOption = "Start";
$timeZoneKey = "HKLM:\SYSTEM\CurrentControlSet\Services\tzautoupdate";
$service = Get-Service W32Time; $service = Get-Service W32Time;
$autoUpdate = (Get-Item $timeZoneKey).GetValue($timeZoneOption);
$stopped = ($service.Status -eq "Stopped"); $stopped = ($service.Status -eq "Stopped");
$setUpdate = { param([int] $Value) Set-ItemProperty $timeZoneKey -Name $timeZoneOption $Value };
& $setUpdate 3;
Start-Service $service; Start-Service $service;
w32tm /resync /force; w32tm /resync /force;
& $setUpdate $autoUpdate;
if ($stopped) { if ($stopped) {
Stop-Service $service; Stop-Service $service;
@ -230,12 +554,92 @@ $null = New-Module {
([SetupStage]::Install) { ([SetupStage]::Install) {
Write-Host "Entering install phase"; Write-Host "Entering install phase";
Deploy-SoftwareAction; Deploy-SoftwareAction;
Set-Stage ([SetupStage]::CreateUser);
}
([SetupStage]::CreateUser) {
$users = @(Get-Users);
$i = Get-CurrentUser;
for (; $i -lt $users.Count; $i++) {
$name = $users[$i];
Set-CurrentUser $i;
if (Test-Admin) {
Disable-BootMessage;
}
while ((Get-UserStage) -ne ([UserStage]::Completed)) {
switch (Get-UserStage) {
($null) {
Set-UserStage ([UserStage]::Create);
continue;
}
([UserStage]::Create) {
$msAccount = Get-UserConfig -UserName $name "microsoftAccount";
if ($env:UserName -ne $name) {
New-ValhallaUser $name;
if ($msAccount) {
logoff;
} else {
Restart-Intermediate;
}
exit;
} else {
if ($msAccount) {
if (-not (Test-Admin)) {
Invoke-OneShot DisableUAC;
Restart-Computer;
return;
}
Clear-SetupRegistration;
Disable-OneShotListener;
}
Set-UserStage ([UserStage]::Configure);
}
}
(([UserStage]::Configure)) {
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
}
Deploy-SoftwareAction -Action ([InstallerAction]::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;
Enable-LocalUser $user;
Set-AutologinUser $user;
wsl --shutdown;
$tempDisk = Rename-Item $wslDisk "ext4_.vhdx" -PassThru;
wsl --unregister $distribution;
Move-Item $tempDisk $wslDisk;
Set-UserStage ([UserStage]::Completed);
Restart-Intermediate;
}
}
}
}
Set-IsFinished $true; Set-IsFinished $true;
} }
} }
} }
} }
} }
}
}
}
function Invoke-WindowsInstallation([Context] $context) { function Invoke-WindowsInstallation([Context] $context) {
$Global:InformationPreference = "Continue"; $Global:InformationPreference = "Continue";

View file

@ -186,6 +186,20 @@ function Start-Setup {
Move-PartitionRange -Disk $Disk -1 -1 ($To + 1) Move-PartitionRange -Disk $Disk -1 -1 ($To + 1)
} }
function Add-StartupCommand {
param(
[string] $Script,
[string] $Description
)
$installationCommand = $oobeSettings.SelectSingleNode("./ua:FirstLogonCommands/ua:SynchronousCommand[last()]", $namespace);
$newCommand = $installationCommand.ParentNode.AppendChild($installationCommand.CloneNode($true));
$newCommand.SelectSingleNode("./ua:CommandLine", $namespace).InnerText = $Script;
$orderElement = $newCommand.SelectSingleNode("./ua:Order", $namespace);
$orderElement.InnerText = ([int]($orderElement.InnerText) + 1);
$newCommand.SelectSingleNode("./ua:Description", $namespace).InnerText = $Description;
}
# Collect necessary variables # Collect necessary variables
$winpePass = Get-PassSettings "windowsPE"; $winpePass = Get-PassSettings "windowsPE";
$setupConfig = Get-Component $winpePass "Microsoft-Windows-Setup"; $setupConfig = Get-Component $winpePass "Microsoft-Windows-Setup";
@ -210,22 +224,18 @@ function Start-Setup {
foreach ($xpath in @("./ua:AutoLogon/ua:Username", foreach ($xpath in @("./ua:AutoLogon/ua:Username",
"./ua:UserAccounts/ua:LocalAccounts/ua:LocalAccount/ua:Name", "./ua:UserAccounts/ua:LocalAccounts/ua:LocalAccount/ua:Name",
"./ua:UserAccounts/ua:LocalAccounts/ua:LocalAccount/ua:DisplayName")) { "./ua:UserAccounts/ua:LocalAccounts/ua:LocalAccount/ua:DisplayName")) {
$oobeSettings.SelectSingleNode($xpath, $namespace).InnerText = $valhallaConfig.setupUser; $oobeSettings.SelectSingleNode($xpath, $namespace).InnerText = $valhallaConfig.setupUser.name;
} }
$installationCommand = $oobeSettings.SelectSingleNode("./ua:FirstLogonCommands/ua:SynchronousCommand[last()]", $namespace); Add-StartupCommand `
$newCommand = $installationCommand.ParentNode.AppendChild($installationCommand.CloneNode($true)); -Script (
"powershell -Command " +
$newCommand.SelectSingleNode("./ua:CommandLine", $namespace).InnerText = ` ($env:DEBUG ? "`$env:DEBUG = $([int]$env:DEBUG);" : "") +
"powershell -Command " + ` "`$env:PWSH_PATH = $(Get-PathInjection $env:PWSH_PATH);" +
"`$env:PWSH_PATH = $(Get-PathInjection $env:PWSH_PATH);" + ` "`$env:INSTALLER_SCRIPT = $(Get-ScriptPathInjection $env:SETUP_SCRIPT_NAME);" +
"`$env:INSTALLER_SCRIPT = $(Get-ScriptPathInjection $env:SETUP_SCRIPT_NAME);" + ` "`$env:CONFIG_MODULE = $(Get-ScriptPathInjection $env:CONFIG_MODULE);" +
"`$env:CONFIG_MODULE = $(Get-ScriptPathInjection $env:CONFIG_MODULE);" + ` "& (Join-Path `$env:PWSH_PATH pwsh) `$env:INSTALLER_SCRIPT;") `
"& (Join-Path `$env:PWSH_PATH pwsh) `$env:INSTALLER_SCRIPT;"; -Description "Install PowerShell Core and git and run setup script";
$orderElement = $newCommand.SelectSingleNode("./ua:Order", $namespace);
$orderElement.InnerText = ([int]($orderElement.InnerText) + 1);
$newCommand.SelectSingleNode("./ua:Description", $namespace).InnerText = "Install PowerShell Core and git and run setup script";
if ($valhallaConfig.dualboot.enable) { if ($valhallaConfig.dualboot.enable) {
$diskSize = [long](ConvertFrom-Csv (wmic diskdrive where "Index=$(Get-InstallDisk)" get Size | ForEach-Object { "$_".Trim(); })).Size; $diskSize = [long](ConvertFrom-Csv (wmic diskdrive where "Index=$(Get-InstallDisk)" get Size | ForEach-Object { "$_".Trim(); })).Size;

View file

@ -206,12 +206,6 @@
</SynchronousCommand> --> </SynchronousCommand> -->
<SynchronousCommand wcm:action="add"> <SynchronousCommand wcm:action="add">
<Order>1</Order> <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> <RequiresUserInput>false</RequiresUserInput>
<CommandLine>powershell -Command "Set-ExecutionPolicy -Force Bypass"</CommandLine> <CommandLine>powershell -Command "Set-ExecutionPolicy -Force Bypass"</CommandLine>
<Description>Allow PowerShell scripts from anywhere.</Description> <Description>Allow PowerShell scripts from anywhere.</Description>

View file

@ -1,8 +1,9 @@
using namespace System.Xml; using namespace System.Xml;
$null = New-Module { $null = New-Module {
$associationElementName = "Association";
$rootSelector = "/DefaultAssociations"; $rootSelector = "/DefaultAssociations";
$associationSelector = "./Association"; $associationSelector = "./$associationElementName";
<# <#
.SYNOPSIS .SYNOPSIS
@ -32,7 +33,9 @@ $null = New-Module {
function Get-DefaultAppAssociations { function Get-DefaultAppAssociations {
[OutputType([xml])] [OutputType([xml])]
param() param()
[xml]::new().LoadXml(((DISM /Online /Get-DefaultAppAssociations) | Select-Object -Skip 6 | Select-Object -SkipLast 2 | Out-String)); $result = [xml]::new();
$result.LoadXml(((DISM /Online /Get-DefaultAppAssociations) | Select-Object -Skip 6 | Select-Object -SkipLast 2 | Out-String));
$result;
} }
<# <#
@ -62,7 +65,12 @@ $null = New-Module {
if ($candidates.Count -eq 1) { if ($candidates.Count -eq 1) {
$association = $candidates[0]; $association = $candidates[0];
} else { } else {
$association = ([System.Xml.XmlNode]($document.SelectNodes((& $getSelector)) | Select-Object -Last 1)[0]).CloneNode($true); $association = $document.SelectSingleNode($rootSelector).AppendChild($document.CreateElement($associationElementName));
foreach ($attributeName in @("Identifier", "ProgId", "ApplicationName")) {
$null = $association.Attributes.Append($document.CreateAttribute($attributeName));
}
$association.Identifier = $Identifier; $association.Identifier = $Identifier;
} }
@ -87,7 +95,7 @@ $null = New-Module {
$associations = $root.SelectNodes((& $getSelector)); $associations = $root.SelectNodes((& $getSelector));
# Reorder associations by their Identifier # Reorder associations by their Identifier
$associations | ForEach-Object { $root.RemoveChild($_); } | Sort-Object -Property "Identifier" | ForEach-Object { $root.AppendChild($_); }; $null = $associations | ForEach-Object { $root.RemoveChild($_) } | Sort-Object -Property "Identifier" | ForEach-Object { $root.AppendChild($_); };
$configFile = New-TemporaryFile; $configFile = New-TemporaryFile;
$writerSettings = [XmlWriterSettings]::new(); $writerSettings = [XmlWriterSettings]::new();
@ -96,7 +104,7 @@ $null = New-Module {
$writer = [XmlWriter]::Create($configFile.FullName, $writerSettings); $writer = [XmlWriter]::Create($configFile.FullName, $writerSettings);
$document.Save($writer); $document.Save($writer);
$writer.Dispose(); $writer.Dispose();
DISM /Online "/Import-DefaultAppAssociations:$($configFile.FullName)"; $null = DISM /Online "/Import-DefaultAppAssociations:$($configFile.FullName)";
Remove-Item $configFile; Remove-Item $configFile;
} }
} }

View file

@ -1,17 +1,61 @@
using namespace Microsoft.Win32; using namespace Microsoft.Win32;
$null = New-Module { $null = New-Module {
. "$PSScriptRoot/../Scripts/Registry.ps1";
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Common/Scripts/Scripting.ps1"; . "$PSScriptRoot/../../Common/Scripts/Scripting.ps1";
[RegistryKey] $key = $null; [RegistryKey] $key = $null;
$runOncePath = "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"; $runOncePath = "Software\Microsoft\Windows\CurrentVersion\RunOnce";
$systemRunOncePath = "HKLM:\$runOncePath";
$logonPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$runOnceName = "PortValhalla"; $runOnceName = "PortValhalla";
$autologinOption = "AutoAdminLogon";
$domainOption = "DefaultDomainName";
$userOption = "DefaultUserName";
$passwordOption = "DefaultPassword";
<# <#
.SYNOPSIS .SYNOPSIS
Gets the reghistry key containing the `RunOnce` commands. Gets the reghistry key containing the `RunOnce` commands.
#> #>
function Get-RunOnceKey { function Get-RunOnceKey {
Get-Item $runOncePath; param(
[RegistryKey] $UserKey
)
[string] $path = $null;
if ($UserKey) {
$path = Join-Path ($UserKey.PSPath) $runOncePath;
} else {
$path = $systemRunOncePath;
}
if (-not (Test-Path $path)) {
New-Item $path;
} else {
Get-Item $path;
}
}
<#
.SYNOPSIS
Generates a script for executing the installer.
#>
function Get-StartupScript {
"pwsh -Command " + (Get-StartupCommand);
}
<#
.SYNOPSIS
Generates a command for running the installer using `pwsh`.
#>
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;";
} }
<# <#
@ -23,28 +67,119 @@ $null = New-Module {
#> #>
function Register-Setup { function Register-Setup {
param( param(
[Parameter(ParameterSetName="System")]
[switch] $System,
[Parameter(ParameterSetName="DefaultUser", Mandatory)]
[switch] $DefaultUser,
[Parameter(ParameterSetName="User", Mandatory)]
[switch] $User,
[Parameter(ParameterSetName="User")]
[Parameter(ParameterSetName="SpecificUser", Mandatory)]
[RegistryKey] $UserKey [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:\";
}
$key = Get-RunOnceKey $UserKey; $key = Get-RunOnceKey $UserKey;
} else {
$key = Get-RunOnceKey;
}
Set-ItemProperty -Path $key.PSPath -Name $runOnceName -Type "ExpandString" -Value ( Set-ItemProperty -Path $key.PSPath -Name $runOnceName -Type "ExpandString" -Value (Get-StartupScript);
"pwsh -Command " +
"`$env:PWSH_PATH = $(ConvertTo-Injection $env:PWSH_PATH);" +
"`$env:INSTALLER_SCRIPT = $(ConvertTo-Injection $env:INSTALLER_SCRIPT);" +
"`$env:CONFIG_MODULE = $(ConvertTo-Injection $env:CONFIG_MODULE);" +
"& `$env:INSTALLER_SCRIPT;"
);
$key.Handle.Close(); $key.Handle.Close();
} }
<#
.SYNOPSIS
Clears leftovers from past registrations.
#>
function Clear-SetupRegistration {
Edit-DefaultUserKey {
param(
[RegistryKey] $Key
)
$runOnceKey = Get-RunOnceKey $Key;
Remove-Item $runOnceKey.PSPath;
}
}
<#
.SYNOPSIS
Sets the user to login automatically on boot.
.PARAMETER Name
The name of the user to login automatically.
#>
function Set-AutologinUser {
param(
[string] $Name
)
Set-ItemProperty $logonPath -Name $autologinOption "1";
if (-not $Name) {
$Name = Get-SetupUser;
}
$options = @{
$domainOption = "";
$userOption = $Name;
$passwordOption = "";
};
foreach ($key in $options.Keys) {
Set-ItemProperty $logonPath -Name $key -Value $options[$key];
}
}
<#
.SYNOPSIS
Disables the automatic login.
#>
function Disable-Autologin {
Set-ItemProperty $logonPath -Name $autologinOption "0";
foreach ($key in @($domainOption, $userOption, $passwordOption)) {
Remove-ItemProperty $logonPath -Name $key -ErrorAction SilentlyContinue;
}
}
<# <#
.SYNOPSIS .SYNOPSIS
Reboots the machine intermediately and restarts the setup after the next login. Reboots the machine intermediately and restarts the setup after the next login.
#> #>
function Restart-Intermediate { function Restart-Intermediate {
param(
[Parameter(ParameterSetName="Default")]
[switch] $DefaultUser,
[Parameter(ParameterSetName="Current", Mandatory)]
[switch] $CurrentUser
)
if ($DefaultUser.IsPresent) {
Register-Setup -DefaultUser;
} elseif ($CurrentUser.IsPresent) {
Register-Setup -User;
} else {
Register-Setup; Register-Setup;
Restart-Computer; }
Restart-Computer -Force;
} }
} }

View file

@ -1,6 +1,8 @@
using namespace Microsoft.Win32; using namespace Microsoft.Win32;
$null = New-Module { $null = New-Module {
$wuPolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate";
function Edit-DefaultUserKey { function Edit-DefaultUserKey {
param( param(
[scriptblock] $Action [scriptblock] $Action
@ -16,4 +18,62 @@ $null = New-Module {
[System.GC]::Collect(); [System.GC]::Collect();
& reg unload $regRootPath; & reg unload $regRootPath;
} }
<#
.SYNOPSIS
Sets a message to show on the login screen.
.PARAMETER Caption
The title of the message.
.PARAMETER Message
The text of the message.
#>
function Set-BootMessage {
param(
[string] $Caption,
[string] $Message
)
$options = @{
legalnoticecaption = $Caption;
legalnoticetext = $Message;
};
foreach ($key in $options.Keys) {
Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" `
-Name $key `
-Type "String" `
-Value ($options[$key]);
}
}
<#
.SYNOPSIS
Disables the boot message.
#>
function Disable-BootMessage {
Set-BootMessage;
}
<#
.SYNOPSIS
Disables automatic reboots by Windows Update.
#>
function Disable-WindowsUpdateAutoRestart {
$path = "$wuPolicyPath\AU";
$null = New-Item -Force $path -ErrorAction SilentlyContinue;
Set-ItemProperty $path `
-Name NoAutoRebootWithLoggedOnUsers `
-Value 1;
}
<#
.SYNOPSIS
Resets the automatic reboot state.
#>
function Reset-WindowsUpdateAutoRestart {
Remove-Item -Recurse "$wuPolicyPath";
}
} }

View file

@ -0,0 +1,70 @@
using namespace System.Security.AccessControl;
using namespace System.Security.Principal;
$null = New-Module {
$uacOption = "EnableLUA";
$systemPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
$uacSetter = {
param(
[bool] $Value
)
Set-ItemProperty -Path $systemPolicyPath -Name $uacOption -Value ([int]$Value);
}
<#
.SYNOPSIS
Determines whether UAC is enabled.
#>
function Get-UACStatus {
[bool](Get-ItemProperty -Path $systemPolicyPath -Name $uacOption);
}
<#
.SYNOPSIS
Enables UAC.
#>
function Enable-UAC {
& $uacSetter $true;
}
<#
.SYNOPSIS
Disables UAC.
#>
function Disable-UAC {
& $uacSetter $false;
}
<#
.SYNOPSIS
Sets read/write permissions for users at the specified path.
.PARAMETER Path
The path to allow access to users.
#>
function Set-UserPermissions {
param(
[string] $Path
)
$acl = Get-Acl $Path;
$acl.AddAccessRule(
[FileSystemAccessRule]::new(
[SecurityIdentifier]::new([WellKnownSidType]::BuiltinUsersSid, $null),
[FileSystemRights]::FullControl,
(& {
if (Test-Path -PathType Container $Path) {
[InheritanceFlags]::ObjectInherit -bor [InheritanceFlags]::ContainerInherit
} else {
0
}
}),
[PropagationFlags]::InheritOnly,
[AccessControlType]::Allow));
Set-Acl $Path $acl;
}
};

View file

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

View file

@ -0,0 +1,164 @@
using namespace System.Management.Automation.Host;
using namespace System.Security.Principal;
$null = New-Module {
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Common/Scripts/Operations.ps1";
$loggedInUserOption = "LoggedInUser";
enum UserStage {
Create
ReEnableFeatures
}
<#
.SYNOPSIS
Creates a new user for the PortValhalla setup.
.PARAMETER Name
The name of the user to create.
#>
function New-ValhallaUser {
param(
[string] $Name
)
function Add-MicrosoftAccount {
param(
[string] $Name
)
$newUser = & {
while ($true) {
$currentUsers = Get-LocalUser | ForEach-Object { $_.Name };
Write-Host (
@(
"So… Windows is too dumb to create users which are bound to a Microsoft Account.",
"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)";
$null = Read-Host "Hit enter once you're done";
$newUsers = @(Get-LocalUser | Where-Object { -not ($currentUsers -contains $_.Name) });
if ($newUsers.Count) {
if ($newUsers.Count -eq 1) {
$newUser = $newUsers[0];
Write-Host "Found new user ``$newUser``";
if (
$Host.UI.PromptForChoice(
"Confirm",
"Is ``$newUser`` your user?",
[ChoiceDescription[]]@(
[ChoiceDescription]::new("&No", "``$newUser`` is not your user"),
[ChoiceDescription]::new("&Yes", "``$newUser`` is your user")),
0) -eq 1) {
return $newUser;
}
} else {
$result = $Host.UI.PromptForChoice(
"Select your User",
"Which one is your user?",
[ChoiceDescription[]](
& {
[ChoiceDescription]::new("&None", "None of these users is yours");
for ($i = 0; $i -lt $newUsers.Count; $i++) {
$name = "$($newUsers[$i])";
[ChoiceDescription]::new("&$($i + 1) - ``$name``", "Your user is ``$name``");
}
}), 0);
if ($result -gt 0) {
return $newUsers[$result - 1];
}
}
} else {
Write-Host "";
Write-Host "Unable to determine the new user";
Write-Host "Retrying…";
}
}
};
Set-MSAccountName ([string]$newUser);
}
$msAccount = Get-UserConfig -UserName $Name "microsoftAccount";
if ($msAccount) {
if (Test-Admin) {
Write-Host "Preparing environment for creating MS Account";
Enable-OneShotListener;
Enable-UAC;
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";
$displayName = Get-UserConfig -UserName $Name "displayName";
Write-Host "Initializing user ``$name``";
$userArguments = @{
name = $name;
};
if ($displayName) {
$userArguments.fullName = $displayName;
}
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
}
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,25 @@
$null = New-Module {
<#
.SYNOPSIS
Gets the name of the WSL distribution used for managing the configuration.
#>
function Get-DistributionName {
return "ValhallaUbuntu";
}
<#
.SYNOPSIS
Gets the path to the directory containing the WSL distribution.
#>
function Get-DistributionPath {
return "$env:ProgramData/PortValhalla/$distribution";
}
<#
.SYNOPSIS
Gets the path to the virtual hard disk of the WSL distribution.
#>
function Get-DistributionDisk {
return "$(Get-DistributionPath)/ext4.vhdx";
}
};

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; Install-ChocoPackage firefox;
& $Installer -Action ([InstallerAction]::Configure)
} ` } `
-Configurator { -Configurator {
Write-Host "Making Firefox the default browser…"; Write-Host "Making Firefox the default browser…";
@ -34,7 +33,7 @@ Start-SoftwareInstaller @PSBoundParameters `
); );
foreach ($extension in $extensions) { foreach ($extension in $extensions) {
Set-DefaultAppAssociation -Identifier $extensions -ProgId "${appName}HTML$progIdSuffix" -ApplicationName $appName; Set-DefaultAppAssociation -Identifier $extension -ProgId "${appName}HTML$progIdSuffix" -ApplicationName $appName;
} }
foreach ($scheme in $schemes) { foreach ($scheme in $schemes) {

View file

@ -0,0 +1,15 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Scripts/AppAssociations.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage lghub;
Remove-DesktopIcon "*G HUB*";
};
# ToDo: Add restoration

View file

@ -0,0 +1,34 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
Install-ChocoPackage MSEdgeRedirect;
} `
-Configurator {
$configPath = "HKLM:\SOFTWARE\Robert Maehl Software\MSEdgeRedirect";
[hashtable] $options = @{
NoBing = 1;
NoImgs = 1;
NoNews = 1;
NoPDFs = 1;
Search = "StartPage";
Images = "Custom";
ImagePath = "https://startpage.com/sp/search?cat=images&query=";
News = "Google";
PDFApp = "C:\Program Files\Mozilla Firefox\firefox.exe";
};
foreach ($key in $options.Keys) {
Set-ItemProperty $configPath -Name $key -Value ($options[$key]);
}
};

View file

@ -0,0 +1,15 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-WingetPackage Nadeo.ManiaPlanet;
Remove-DesktopIcon "ManiaPlanet*";
};
# ToDo: Add restoration

View file

@ -0,0 +1,29 @@
using namespace System.Security.AccessControl;
using namespace System.Security.Principal;
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../Scripts/Security.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
$env:NVS_HOME = "$env:ProgramData\nvs";
git clone "https://github.com/jasongin/nvs.git" $env:NVS_HOME;
& "$env:NVS_HOME\nvs.cmd" install;
refreshenv;
Set-UserPermissions $env:NVS_HOME;
} `
-Configurator {
nvs add latest;
nvs link 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,58 +0,0 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage nextcloud-client -ArgumentList "-y","--params='/KeepUpdateCheck'";
} `
-Configurator {
Write-Host "Making Firefox the default browser…";
$progIdSuffix = "-308046B0AF4A39CB";
$appName = "Firefox";
$extensions = @(
".htm",
".html",
".svg",
".xht",
".xhtml"
);
$schemes = @(
"http",
"https"
);
foreach ($extension in $extensions) {
Set-DefaultAppAssociation -Identifier $extensions -ProgId "${appName}HTML$progIdSuffix" -ApplicationName $appName;
}
foreach ($scheme in $schemes) {
Set-DefaultAppAssociation -Identifier $scheme -ProgId "${appName}URL$progIdSuffix" -ApplicationName $appName;
}
} `
-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/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1"; . "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters ` & {
-Installer { param($Parameters)
param( $base = "$PSScriptRoot/../../../Common/Software/Oh My Posh/Manage.ps1";
[scriptblock] $Installer
)
Install-WingetPackage JanDeDobbeleer.OhMyPosh; Start-SoftwareInstaller @Parameters `
& $Installer -Action ([InstallerAction]::Configure); -Installer {
Install-WingetPackage JanDeDobbeleer.OhMyPosh -ArgumentList "--scope","machine";
} ` } `
-Configurator { -Configurator {
. "$PSScriptRoot/../../../Common/Software/Oh My Posh/Manage.ps1" ` . $base -Action ([InstallerAction]::Configure);
-Action ([InstallerAction]::Configure); } `
-UserConfigurator {
. $base -Action ([InstallerAction]::ConfigureUser);
}; };
} $PSBoundParameters;

View file

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

View file

@ -0,0 +1,32 @@
param (
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Software/PowerShell/Module.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
$parameters = Get-ModuleInstallerComponents "PinnedItem" -NativeOnly -NoProfile;
foreach ($key in $PSBoundParameters.Keys) {
$parameters.Add($key, $PSBoundParameters.TryGetValue($key));
}
$arguments = $parameters.arguments;
$arguments.Add("Installer", $parameters.installer);
Start-SoftwareInstaller @parameters -Installer {
param(
[scriptblock] $Installer,
[hashtable] $Arguments
)
$feature = "NetFx3";
if ((Get-WindowsOptionalFeature -Online -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"; . "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator { -Configurator {
. "$PSScriptRoot/../../../Common/Software/PowerShell/Manage.ps1" ` . "$PSScriptRoot/../../../Common/Software/PowerShell/Manage.ps1" `
-Action ([InstallerAction]::Configure); -Action ([InstallerAction]::Configure);

View file

@ -0,0 +1,15 @@
using namespace Microsoft.Win32;
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../Scripts/AppAssociations.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage putty;
};
# ToDo: Add restoration

View file

@ -0,0 +1,17 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage retroarch;
} `
-Configurator {
Add-StartMenuIcon "RetroArch" "C:\tools\RetroArch-Win64\retroarch.exe";
};
# ToDo: Add restoration

View file

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

View file

@ -0,0 +1,21 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
foreach ($feature in @("DirectPlay", "NetFx3")) {
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
Write-Information "Enabling the ``$feature`` feature…";
choco install --source windowsFeatures -y $feature;
}
}
Install-WingetPackage Nadeo.TrackManiaNationsForever;
Remove-DesktopIcon "*TmNationsForever*";
};
# ToDo: Add restoration

View file

@ -0,0 +1,33 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
$file = "TmUnitedForever.exe";
$dir = New-TemporaryDirectory;
foreach ($feature in @("DirectPlay", "NetFx3")) {
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
Write-Information "Enabling the ``$feature`` feature…";
choco install --source windowsFeatures -y $feature;
}
}
$null = Push-Location $dir;
Write-Host "Downloading TrackMania United Forever…";
Invoke-WebRequest "http://files.trackmaniaforever.com/tmunitedforever_setup.exe" -OutFile "$file";
Write-Host "Starting installation…";
Start-Process -Wait -FilePath $file -ArgumentList "/Silent";
Remove-DesktopIcon "*TmUnitedForever*";
$null = Pop-Location;
Remove-Item -Recurse $dir;
};
# ToDo: Add restoration

View file

@ -0,0 +1,27 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Write-Information "Downgrading AutoHotkey…";
$id = "AutoHotkey.AutoHotkey";
$uninstall = { winget uninstall --accept-source-agreements -e --id "$id"; };
& $uninstall;
Install-WingetPackage $id -ArgumentList "--version","1.1.37.00";
Install-ChocoPackage temurin11jre;
Write-Host "Installing UniFi Controller…";
Install-ChocoPackage ubiquiti-unifi-controller -ArgumentList "--ignore-dependencies";
Write-Information "Upgrading AutoHotkey…";
& $uninstall;
Install-WingetPackage $id;
Remove-DesktopIcon "UniFi*";
};
# ToDo: Add restoration

View file

@ -0,0 +1,34 @@
param(
$Action,
[hashtable] $Arguments
)
& {
param($parameters)
. "$PSScriptRoot/../../../Common/Scripts/BrowserAutomation.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
[System.Tuple[string, string, string][]] $versions = @(
[System.Tuple]::Create("visualstudio2019enterprise", "VisualStudio.16.Release", "Microsoft.VisualStudio.Product.Enterprise"),
[System.Tuple]::Create("visualstudio2019community", "VisualStudio.16.Release", "Microsoft.VisualStudio.Product.Community"),
[System.Tuple]::Create("visualstudio2022enterprise", "VisualStudio.17.Release", "Microsoft.VisualStudio.Product.Enterprise"),
[System.Tuple]::Create("visualstudio2022community", "VisualStudio.17.Release", "Microsoft.VisualStudio.Product.Community")
);
Start-SoftwareInstaller @parameters `
-Installer {
foreach ($version in $versions) {
$packageName = $version[0];
Write-Host "Installing ``$packageName``";
Install-ChocoPackage $packageName;
}
Remove-DesktopIcon "CocosCreator*";
Remove-DesktopIcon "Unity Hub*";
};
# ToDo: Add restoration
# Only restore version if it has been backed up
} $PSBoundParameters;

View file

@ -7,16 +7,11 @@ param(
. "$PSScriptRoot/../../Scripts/AppAssociations.ps1"; . "$PSScriptRoot/../../Scripts/AppAssociations.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1"; . "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Scripts/System.ps1"; . "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @PSBoundParameters `
-Installer { -Installer {
param(
[scriptblock] $Installer
)
Install-ChocoPackage winscp; Install-ChocoPackage winscp;
& $Installer -Action ([InstallerAction]::Configure)
} ` } `
-Configurator { -Configurator {
Remove-DesktopIcon "WinSCP*"; Remove-DesktopIcon "WinSCP*";

View file

@ -6,19 +6,12 @@ param(
) )
. "$PSScriptRoot/../../Scripts/Registry.ps1"; . "$PSScriptRoot/../../Scripts/Registry.ps1";
. "$PSScriptRoot/../../Scripts/Config.ps1"; . "$PSScriptRoot/../../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Scripts/System.ps1"; . "$PSScriptRoot/../../../Common/Scripts/System.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1"; . "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1"; . "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator { -Configurator {
$dir = New-TemporaryDirectory; $dir = New-TemporaryDirectory;
Push-Location $dir; 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"; . "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters ` Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator { -Configurator {
[string] $backup = $null; [string] $backup = $null;
$nativeProfile = powershell -c '$PROFILE'; $nativeProfile = powershell -c '$PROFILE';

View file

@ -0,0 +1,39 @@
param (
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Config.ps1";
& {
param(
[hashtable] $Parameters
)
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
$base = "$PSScriptRoot/../../../Common/Software/git/Manage.ps1";
Start-SoftwareInstaller @Parameters `
-Installer {
$params = "/WindowsTerminalProfile";
$defaultBranch = Get-Config "valhalla.git.defaultBranch";
if ($defaultBranch) {
$params += " /DefaultBranchName:`"$defaultBranch`"";
}
Install-ChocoPackage git -ArgumentList "--params",$params;
} `
-Configurator {
& $base ([InstallerAction]::Configure);
} `
-UserConfigurator {
param(
$Arguments
)
& $base ([InstallerAction]::ConfigureUser) @PSBoundParameterrs;
};
} $PSBoundParameters;

View file

@ -0,0 +1,14 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage osu;
Remove-DesktopIcon "*osu*";
};
# ToDo: Add restoration

View file

@ -0,0 +1,15 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-WingetPackage "ppy.osu";
Remove-DesktopIcon "*osu*";
};
# ToDo: Add restoration

View file

@ -0,0 +1,22 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Scripts/BrowserAutomation.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
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 -Timeout 1;
Write-Host "Installing reWASD…";
Start-Process -Wait -FilePath $($file.FullName) -ArgumentList "/S";
Remove-Item -Recurse $dir;
Remove-DesktopIcon "*reWASD*";
};
# ToDo: Add restoration

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

@ -0,0 +1,27 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../../Common/Software/PowerShell/Profile.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
Install-ChocoPackage zoxide;
Install-WingetPackage junegunn.fzf;
} `
-Configurator {
Add-PowerShellProfileStatement `
-System `
-Category "zoxide" `
-Script (
@(
"# zoxide",
(Get-ScriptInitializer "zoxide init powershell | Out-String")
) -join [System.Environment]::NewLine);
};

View file

@ -13,6 +13,9 @@ begin
sed "s/\//\\\\/g" sed "s/\//\\\\/g"
end end
argparse --name (status filename) -x "iso,usb" "iso" "usb" "debug" -- $argv
or exit 1
set -l setupLabel "winiso-valhalla" set -l setupLabel "winiso-valhalla"
set -l projectPath "PortValhalla" set -l projectPath "PortValhalla"
set -l systemDrivePath "sources/\$OEM\$/\$1" set -l systemDrivePath "sources/\$OEM\$/\$1"
@ -131,6 +134,13 @@ begin
"$git[5]\\bin" "$git[5]\\bin"
) \ ) \
"set SETUP_LABEL=$setupLabel" \ "set SETUP_LABEL=$setupLabel" \
(
begin
if [ -n "$_flag_debug" ]
echo "set DEBUG=1"
end
end
) \
"set PWSH_PATH=$(echo "$pwshPath" | mkWinPath)" \ "set PWSH_PATH=$(echo "$pwshPath" | mkWinPath)" \
"set LOCAL_PROJECT_PATH=$(echo "$localProjectPath" | mkWinPath)" \ "set LOCAL_PROJECT_PATH=$(echo "$localProjectPath" | mkWinPath)" \
"set REMOTE_PROJECT_PATH=$(echo "$projectPath" | mkWinPath)" \ "set REMOTE_PROJECT_PATH=$(echo "$projectPath" | mkWinPath)" \
@ -192,7 +202,7 @@ begin
find "$projectPath/profiles" -type f -name "*.nix" | while read -l file find "$projectPath/profiles" -type f -name "*.nix" | while read -l file
set -l CONFIG_MODULE "$file" set -l CONFIG_MODULE "$file"
getConfig "valhalla.windows" --json > "$file.json" getConfig "valhalla.windows.config" --json > "$file.json"
end end
end end

View file

@ -19,7 +19,7 @@ then
echo "Please specify the path to the Windows 11 ISO image in your .env file located at:"; echo "Please specify the path to the Windows 11 ISO image in your .env file located at:";
realpath --relative-to "$workingDir" "$(realpath .env)"; realpath --relative-to "$workingDir" "$(realpath .env)";
else else
WIN11_IMAGE_PATH="$WIN11_IMAGE_PATH" fish ./deploy.fish; WIN11_IMAGE_PATH="$WIN11_IMAGE_PATH" exec fish ./deploy.fish $@;
fi; fi;
popd > /dev/null; popd > /dev/null;