Compare commits

...

278 commits

Author SHA1 Message Date
Manuel Thalmann 346e93983d Add scripts for backing up and restoring LGHub 2024-08-28 05:05:55 +02:00
Manuel Thalmann 4a23017987 Allow users to restore a backup 2024-08-28 04:40:32 +02:00
Manuel Thalmann 682c281b04 Add scripts for backing up and restoring personal files 2024-08-28 04:40:00 +02:00
Manuel Thalmann 899b58261b Fix non-functioning profile script 2024-08-28 04:39:15 +02:00
Manuel Thalmann 87408b9080 Ensure 7z is installed for backups 2024-08-28 04:38:56 +02:00
Manuel Thalmann db422c45fb Streamline restoration of directories 2024-08-28 04:38:30 +02:00
Manuel Thalmann fd514b1415 Set a default path for backup artifacts 2024-08-28 00:38:20 +02:00
Manuel Thalmann 16271566f2 Add capabilities to back up apps 2024-08-28 00:37:04 +02:00
Manuel Thalmann b01faf1145 Allow specifying a backup action 2024-08-28 00:29:33 +02:00
Manuel Thalmann bf51308c30 Ignore unspecified backup archives 2024-08-28 00:22:38 +02:00
Manuel Thalmann cddf06a9d3 Ignore inexistent backup artifacts 2024-08-28 00:21:06 +02:00
Manuel Thalmann 00d9809fcb Make the install script action agnostic 2024-08-28 00:03:28 +02:00
Manuel Thalmann 53a0e59649 Rename the Windows installer script 2024-08-27 23:35:56 +02:00
Manuel Thalmann d7c7d69318 Rename outdated script 2024-08-27 23:08:41 +02:00
Manuel Thalmann 058126c70d Silence errors concerning empty aliae configurations 2024-08-27 22:35:31 +02:00
Manuel Thalmann 922f8d73e6 Make Operations script cross platform 2024-08-27 22:27:44 +02:00
Manuel Thalmann d4360a4a15 Handle OneShot tasks only on Windows 2024-08-27 21:32:49 +02:00
Manuel Thalmann 3614be475e Add a script for managing backups 2024-08-27 21:05:51 +02:00
Manuel Thalmann 1047a7a471 Add tools for managing aliae 2024-08-27 18:58:33 +02:00
Manuel Thalmann f5f024f97f Fix non-functioning aliae installation 2024-08-27 18:55:12 +02:00
Manuel Thalmann 7e25efe764 Create dedicated script for creating users 2024-08-27 17:04:17 +02:00
Manuel Thalmann ba0d0dca61 Create dedicated script for installing software 2024-08-27 16:41:08 +02:00
Manuel Thalmann aef7893551 Prevent reading nix config multiple times 2024-08-27 14:35:04 +02:00
Manuel Thalmann c2337fe349 Ensure only one user is enabled at once 2024-08-27 14:11:31 +02:00
Manuel Thalmann fecb9f37aa Prevent unnecessary file creation 2024-08-27 14:06:56 +02:00
Manuel Thalmann 45ad9cb17e Execute OneShot tasks in any operation 2024-08-27 14:05:16 +02:00
Manuel Thalmann a4bc01ec04 Use /mnt as mount directory 2024-08-27 04:30:12 +02:00
Manuel Thalmann 1974ee6de7 Force the use of the managed distribution 2024-08-27 04:26:25 +02:00
Manuel Thalmann b0570d00af Initialize operation for all users 2024-08-27 04:24:29 +02:00
Manuel Thalmann 91c0f27d36 Handle initialization in operation code 2024-08-27 04:15:37 +02:00
Manuel Thalmann c281421a30 Execute script non-interactive during OneShot tasks 2024-08-27 03:50:08 +02:00
Manuel Thalmann 04f89fc882 Exit script after running OneShot task 2024-08-27 03:45:44 +02:00
Manuel Thalmann c79adc4a0d Modify user after first login 2024-08-27 03:27:54 +02:00
Manuel Thalmann 021bb87ac2 Rearm Windows Activation before creating MSAcc 2024-08-27 03:25:19 +02:00
Manuel Thalmann 3cb39f09ae Register MSAcc logon script early 2024-08-27 03:24:37 +02:00
Manuel Thalmann 12855a4c04 Allow rebooting without registering setup 2024-08-27 03:11:35 +02:00
Manuel Thalmann d27beb12c1 Fix non-functioning NoProfile argument 2024-08-27 02:09:04 +02:00
Manuel Thalmann c28cf9b477 Prevent unnecessary installation actions 2024-08-27 01:57:46 +02:00
Manuel Thalmann 0e2125b6d4 Only install PowerShell module if necessary 2024-08-27 01:25:32 +02:00
Manuel Thalmann fd67b3b181 Streamline PowerShell installation 2024-08-27 00:45:46 +02:00
Manuel Thalmann 256075c01d Add further functionality to the WSL script 2024-08-27 00:38:46 +02:00
Manuel Thalmann 2bd173fe3a Create a separate script for WSL interaction 2024-08-26 23:33:46 +02:00
Manuel Thalmann 051d7a53c7 Fix recursive configuration 2024-08-25 03:58:28 +02:00
Manuel Thalmann b066099e48 Fix malformed module 2024-08-24 18:35:43 +02:00
Manuel Thalmann c7c3d71eff Keep Windows fixes separate 2024-08-24 16:56:29 +02:00
Manuel Thalmann 91632eb913 Remove WSL after operation 2024-08-24 16:52:41 +02:00
Manuel Thalmann 90a496ea40 Make distribution name unique 2024-08-24 16:41:05 +02:00
Manuel Thalmann 117150194e Streamline WSL distribution name 2024-08-24 16:27:34 +02:00
Manuel Thalmann ba34d28e56 Remove unused resources after user setup 2024-08-24 16:15:10 +02:00
Manuel Thalmann ebb79c338c Print update logs properly 2024-08-24 14:47:51 +02:00
Manuel Thalmann 1ca1bad92f Allow overriding Windows settings 2024-08-24 14:20:22 +02:00
Manuel Thalmann 8c7452dd10 Update incorrect path 2024-08-24 14:11:38 +02:00
Manuel Thalmann 0440e60c68 Simplify osu!lazer installation 2024-08-24 14:10:02 +02:00
Manuel Thalmann d1f1b6769e Determine name of setup user properly 2024-08-24 14:01:05 +02:00
Manuel Thalmann b6047670ba Make OMP configuration platform independent 2024-08-24 13:27:48 +02:00
Manuel Thalmann 1ae8393738 Fix incorrect character in OMP theme 2024-08-24 13:27:35 +02:00
Manuel Thalmann 8aeaf02cd1 Remove unnecessary code 2024-08-24 04:25:07 +02:00
Manuel Thalmann a80e9b7e89 Remove unnecessary loop 2024-08-24 04:24:55 +02:00
Manuel Thalmann 303de8216e Add missing module 2024-08-24 04:24:37 +02:00
Manuel Thalmann 94f9160cde Add nextcloud to the module list 2024-08-24 04:18:57 +02:00
Manuel Thalmann f2074466ae Add a function for creating shortcuts 2024-08-24 04:18:33 +02:00
Manuel Thalmann 6d6ca0ff04 Configure nextcloud syncs 2024-08-24 04:07:47 +02:00
Manuel Thalmann e615aa5df4 Allow configuring nextcloud syncs 2024-08-24 04:07:35 +02:00
Manuel Thalmann 9eb95e6b4a Create separate option holding win users 2024-08-24 03:25:28 +02:00
Manuel Thalmann 02d744d06c Rename Nextcloud installer 2024-08-24 01:50:07 +02:00
Manuel Thalmann 577bb648e3 Add file system driver for dual boot 2024-08-24 01:41:09 +02:00
Manuel Thalmann ee6403ee9c Prevent unnecessary config evaluation 2024-08-24 01:31:39 +02:00
Manuel Thalmann 30005f965e Fix non-functioning installer 2024-08-24 01:27:26 +02:00
Manuel Thalmann dcac949106 Install vscode extensions by default 2024-08-24 01:16:56 +02:00
Manuel Thalmann ff6ee5b034 Load theme file from WSL properly 2024-08-24 00:59:59 +02:00
Manuel Thalmann 006b60b080 Update aliae configuration script 2024-08-24 00:42:57 +02:00
Manuel Thalmann bbb294dc48 Strip duplicate variables and aliases 2024-08-24 00:08:58 +02:00
Manuel Thalmann 8fcf599606 Install posh theme automatically 2024-08-23 23:53:48 +02:00
Manuel Thalmann 91ddea6b5a Export missing function 2024-08-23 23:50:13 +02:00
Manuel Thalmann 624398c0b6 Install aliae by default 2024-08-23 23:46:23 +02:00
Manuel Thalmann fdf63e7376 Add scripts for changing aliae config 2024-08-23 23:44:51 +02:00
Manuel Thalmann ebe1144446 Fix compatibility with mixed new line characters 2024-08-23 23:44:23 +02:00
Manuel Thalmann c95bfd61e2 Add a script for installing aliae 2024-08-23 22:38:28 +02:00
Manuel Thalmann cd066d6e0d Add desired posh theme 2024-08-23 19:43:06 +02:00
Manuel Thalmann 2d11059b6f Make option names more clear 2024-08-23 19:42:27 +02:00
Manuel Thalmann 6157dbc28a Allow configuring oh-my-posh 2024-08-23 19:39:18 +02:00
Manuel Thalmann 024fba459e Fetch config from proper section 2024-08-23 19:24:49 +02:00
Manuel Thalmann 065edebbee Adjust configuration accordingly 2024-08-23 19:14:09 +02:00
Manuel Thalmann 31d98d632d Refactor option descriptions 2024-08-23 19:02:06 +02:00
Manuel Thalmann 4570f76510 Clean up the Windows configuration 2024-08-23 18:59:49 +02:00
Manuel Thalmann 69a5a09b34 Clean up the users.nix file 2024-08-23 18:51:54 +02:00
Manuel Thalmann 6ca15c54dc Create dedicated rclone module 2024-08-23 18:48:30 +02:00
Manuel Thalmann 64cf51ede8 Move git module to separate directory 2024-08-23 18:42:16 +02:00
Manuel Thalmann 6ad5b92d2e Move git options to separate module 2024-08-23 18:40:24 +02:00
Manuel Thalmann 9c68c31d3a Fix inheritance of user config 2024-08-23 18:28:20 +02:00
Manuel Thalmann 8b7f2f3ea4 Allow OS specific settings 2024-08-23 18:11:48 +02:00
Manuel Thalmann efc61159e6 Update archiso 2024-08-23 14:19:56 +02:00
Manuel Thalmann 0fdb876482 Set user info during git setup 2024-08-23 02:01:16 +02:00
Manuel Thalmann a21eb3d17b Make all config scripts platform independent 2024-08-23 01:57:53 +02:00
Manuel Thalmann 6f99c09cb7 Allow leaving aliases unspecified 2024-08-23 01:52:25 +02:00
Manuel Thalmann db61088819 Make scripts platform independent 2024-08-23 01:52:04 +02:00
Manuel Thalmann a754f963b1 Add scripts for configuring git 2024-08-23 01:43:26 +02:00
Manuel Thalmann 6d5c8d5db4 Configure software implicitly 2024-08-23 01:41:32 +02:00
Manuel Thalmann 91d0952f51 Skip profile creation for PinnedItem 2024-08-22 23:55:41 +02:00
Manuel Thalmann 95724eeb69 Allow skipping powershell module registration 2024-08-22 23:55:00 +02:00
Manuel Thalmann 7332a60885 Add profiles to the flake 2024-08-22 23:37:53 +02:00
Manuel Thalmann 00c64ae665 Remove user profile of OneShot user 2024-08-22 23:12:11 +02:00
Manuel Thalmann 7352452e36 Add missing OneShotTask declaration 2024-08-22 20:41:30 +02:00
Manuel Thalmann e7aa169cb3 Fix infinite loop 2024-08-22 20:41:17 +02:00
Manuel Thalmann 03ce7e41d2 Fix incorrect variable name 2024-08-22 20:34:16 +02:00
Manuel Thalmann 6ea5445272 Fix handling empty error messages 2024-08-22 20:12:18 +02:00
Manuel Thalmann 52255d2144 Add choco to the profile of the setup user 2024-08-22 13:46:55 +02:00
Manuel Thalmann bdadb20cfe Fix incorrect typings 2024-08-22 11:11:12 +02:00
Manuel Thalmann 15bf4d13c5 Fix permission issues when enabling Win hack 2024-08-22 11:11:00 +02:00
Manuel Thalmann 8ae77868d8 Register setup script as admin 2024-08-22 11:10:39 +02:00
Manuel Thalmann 92852eba76 Execute the entire installer using live scripts 2024-08-21 23:21:32 +02:00
Manuel Thalmann 45654bb508 Streamline the creation of users 2024-08-21 18:34:18 +02:00
Manuel Thalmann d025d642f8 Replace osk with cmd during debugging 2024-08-21 18:33:41 +02:00
Manuel Thalmann 0ee20e6a4b Prevent pauses in OneShot tasks 2024-08-21 18:28:50 +02:00
Manuel Thalmann 1a059cbc92 Print commands in debug mode 2024-08-21 18:28:08 +02:00
Manuel Thalmann a233206c29 Run OneShot tasks with dedicated user 2024-08-21 18:27:47 +02:00
Manuel Thalmann 0758455a6e Add function for generating startup command 2024-08-21 18:26:58 +02:00
Manuel Thalmann 7d405f1295 Allow registering startup script for the default user 2024-08-21 18:20:11 +02:00
Manuel Thalmann 4fb9e5d3ba Prevent unnecessary errors during WSL execution 2024-08-21 14:08:26 +02:00
Manuel Thalmann a5f8f11c7e Register WSL before running OneShot tasks 2024-08-21 03:37:44 +02:00
Manuel Thalmann 11c3b98018 Overwrite broken module 2024-08-21 03:20:37 +02:00
Manuel Thalmann e040336c9e Prevent initialization of nested operations 2024-08-21 03:18:31 +02:00
Manuel Thalmann 2783605187 Improve log messages of OneShot tasks 2024-08-21 02:02:30 +02:00
Manuel Thalmann 39efe78ea5 Retry Linux path conversion for errors 2024-08-20 00:20:33 +02:00
Manuel Thalmann 128eb478ad Fix typo 2024-08-20 00:20:07 +02:00
Manuel Thalmann 51027e1f8f Fix broken signature of Restart-Intermediate 2024-08-19 12:07:26 +02:00
Manuel Thalmann 0352e9a064 Report unexpected path conversions 2024-08-19 02:50:41 +02:00
Manuel Thalmann 0051c3415a Load missing path 2024-08-19 02:50:19 +02:00
Manuel Thalmann 6856664321 Ensure error file can be read from 2024-08-19 02:24:45 +02:00
Manuel Thalmann 95f21a035e Streamline OneShot task handler 2024-08-19 02:24:30 +02:00
Manuel Thalmann a33fdd1989 Simplify script registration 2024-08-19 02:24:13 +02:00
Manuel Thalmann 58a4f0a9a4 Fix broken regedit paths 2024-08-19 01:38:25 +02:00
Manuel Thalmann b2b6167600 Allow registering reboots for users 2024-08-19 01:37:14 +02:00
Manuel Thalmann 3859040556 Prevent users from being excluded 2024-08-19 01:10:29 +02:00
Manuel Thalmann d19b0c58b1 Force copying of Linux users to Windows 2024-08-19 00:54:13 +02:00
Manuel Thalmann 68c458372a Improve log messages of updates 2024-08-18 12:20:21 +02:00
Manuel Thalmann 2f7f8078a7 Remove unnecessary command 2024-08-18 10:24:15 +02:00
Manuel Thalmann 7f94799428 Fix time for QEMU VMs 2024-08-18 09:35:16 +02:00
Manuel Thalmann 19659aac61 Remove unnecessary desktop icons 2024-08-18 09:25:23 +02:00
Manuel Thalmann cda0bd71dd Add a timeout for the reWASD downloader 2024-08-18 09:05:04 +02:00
Manuel Thalmann cd8b063d56 Allow setting a timeout for clicking download buttons 2024-08-18 09:04:42 +02:00
Manuel Thalmann 64c2727622 Emit errors concerning WSL commands 2024-08-17 13:51:10 +02:00
Manuel Thalmann 51e635a062 Emit errors using Write-Error 2024-08-17 13:49:21 +02:00
Manuel Thalmann a6405bd849 Convert Argument to string explicitly 2024-08-16 23:03:19 +02:00
Manuel Thalmann 51459355b0 Ignore unfinished browser downloads 2024-08-16 17:57:22 +02:00
Manuel Thalmann 48b1bcf0c6 Install powershell modules for all users 2024-08-16 16:43:30 +02:00
Manuel Thalmann eb9ae752df Fix typos 2024-08-16 16:10:09 +02:00
Manuel Thalmann 636e5b2cb3 Install AutoHotkey as preparation 2024-08-16 15:22:09 +02:00
Manuel Thalmann 8a6cbfa260 Allow running live scripts in debug mode 2024-08-16 15:21:41 +02:00
Manuel Thalmann 7a7c2d560e Generate env variables using shorthand scripts 2024-08-16 15:16:56 +02:00
Manuel Thalmann aa1ee66df8 Allow running installation in debug mode 2024-08-16 15:16:28 +02:00
Manuel Thalmann 0edd672f73 Redirect winiso exit code properly 2024-08-16 15:13:53 +02:00
Manuel Thalmann bb85fbef3c Allow specifying winiso build type 2024-08-16 15:13:33 +02:00
Manuel Thalmann 69c7865374 Refactor winget check for rare issue 2024-08-16 15:04:37 +02:00
Manuel Thalmann 3863bf20a5 Disable Windows Update reboot only as admin 2024-08-16 14:35:35 +02:00
Manuel Thalmann b12569cc1d Add a function for queueing startup commands 2024-08-15 18:34:48 +02:00
Manuel Thalmann 9e7191968c Hide output of DISM commands 2024-08-15 13:57:15 +02:00
Manuel Thalmann 081be84541 Ensure website is loaded before download 2024-08-15 02:42:00 +02:00
Manuel Thalmann 4d39414478 Prevent Jellyfin from rebooting 2024-08-15 02:22:07 +02:00
Manuel Thalmann f14f66e91b Improve handling of slow websites 2024-08-14 18:47:29 +02:00
Manuel Thalmann 6af7a2d885 Fix potential CRC errors 2024-08-14 18:46:42 +02:00
Manuel Thalmann 3ed8bf77ba Ensure auto reboot is disabled properly 2024-08-12 21:32:53 +02:00
Manuel Thalmann e49a4ba069 Disable auto reboot by default 2024-08-12 01:27:50 +02:00
Manuel Thalmann c04e2c2fb9 Add methods for managing auto restart feature 2024-08-12 01:23:42 +02:00
Manuel Thalmann 40bd60f130 Install Wave Link first 2024-08-11 18:27:16 +02:00
Manuel Thalmann 0c581a8375 Throw an error when failing to load config 2024-08-11 18:27:06 +02:00
Manuel Thalmann 7cf55602ca Fix incorrect script path 2024-08-10 20:37:10 +02:00
Manuel Thalmann 51bea62f79 Allow leaving install action unspecified 2024-08-10 19:27:56 +02:00
Manuel Thalmann a5e807b643 Retrieve registry value properly 2024-08-10 19:26:53 +02:00
Manuel Thalmann e03943fd97 Add scripts for installing git 2024-08-10 15:28:10 +02:00
Manuel Thalmann 910dbd0dae Remove unnecessary code 2024-08-10 15:24:15 +02:00
Manuel Thalmann 9604edccde Add a function for removing the RunOnce key 2024-08-10 15:24:04 +02:00
Manuel Thalmann a27875b7df Set user groups properly 2024-08-10 15:23:38 +02:00
Manuel Thalmann b272a36245 Configure MS accounts properly 2024-08-10 15:21:13 +02:00
Manuel Thalmann 1032100106 Queue next user after configuration finished 2024-08-10 15:20:36 +02:00
Manuel Thalmann 38043700e6 Disable UAC after logging in MS account 2024-08-10 15:19:14 +02:00
Manuel Thalmann 91fc212e8b Enable OneShot listener for MS accounts 2024-08-10 15:18:10 +02:00
Manuel Thalmann ea28ec2f23 Set timezone automatically 2024-08-10 15:17:21 +02:00
Manuel Thalmann 76d4d93cc2 Prevent variable overwrite 2024-08-10 15:16:57 +02:00
Manuel Thalmann 8274daf1b7 Register installer script after disabling UAG 2024-08-10 15:16:27 +02:00
Manuel Thalmann 2430d81343 Redirect user for configuration properly 2024-08-10 15:16:00 +02:00
Manuel Thalmann 065882aca8 Fix broken redirection of arguments 2024-08-10 15:15:40 +02:00
Manuel Thalmann 223b6bcbc7 Determine installer action properly 2024-08-10 15:15:21 +02:00
Manuel Thalmann a980cb66ce Redirect arguments to chocolatey properly 2024-08-10 15:13:46 +02:00
Manuel Thalmann facc04959a Fix non-functioning OneShot script 2024-08-10 15:13:20 +02:00
Manuel Thalmann 051b7aeaeb Fix oneshot task execution 2024-08-10 06:11:55 +02:00
Manuel Thalmann fe85d19cd8 Allow removing the OneShot listener 2024-08-10 05:19:24 +02:00
Manuel Thalmann a5dd12a857 Remove duplicate code 2024-08-10 05:17:08 +02:00
Manuel Thalmann 12cbaa5331 Fix typo 2024-08-10 03:57:37 +02:00
Manuel Thalmann 5e2dd156b9 Fix copy paste error 2024-08-10 03:57:26 +02:00
Manuel Thalmann 12c79d0666 Allow skipping the User parameter 2024-08-10 03:40:37 +02:00
Manuel Thalmann 379df3b55d Fix incorrect script path 2024-08-10 03:13:13 +02:00
Manuel Thalmann 0e963b6efd Fix broken scripts 2024-08-10 01:50:52 +02:00
Manuel Thalmann a1aed0074e Remove unnecessary confirmation dialogue 2024-08-10 00:23:47 +02:00
Manuel Thalmann 60ac69074f Add a task for disabling UAC 2024-08-10 00:23:37 +02:00
Manuel Thalmann 1878f6d2c0 Force creation of sudo alias 2024-08-10 00:22:46 +02:00
Manuel Thalmann d7db66a359 Allow execution of OneShot tasks 2024-08-10 00:22:30 +02:00
Manuel Thalmann 36a784f475 Ensure CONFIG_MODULE is resolved 2024-08-09 23:23:55 +02:00
Manuel Thalmann f65f41b01b Add dedicated functions for creating startup scripts 2024-08-09 23:23:29 +02:00
Manuel Thalmann 3845edd6f8 Change login message 2024-08-09 22:11:12 +02:00
Manuel Thalmann 70db88f485 Set up shared WSL 2024-08-09 16:02:33 +02:00
Manuel Thalmann 67ff96b459 Install updates only as admin 2024-08-09 16:02:24 +02:00
Manuel Thalmann 8a3940941d Disable boot message only as admin 2024-08-09 16:02:00 +02:00
Manuel Thalmann 7efc63f24f Add a function for allowing user access 2024-08-09 15:56:16 +02:00
Manuel Thalmann d792c2d5ad Fix broken reboot registration 2024-08-09 15:49:36 +02:00
Manuel Thalmann 72eec78a18 Ensure the script path is detected properly 2024-08-09 14:45:50 +02:00
Manuel Thalmann da11bb46f7 Allow automatic script execution for MS accounts 2024-08-09 14:45:29 +02:00
Manuel Thalmann 07070b8ed1 Reorder winget arguments 2024-08-09 14:45:05 +02:00
Manuel Thalmann e7de253509 Allow registering reboot for the default user 2024-08-09 14:44:57 +02:00
Manuel Thalmann 33a8fe8d2e Add a dedicated function for disabling boot message 2024-08-09 13:35:12 +02:00
Manuel Thalmann ae1c05ff35 Implement root install loop using a switch 2024-08-09 13:34:46 +02:00
Manuel Thalmann 08e6c78d31 Force computer reboots 2024-08-09 04:42:55 +02:00
Manuel Thalmann d5bb09916e Add scripts for controlling UAC 2024-08-09 04:29:26 +02:00
Manuel Thalmann e3b9eab9d3 Set displayname of all users 2024-08-09 04:20:00 +02:00
Manuel Thalmann a2f3d1ff76 Login to users for configuration 2024-08-09 04:19:49 +02:00
Manuel Thalmann 5521118d8e Skip PWSH_PATH if undefined 2024-08-09 04:08:22 +02:00
Manuel Thalmann 69310fe702 Fix typo 2024-08-09 03:38:10 +02:00
Manuel Thalmann 6e714db198 Add missing setup stage 2024-08-09 03:02:25 +02:00
Manuel Thalmann 305391bec7 Make Get-Users output explicit 2024-08-09 03:02:17 +02:00
Manuel Thalmann be7fb65f72 Allow displaying a boot message 2024-08-09 02:59:06 +02:00
Manuel Thalmann 88f4720758 Disable users by default 2024-08-09 02:58:01 +02:00
Manuel Thalmann f74f7066e0 Add a stage for configuring users 2024-08-09 02:27:24 +02:00
Manuel Thalmann f418daa4c9 Detect installation properly 2024-08-09 02:24:59 +02:00
Manuel Thalmann c1d1bb14f1 Remove unnecessary icon 2024-08-09 02:23:56 +02:00
Manuel Thalmann 4adf4fa861 Add Predator Z301C to the hardware list 2024-08-09 02:23:41 +02:00
Manuel Thalmann 192add34e1 Add support for the sudo command 2024-08-09 02:22:45 +02:00
Manuel Thalmann e7ade5b55f Fix renaming user 2024-08-09 02:20:27 +02:00
Manuel Thalmann 939ed5574c Make specifying PWSH_PATH optional 2024-08-09 02:12:27 +02:00
Manuel Thalmann 44bd8fd5f6 Show error properly 2024-08-09 02:00:18 +02:00
Manuel Thalmann e01239cda5 Fix typo 2024-08-09 01:53:59 +02:00
Manuel Thalmann 4fa4f6f2bf Remove code duplication 2024-08-09 01:33:04 +02:00
Manuel Thalmann 136a5cc314 Remove unnecessary console output 2024-08-09 01:22:51 +02:00
Manuel Thalmann dd40c0b04b Fix incorrect file paths 2024-08-09 00:17:05 +02:00
Manuel Thalmann eed989f4f1 Fix incorrect hardware name 2024-08-09 00:03:45 +02:00
Manuel Thalmann 4f65cf181f Reorder installation steps 2024-08-08 23:03:10 +02:00
Manuel Thalmann 6fd44e17eb Suppress unnecessary output 2024-08-08 22:24:41 +02:00
Manuel Thalmann 863e8d0a53 Refactor the wsl installation check 2024-08-08 22:21:49 +02:00
Manuel Thalmann 6d371c9eae Ensure WSL Ubuntu is installed 2024-08-08 22:08:13 +02:00
Manuel Thalmann e298767531 Make config script platform independent 2024-08-08 18:21:16 +02:00
Manuel Thalmann 95698011d4 Leave groups unspecified 2024-08-08 17:50:32 +02:00
Manuel Thalmann 6e8b09d2f2 Add users during installation 2024-08-08 17:49:43 +02:00
Manuel Thalmann 13e1cd5b02 Fix incorrect user conversion 2024-08-08 17:16:51 +02:00
Manuel Thalmann 3dd0871deb Keep Windows groups separate 2024-08-08 15:33:55 +02:00
Manuel Thalmann d8e96e1f8b Remove unnecessary options from Win users 2024-08-08 15:32:05 +02:00
Manuel Thalmann f2eccc00d5 Inherit Windows users from linux 2024-08-08 15:28:29 +02:00
Manuel Thalmann dfccaae81f Add functions for retrieving attributes 2024-08-08 14:45:34 +02:00
Manuel Thalmann 7f4454af55 Install Oh My Posh system wide 2024-08-08 14:23:15 +02:00
Manuel Thalmann 44cc0e6a9d Fix typo 2024-08-08 14:22:22 +02:00
Manuel Thalmann b9f8a95cac Skip scope argument by default 2024-08-08 14:22:13 +02:00
Manuel Thalmann 3f77d636d4 Fix incorrect file paths 2024-08-08 14:21:55 +02:00
Manuel Thalmann 0426ff3fcc Configure NVS after installation 2024-08-08 14:09:20 +02:00
Manuel Thalmann a903b8fa85 Refactor app association script 2024-08-08 14:09:07 +02:00
Manuel Thalmann 37752cb27d Fix typo 2024-08-08 14:08:48 +02:00
Manuel Thalmann 96404ea5be Apply the error action globally 2024-08-08 14:08:38 +02:00
Manuel Thalmann df40a8b531 Move PinnedItem script to proper location 2024-08-08 14:04:51 +02:00
Manuel Thalmann 7dc4b86e7c Add notes to installation script 2024-08-08 14:03:15 +02:00
Manuel Thalmann d03b9eef75 Add a script for installing LGHub 2024-08-08 13:25:21 +02:00
Manuel Thalmann 861c519c86 Reorder installation steps 2024-08-08 13:17:14 +02:00
Manuel Thalmann 53af5fd434 Reload env after installing git 2024-08-08 12:18:04 +02:00
Manuel Thalmann 6bfed53082 Enure features for PinnedItem are installed 2024-08-08 05:21:21 +02:00
Manuel Thalmann 40673bc66a Install features using chocolatey 2024-08-08 05:20:58 +02:00
Manuel Thalmann 0dcbf245f8 Ensure git is installed 2024-08-08 05:14:31 +02:00
Manuel Thalmann 3256aee9fb Fix broken XML document creation 2024-08-08 05:04:59 +02:00
Manuel Thalmann 045a5de325 Fix incorrect parameter access 2024-08-08 05:03:24 +02:00
Manuel Thalmann b3e4f57140 Fix incorrect path 2024-08-08 05:01:45 +02:00
Manuel Thalmann abd24b69d9 Add a dedicated user option for windows 2024-08-08 04:45:27 +02:00
Manuel Thalmann b2e288b9e3 Add a stage for creating users 2024-08-08 04:38:40 +02:00
Manuel Thalmann d453c4e773 Add scripts for all remaining apps 2024-08-08 04:36:35 +02:00
Manuel Thalmann 9f54702158 Allow custom winget arguments 2024-08-08 04:29:00 +02:00
Manuel Thalmann 23954e7e9f Improve winget function 2024-08-08 04:28:21 +02:00
Manuel Thalmann a2c6d8bc04 Add missing function 2024-08-08 04:20:11 +02:00
Manuel Thalmann e91c7ba371 Refactor browser scripts 2024-08-08 03:32:03 +02:00
Manuel Thalmann b6135b0750 Ensure Selenium is imported 2024-08-08 02:59:02 +02:00
Manuel Thalmann ab07c87c57 Allow skipping the Action argument 2024-08-08 02:56:28 +02:00
Manuel Thalmann 1b7e2b5966 Rename all old installation scripts 2024-08-08 02:56:13 +02:00
Manuel Thalmann 8655012f33 Add options for enabling LG Hub 2024-08-08 02:32:15 +02:00
Manuel Thalmann 9d9d910554 Remove Firefox taskbar icon 2024-08-08 02:32:15 +02:00
Manuel Thalmann 5a64f8e42d Allow removing task bar icons 2024-08-08 02:31:59 +02:00
106 changed files with 4448 additions and 1105 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -43,6 +43,12 @@
description = "A value indicating whether an Elgato Wave device is present.";
default = false;
};
logitechG = mkOption {
type = types.bool;
description = "A value indicating whether a Logitech G device is present.";
default = false;
};
};
};
};

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,24 +5,10 @@
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;
};
};
});
capitalize = (import ../text.nix { inherit lib; }).capitalize;
userType = types.submodule (
{ ... }: {
{ ... } : {
options = {
displayName = mkOption {
type = types.nullOr types.str;
@ -41,21 +27,27 @@
description = "The additional groups of the user.";
default = [];
};
};
});
linuxUserType = types.submodule (
{ ... }: {
options = {
defaultShell = mkOption {
type = types.nullOr types.str;
description = "The default shell of the user.";
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.";
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 {
imports = [
./git.nix
./packages/git.nix
./packages/nextcloud.nix
./packages/oh-my-posh.nix
./packages/rclone.nix
./hardware.nix
./i18n.nix
./os.nix
./partition.nix
./software.nix
./users.nix

View file

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

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

@ -1,7 +1,7 @@
#!/bin/pwsh
$null = New-Module {
. "$PSScriptRoot/../../../scripts/Common/Scripts/Context.ps1";
. "$PSScriptRoot/../../../scripts/Windows/OS/Manage.ps1";
. "$PSScriptRoot/../../../scripts/Windows/OS/Legacy.ps1";
Write-Host "Starting Backup of Windows";
$context = [Context]::new();

View file

@ -2,7 +2,7 @@
. "$PSScriptRoot/Drivers.ps1";
. "$PSScriptRoot/../../../scripts/Common/Scripts/Context.ps1";
. "$PSScriptRoot/../../../scripts/Windows/Collections/Personal.ps1"
. "$PSScriptRoot/../../../scripts/Windows/OS/Install.ps1";
. "$PSScriptRoot/../../../scripts/Windows/OS/Manage.ps1";
function Initialize-Configuration {
# Fix synchronization between Linux and Windows clock

View file

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

View file

@ -1,6 +1,6 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../scripts/Common/Scripts/Context.ps1";
. "$PSScriptRoot/../../../scripts/Windows/OS/Install.ps1";
. "$PSScriptRoot/../../../scripts/Windows/OS/Manage.ps1";
. "$PSScriptRoot/../../../scripts/Windows/Collections/Generic.ps1"
function Restore-Apps {

View file

@ -3,6 +3,7 @@
fs = import ../../lib/modules/partition/fs.nix;
in {
imports = [
../manuel/config.nix
../../lib/modules/valhalla.nix
];
@ -44,7 +45,10 @@
"wheel"
"nix-users"
];
};
};
linux.users.manuel = {
defaultShell = "fish";
rclone = {
@ -57,6 +61,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";
}
];
};
};

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

@ -52,21 +52,25 @@ $null = New-Module {
[string] $OutDir
)
if (-not $OutDir) {
$OutDir = ".";
}
$downloadAction = $Action;
$dir = New-TemporaryDirectory;
Write-Host "Downloading ``$URL`` using browser automation…";
$options = [OpenQA.Selenium.Firefox.FirefoxOptions]::new();
$options.SetPreference("browser.download.folderList", 2);
$options.SetPreference("browser.download.dir", "$dir");
$downloadChecker = {
$files = Get-ChildItem $dir;
if ((@($files)).Count -gt 0) {
foreach ($file in $files) {
Start-BrowserAutomation {
if (-not $OutDir) {
$OutDir = ".";
}
$dir = New-TemporaryDirectory;
Write-Host "Downloading ``$URL`` using browser automation…";
$options = [OpenQA.Selenium.Firefox.FirefoxOptions]::new();
$options.SetPreference("browser.download.folderList", 2);
$options.SetPreference("browser.download.dir", "$dir");
$downloadChecker = {
$files = Get-ChildItem $dir;
if ((@($files)).Count -eq 1) {
$file = $files[0];
try {
$stream = [System.IO.File]::Open($file.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None);
@ -77,28 +81,38 @@ $null = New-Module {
catch {
return $true;
}
return $false;
} else {
return $true;
}
};
$browser = [OpenQA.Selenium.Firefox.FirefoxDriver]::new($options);
$browser.Navigate().GoToUrl($URL);
return $false;
} else {
return $true;
while (-not ($browser.ExecuteScript("return document.readyState;") -eq "complete")) {
Start-Sleep 0.1;
}
};
$browser = [OpenQA.Selenium.Firefox.FirefoxDriver]::new($options);
$browser.Navigate().GoToUrl($URL);
& $Action -Browser $browser;
while (& $downloadChecker) {
Write-Host "Waiting for the download to finish…";
Start-Sleep 1;
try {
$null = & $downloadAction -Browser $browser;
while (& $downloadChecker) {
Write-Host "Waiting for the download to finish…";
Start-Sleep 1;
}
$file = Get-ChildItem $dir;
$result = Move-Item $file $OutDir -PassThru;
$browser.Quit();
Remove-Item -Recurse $dir;
$result;
}
catch {
Write-Error $Error;
}
}
$file = Get-ChildItem $dir;
$result = Move-Item $file $OutDir -PassThru;
$browser.Quit();
Remove-Item -Recurse $dir;
$result;
}
<#
@ -113,12 +127,16 @@ $null = New-Module {
.PARAMETER OutDir
The directory to download the file to.
.PARAMETER Timeout
The number of seconds to wait before clicking the download button.
#>
function Start-BrowserDownload {
param(
[string] $URL,
[string] $ButtonSelector,
[string] $OutDir = $null
[string] $OutDir = $null,
[double] $Timeout = 0
)
Start-CustomBrowserDownload @PSBoundParameters -Action {
@ -126,7 +144,28 @@ $null = New-Module {
[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

@ -2,15 +2,32 @@ using namespace Microsoft.Win32;
using namespace System.Security.AccessControl;
using namespace System.Security.Principal;
enum SetupStage {
enum WindowsInstallerStage {
Initialize
Run
Completed
}
enum SetupStage {
Configure
Install
CreateUser
}
enum UserStage {
Create
Configure
Cleanup
Completed
}
$null = New-Module {
[string] $configRoot = "HKLM:\Software\PortValhalla";
[string] $stageOption = "Stage";
[string] $setupStageOption = "SetupStage";
[string] $userOption = "SetupUser";
[string] $userStageOption = "UserStage";
[string] $accountOption = "MSAccount";
[string] $finishedOption = "Finished";
[RegistryKey] $key = $null;
@ -26,14 +43,36 @@ $null = New-Module {
[string] $Path
)
$job = Start-Job {
$env:Value = Resolve-Path $Using:Path;
$env:WSLENV = "Value/p";
$result = wsl -- bash -c 'echo "$Value"';
wsl -e printf "%q" "$result";
};
& {
$ErrorActionPreference = 'Continue';
$completed = $false;
Receive-Job -Wait $job;
while (-not $completed) {
$job = Start-Job {
$env:Value = Resolve-Path $Using:Path;
$env:WSLENV = "Value/p";
$result = wsl -- bash -c 'echo "$Value"';
wsl -e printf "%q" "$result";
};
$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 +114,34 @@ $null = New-Module {
$scriptPath = "$PSScriptRoot/../../Common/Scripts/config.fish";
function fish {
wsl --shell-type login -- nix --extra-experimental-features "nix-command flakes" run nixpkgs`#fish -- $args
}
if ($env:CONFIG_MODULE) {
$output = & {
if (-not $IsWindows) {
$escapedPath = (fish -c 'string escape $argv' "$scriptPath");
fish -c ". $escapedPath; $Script";
} else {
function fish {
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 -and ($output | Test-Json))) {
Write-Error "The value ``$output`` is not valid JSON.";
} else {
$output | ConvertFrom-Json;
}
} else {
$null;
}
}
<#
@ -91,10 +153,67 @@ $null = New-Module {
#>
function Get-Config {
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
)
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 +221,19 @@ $null = New-Module {
Gets the names of the users to create.
#>
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";
}
<#
@ -148,11 +279,44 @@ $null = New-Module {
<#
.SYNOPSIS
Gets the name of the current setup stage.
Gets the name of the current stage of the Windows install script action.
#>
function Get-Stage {
$stage = Get-SetupOption $stageOption;
if ($null -ne $stage) {
$stage = [WindowsInstallerStage]$stage;
}
return $stage;
}
<#
.SYNOPSIS
Sets the name of the current stage of the Windows install script action.
.PARAMETER Name
The name of the stage to set.
#>
function Set-Stage {
param(
$Name
)
if (-not (($null -eq $Name) -or ($Name -is [string]))) {
$Name = ([WindowsInstallerStage]$Name).ToString();
}
$null = Set-SetupOption $stageOption $Name;
}
<#
.SYNOPSIS
Gets the name of the current setup stage.
#>
function Get-SetupStage {
$stage = Get-SetupOption $setupStageOption;
if ($null -ne $stage) {
$stage = [SetupStage]$stage;
}
@ -167,7 +331,7 @@ $null = New-Module {
.PARAMETER Name
The name to set the current stage to.
#>
function Set-Stage {
function Set-SetupStage {
param(
$Name
)
@ -176,7 +340,86 @@ $null = New-Module {
$Name = ([SetupStage]$Name).ToString();
}
$null = Set-SetupOption $stageOption $Name;
$null = Set-SetupOption $setupStageOption $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;
}
<#
@ -184,7 +427,7 @@ $null = New-Module {
Gets a value indicating whether the setup has finished.
#>
function Get-IsFinished {
return [bool] (Get-SetupOption $finishedOption);
return [bool](Get-SetupOption $finishedOption);
}
<#
@ -211,7 +454,15 @@ $null = New-Module {
[string] $Name
)
Get-Config "valhalla.software.$Name";
Get-Config "$(Get-ConfigRootName).software.$Name";
}
<#
.SYNOPSIS
Checks whether the running system is a QEMU virtual machine.
#>
function Test-Qemu {
((Get-WmiObject win32_computersystem).Manufacturer) -eq "QEMU";
}
<#
@ -219,7 +470,7 @@ $null = New-Module {
Checks whether the current user is the setup user.
#>
function Test-SetupUser {
$env:UserName -eq (Get-Config "valhalla.windows.setupUser");
($IsWindows ? $env:UserName : $env:USER) -eq (Get-SetupUser);
}
<#

View file

@ -1,14 +1,412 @@
function Start-Operation {
param(
[scriptblock] $Action
)
using namespace System.Management.Automation.Host;
$ErrorActionPreference = 'Inquire';
$env:WSLENV = "CONFIG_MODULE/p";
. "$PSScriptRoot/../Types/OneShotTask.ps1";
if ($env:CONFIG_MODULE) {
$env:CONFIG_MODULE = Resolve-Path $env:CONFIG_MODULE;
$null = New-Module {
. "$PSScriptRoot/Config.ps1";
. "$PSScriptRoot/../Scripts/SoftwareManagement.ps1";
. "$PSScriptRoot/../Types/OneShotTask.ps1";
. "$PSScriptRoot/../../Windows/Scripts/Hooks.ps1";
. "$PSScriptRoot/../../Windows/Scripts/PowerManagement.ps1";
. "$PSScriptRoot/../../Windows/Scripts/Registry.ps1";
. "$PSScriptRoot/../../Windows/Scripts/Security.ps1";
. "$PSScriptRoot/../../Windows/Scripts/WSL.ps1";
$oneShotTaskName = "PortValhalla OneShot";
$logName = "Application";
$oneShotTrigger = 1337;
$taskOption = "OneShotTask";
# ToDo: Store "ProgramData/PortValhalla" path somewhere as const
$errorPath = "$env:ProgramData/PortValhalla/error.txt";
$getUserName = {
"$(Get-SetupUser)OneShot";
};
$taskSetter = {
param([Nullable[OneShotTask]] $Task)
Set-SetupOption $taskOption ([string]$Task);
};
function Start-Operation {
param(
[switch] $NonInteractive,
[switch] $NoImplicitCleanup,
[scriptblock] $Action
)
$cleanup = { };
$taskPending = $false;
if ($IsWindows -and ($null -ne (Get-OneShotTask))) {
$taskPending = $true;
[switch] $NonInteractive = $true;
}
if (-not $Global:InOperation) {
if ($env:DEBUG) {
Set-PSDebug -Trace 1;
}
if ($null -ne (Get-OneShotTask)) {
$taskPending = $true;
[switch] $NonInteractive = $true;
}
$Global:InOperation = $true;
$Global:ErrorActionPreference = $NonInteractive.IsPresent ? 'Continue' : 'Inquire';
if ($IsWindows) {
$env:WSLENV = "CONFIG_MODULE/p";
if ($env:CONFIG_MODULE) {
$env:CONFIG_MODULE = Resolve-Path $env:CONFIG_MODULE;
}
if (Test-Admin) {
Disable-WindowsUpdateAutoRestart;
}
New-Alias -Force "sudo" gsudo;
}
if (-not $NoImplicitCleanup.IsPresent) {
$cleanup = {
Clear-OperationResources;
};
}
& {
$initialized = $false;
while (-not $initialized) {
if ($IsWindows) {
if (-not ((Test-Command "choco") -and (Test-Command "refreshenv"))) {
Invoke-Hook "Install-Chocolatey" -Fallback {
# Install chocolatey
New-Item -Force $PROFILE;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
Import-Module $env:ChocolateyInstall/helpers/chocolateyProfile.psm1;
refreshenv;
};
continue;
}
if (-not (Test-ChocoPackage "powershell-core")) {
Invoke-Hook "Install-PowerShellCore" -Fallback {
choco install -y powershell-core --install-arguments='"ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 REGISTER_MANIFEST=1 USER_MU=1 ENABLE_MU=1"';
};
Restart-Intermediate;
return;
}
if ($env:PWSH_PATH -and (Test-Path $env:PWSH_PATH)) {
attrib "-R" "$env:PWSH_PATH\*" /S /D;
Remove-Item -Recurse -Force $env:PWSH_PATH;
continue;
}
if ($env:DEBUG) {
if (
(Get-Item $env:INSTALLER_SCRIPT).IsReadOnly -and
(Test-Qemu) -and
($Host.UI.PromptForChoice(
"Confirm",
"Do you wish to swap to live scripts?",
[ChoiceDescription[]]@(
[ChoiceDescription]::new("&No", "Use scripts stored in the virtual machine"),
[ChoiceDescription]::new("&Yes", "Use live scripts stored on the host")),
0) -eq 1)) {
Install-ChocoPackage winfsp qemu-guest-agent;
Get-Service VirtioFsSvc | Start-Service -PassThru | Set-Service -StartupType Automatic;
while (-not (Test-Path Z:\)) {
Start-Sleep 0.1;
}
foreach ($name in @("CONFIG_MODULE", "INSTALLER_SCRIPT")) {
$variable = Get-Item "Env:\$name";
$path = Join-Path `
"Z:\Repositories\PortValhalla" `
([System.IO.Path]::GetRelativePath("$PSScriptRoot/../../..", $variable.Value));
Set-Item "Env:\$name" $path;
Write-Host "The new value of ``$name`` is ``$path``";
}
Restart-Intermediate;
exit;
}
}
if (-not (Test-Command "gsudo")) {
Install-ChocoPackage gsudo;
refreshenv;
continue;
}
if ($env:DEBUG) {
& {
$sys32 = "$env:WINDIR/System32";
$osk = (Get-Item "$sys32/osk.exe").FullName;
$cmd = (Get-Item "$sys32/cmd.exe").FullName;
if ((Get-FileHash $osk).Hash -ne (Get-FileHash $cmd).Hash) {
Set-MpPreference -ExclusionPath $osk;
gsudo -d --ti move $osk "${osk}_";
gsudo -d -s copy $cmd $osk;
continue;
}
};
}
if (-not (Test-Winget)) {
. "$PSScriptRoot/../../Windows/Software/winget/Manage.ps1";
continue;
}
if (-not (Test-Command "git")) {
Install-WingetPackage Git.Git;
refreshenv;
continue;
}
if (-not (Test-Command "7z")) {
Install-ChocoPackage 7zip.portable;
refreshenv;
continue;
}
if (-not (Test-Command "yq")) {
Install-ChocoPackage "yq";
refreshenv;
continue;
}
if (-not (Test-Wsl)) {
Install-Wsl;
Restart-Intermediate;
return;
}
if (-not (Test-WslDistribution)) {
if (-not (Test-Path (Get-WslDistributionDisk))) {
Install-WslDistribution;
}
Register-WslDistribution;
continue;
}
if (-not (wsl --shell-type login type -t nix)) {
wsl -- sh `<`(curl -L https://nixos.org/nix/install`) --daemon --yes;
wsl --shutdown;
continue;
}
if (-not (Test-PSPackage Selenium.WebDriver)) {
Write-Host "Installing browser automation tools…";
$null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies;
continue;
}
Install-ChocoPackage selenium-gecko-driver firefox;
Install-WingetPackage AutoHotkey.AutoHotkey;
. "$PSScriptRoot/../../Windows/Software/PinnedItem/Manage.ps1";
}
Invoke-Hook "Install-PSModules" -Fallback {
$modules = @(
@("PSScriptAnalyzer")
) + (& {
if (-not $IsWindows) {
@()
} else {
@(
@("KnownFolders"),
@("PSWindowsUpdate"),
@("LocalAccounts", $true),
@("NuGet")
)
}
});
foreach ($module in $modules) {
$parameters = @{ };
if ($module -is [string]) {
$module = @($module);
}
if ($module[1]) {
$parameters = @{
allowPrerelease = $true;
};
}
if (-not (Test-PSModule $module[0])) {
Install-Module -Scope AllUsers -AcceptLicense -Force -AllowClobber $module[0] @parameters;
Import-Module $module[0];
}
}
};
$initialized = $true;
}
}
}
if ($taskPending) {
Start-OneShot;
} else {
& $Action;
}
& $cleanup;
}
& $Action;
}
<#
.SYNOPSIS
Gets the current OneShot task.
#>
function Get-OneShotTask {
$task = Get-SetupOption $taskOption;
if ($task) {
return [OneShotTask]$task;
} else {
return $null;
}
}
<#
.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
)
& $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;
}
};
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 {
try {
Write-Host "Running OneShot task ``$(Get-OneShotTask)``";
switch (Get-OneShotTask) {
([OneShotTask]::InitializeMSAccount) {
Initialize-UserCreation;
}
([OneShotTask]::DisableUAC) {
Disable-UAC;
Register-Setup;
}
}
}
catch {
Set-Content -Path $errorPath -Value $Error;
Set-UserPermissions $errorPath;
}
finally {
& $taskSetter $null;
Write-EventLog -LogName $logName -Source $logName -EventId $oneShotTrigger -Message "The OneShot task ``$(Get-OneShotTask)`` finished.";
}
}
<#
.SYNOPSIS
Clears resources allocated during the operation.
#>
function Clear-OperationResources {
if ($IsWindows) {
Uninstall-WslDistribution;
}
}
};

View file

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

View file

@ -42,7 +42,7 @@ $null = New-Module {
}
if ($Names.Count -ge 1) {
choco install -y $ArgumentList $Names;
choco install -y @ArgumentList @Names;
}
}
@ -56,23 +56,74 @@ $null = New-Module {
function Install-WingetPackage {
param(
[switch] $Force,
[string[]] $ArgumentList,
[Parameter(Position=0)]
[string] $Name,
[Parameter(ValueFromRemainingArguments = $true)]
[string[]] $Names
[string[]] $AdditionalNames = @()
)
[System.Collections.ArrayList] $Names = @();
$null = $Names.Add($Name);
$Names.AddRange($AdditionalNames);
foreach ($name in $Names) {
if ($Force.IsPresent -or -not (Test-WingetPackage $name)) {
winget install `
--accept-source-agreements --accept-package-agreements `
--source winget `
--scope machine `
--exact --id $name;
$ArgumentList `
--exact --id $name ;
} else {
Write-Host "Package ``$name`` is already installed"
}
}
}
<#
.SYNOPSIS
Installs a setup package from the specified source.
.PARAMETER Source
The location of the setup package.
.PARAMETER ArgumentList
The arguments to pass to the setup package.
.PARAMETER Local
A value indicating whether the setup package is stored locally.
#>
function Install-SetupPackage {
param(
[string] $Source,
[string[]] $ArgumentList = @("/S"),
[switch] $Local
)
[string] $dir = $null;
[string] $filePath = $null;
if (-not ($Local.IsPresent)) {
$dir = New-TemporaryDirectory;
Write-Host "Determining the file name of ``$Source``";
$fileName = ([uri]$Source).Segments[-1];
Write-Host "Found name ``$fileName``";
$filePath = Join-Path $dir $fileName;
Write-Host "Downloading setup file from ``$Source``";
Invoke-WebRequest $Source -OutFile $filePath;
} else {
$filePath = $Source;
}
Write-Host "Starting installation of ``$(Split-Path -Leaf $filePath)``";
Start-Process -Wait -WorkingDirectory (Split-Path -Parent $filePath) -FilePath $filePath -ArgumentList $ArgumentList;
if ($dir) {
Remove-Item -Recurse $dir;
}
}
<#
.SYNOPSIS
Installs a package downloaded from ASUS.
@ -134,25 +185,35 @@ $null = New-Module {
try {
& $download;
} catch {
$Browser.ExecuteScript("document.querySelector('$cookieBannerSelector').remove()");
$null = $Browser.ExecuteScript("document.querySelector('$cookieBannerSelector').remove()");
& $download;
}
};
Start-Process -Wait -WorkingDirectory $dir -FilePath $file -ArgumentList "/S";
Start-Process -Wait -WorkingDirectory (Split-Path -Parent "$file") -FilePath "$file" -ArgumentList "/S";
Remove-Item -Recurse $dir;
}
function Start-SoftwareInstaller {
param(
[string] $Name,
[scriptblock] $Installer = { },
[scriptblock] $Configurator = { },
[scriptblock] $UserConfigurator = { },
[InstallerAction] $Action = [InstallerAction]::Install,
[scriptblock] $Backup = $null,
[scriptblock] $Installer = $null,
[scriptblock] $Configurator = $null,
[scriptblock] $UserBackup = $null,
[scriptblock] $UserConfigurator = $null,
[Nullable[InstallerAction]] $Action,
[hashtable] $Arguments
)
[InstallerAction] $Action = & {
if ($null -ne $Action) {
$Action;
} else {
[InstallerAction]::Install;
}
};
if (-not $Name) {
$Name = Split-Path -Leaf (Split-Path -Parent ((Get-PSCallStack)[1].ScriptName));
}
@ -176,26 +237,54 @@ $null = New-Module {
installer = $installHandler;
arguments = $Arguments;
};
if ($action -eq ([InstallerAction]::Install)) {
Write-Host "Installing $Name";
& $Installer @argumentList;
# ToDo: Automatically configure after installation
} elseif ($Action -eq ([InstallerAction]::Configure)) {
Write-Host "Configuring $Name";
& $Configurator @argumentList;
if (-not (Test-SetupUser)) {
$argumentList.Add("action", [InstallerAction]::ConfigureUser);
& $installHandler @argumentList;
switch ($Action) {
([InstallerAction]::Backup) {
if ($Backup) {
Write-Host "Backing up $Name";
& $Backup @argumentList;
}
}
} elseif ($Action -eq ([InstallerAction]::ConfigureUser)) {
if ((-not $Arguments.ContainsKey($userArgument)) -or ($null -eq $Arguments[$userArgument])) {
$argumentList.Add($userArgument, ($env:UserName));
([InstallerAction]::Install) {
if ($Installer) {
Write-Host "Installing $Name";
& $Installer @argumentList;
}
& $installHandler @argumentList -Action ([InstallerAction]::Configure);
if ($UserConfigurator -and (-not (Test-SetupUser))) {
& $installHandler @argumentList -Action ([InstallerAction]::ConfigureUser);
}
}
([InstallerAction]::Configure) {
if ($Configurator) {
Write-Host "Configuring $Name";
& $Configurator @argumentList;
}
}
default {
if ((-not $Arguments.ContainsKey($userArgument)) -or (-not $Arguments[$userArgument])) {
$Arguments.Add($userArgument, ($IsWindows ? $env:UserName : $env:USER));
}
$user = $Arguments[$userArgument];
switch ($_) {
([InstallerAction]::BackupUser) {
if ($UserBackup) {
Write-Host "Backing up ``$Name`` for user ``$user``";
& $UserBackup @argumentList;
}
}
([InstallerAction]::ConfigureUser) {
if ($UserConfigurator) {
Write-Host "Configuring $Name for user ``$user``";
& $UserConfigurator @argumentList;
}
}
}
}
Write-Host "Configuring $Name for user ``$($Arguments[$userArgument])``";
& $UserConfigurator @argumentList;
}
};

View file

@ -79,10 +79,14 @@ function Test-Command {
Checks whether `winget` is working properly.
#>
function Test-Winget {
(Test-Command winget) -and -not (
[System.Linq.Enumerable]::Any(
[string[]](winget source update winget),
[System.Func[string,bool]]{ param($line) $line -eq "Cancelled"; }));
(Test-Command winget) -and (
& {
$output = winget source update winget;
$? -and -not ([System.Linq.Enumerable]::Any(
[string[]]($output),
[System.Func[string,bool]]{ param($line) $line -eq "Cancelled"; }));
});
}
<#
@ -99,3 +103,18 @@ function Test-PSPackage {
[bool] (Get-Package $Name -ErrorAction SilentlyContinue);
}
<#
.SYNOPSIS
Checks whether a module with the specified name is installed.
.PARAMETER Name
The name of the module to check.
#>
function Test-PSModule {
param(
[string] $Name
)
[bool](Get-Module -ListAvailable $Name -ErrorAction SilentlyContinue);
}

View file

@ -29,3 +29,40 @@ function Remove-DesktopIcon {
}
}
}
<#
.SYNOPSIS
Adds a new shortcut to the start menu.
.PARAMETER Name
The name of the icon to create.
.PARAMETER Target
The file to link to.
#>
function Add-StartMenuIcon {
param(
[string] $Name,
[string] $Target
)
Import-Module KnownFolders;
Import-Module "$env:ChocolateyInstall/helpers/chocolateyInstaller.psm1";
Install-ChocolateyShortcut -ShortcutFilePath "$((Get-KnownFolder "Common Programs").Path)/$Name.lnk" -TargetPath ((Get-Item $Target).FullName);
}
<#
.SYNOPSIS
Removes icons from the task bar.
.PARAMETER Pattern
The pattern of the icon names to remove.
#>
function Remove-TaskbarItem {
param(
[string] $Pattern
)
Import-Module -UseWindowsPowerShell PinnedItem;
Get-PinnedItem -Type TaskBar | Where-Object { $_.Name -like "$Pattern" } | Remove-PinnedItem;
}

View file

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

View file

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

View file

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

View file

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

View file

@ -75,9 +75,11 @@ $null = New-Module {
Push-Location ~;
$profiles = $profiles |
ForEach-Object { [System.IO.Path]::GetRelativePath((Get-Location), $_) } |
ForEach-Object { "$HomeDir/$_" };
$profiles = @(
$profiles |
ForEach-Object { [System.IO.Path]::GetRelativePath((Get-Location), $_) } |
ForEach-Object { "$HomeDir/$_" }
);
Pop-Location;
}

View file

@ -9,7 +9,7 @@ param (
$parameters = Get-ModuleInstallerComponents "Terminal-Icons";
foreach ($key in $PSBoundParameters.Keys) {
$parameters.Add($key, $PSBoundParameters.TryGetValue($key));
$parameters.Add($key, $PSBoundParameters[$key]);
}
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) {
$null = & ([scriptblock]::Create((aliae init pwsh --config $globalPath))) *>&1;
}
if (Test-Path $userPath) {
$null = & ([scriptblock]::Create((aliae init pwsh))) *>&1;
}
aliae completion powershell | Out-String | Invoke-Expression;
}
) -join [System.Environment]::NewLine)
} `
-UserConfigurator {
Copy-Item -Force "$PSScriptRoot/aliae.yml" ~/.aliae.yml;
};

View file

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

View file

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

View file

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

View file

@ -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";
foreach ($key in $PSBoundParameters.Keys) {
$parameters.Add($key, $PSBoundParameters.TryGetValue($key));
$parameters.Add($key, $PSBoundParameters[$key]);
}
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
set -l dir (status dirname)
source "$dir/../../Scripts/software.fish"
source "$dir/../../../Common/Software/aliae/main.fish"
function userConfig -a name
set -l bins codium codium-insiders code code-insiders
set -l extensions zokugun.{sync-settings,vsix-manager}
for bin in $bins
if type -q "$bin"
for extension in $extensions
sudo -u "$name" "$bin" --install-extension "$extension"
end
end
end
function userConfig -V dir -a name
pwsh "$dir/Main.ps1" ConfigureUser;
end
runInstaller $argv

View file

@ -1,5 +1,7 @@
enum InstallerAction {
Backup
Install
Configure
BackupUser
ConfigureUser
}

View file

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

View file

@ -1,16 +1,16 @@
#!/bin/pwsh
. "$PSScriptRoot/../Software/Firefox/Install.ps1";
. "$PSScriptRoot/../Software/git/Manage.ps1";
. "$PSScriptRoot/../Software/git/Install.ps1";
. "$PSScriptRoot/../Software/LGHub/Install.ps1";
. "$PSScriptRoot/../Software/ManiaPlanet/Manage.ps1";
. "$PSScriptRoot/../Software/osu!/Manage.ps1";
. "$PSScriptRoot/../Software/osu!lazer/Manage.ps1";
. "$PSScriptRoot/../Software/ManiaPlanet/Install.ps1";
. "$PSScriptRoot/../Software/osu!/Install.ps1";
. "$PSScriptRoot/../Software/osu!lazer/Install.ps1";
. "$PSScriptRoot/../Software/PuTTY/Install.ps1";
. "$PSScriptRoot/../Software/RetroArch/Manage.ps1";
. "$PSScriptRoot/../Software/reWASD/Manage.ps1";
. "$PSScriptRoot/../Software/TrackMania Nations Forever/Manage.ps1";
. "$PSScriptRoot/../Software/TrackMania United Forever/Manage.ps1";
. "$PSScriptRoot/../Software/VisualStudio/Manage.ps1";
. "$PSScriptRoot/../Software/RetroArch/Install.ps1";
. "$PSScriptRoot/../Software/reWASD/Install.ps1";
. "$PSScriptRoot/../Software/TrackMania Nations Forever/Install.ps1";
. "$PSScriptRoot/../Software/TrackMania United Forever/Install.ps1";
. "$PSScriptRoot/../Software/VisualStudio/Install.ps1";
. "$PSScriptRoot/../../Common/Scripts/Context.ps1";
. "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1";

View file

@ -1,17 +1,17 @@
#!/bin/pwsh
. "$PSScriptRoot/Generic.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1";
. "$PSScriptRoot/../Software/git/Manage.ps1";
. "$PSScriptRoot/../Software/git/Install.ps1";
. "$PSScriptRoot/../Software/LGHub/Install.ps1";
. "$PSScriptRoot/../Software/ManiaPlanet/Manage.ps1";
. "$PSScriptRoot/../Software/osu!/Manage.ps1";
. "$PSScriptRoot/../Software/osu!lazer/Manage.ps1";
. "$PSScriptRoot/../Software/ManiaPlanet/Install.ps1";
. "$PSScriptRoot/../Software/osu!/Install.ps1";
. "$PSScriptRoot/../Software/osu!lazer/Install.ps1";
. "$PSScriptRoot/../Software/PuTTY/Install.ps1";
. "$PSScriptRoot/../Software/RetroArch/Manage.ps1";
. "$PSScriptRoot/../Software/reWASD/Manage.ps1";
. "$PSScriptRoot/../Software/TrackMania Nations Forever/Manage.ps1";
. "$PSScriptRoot/../Software/TrackMania United Forever/Manage.ps1";
. "$PSScriptRoot/../Software/VisualStudio/Manage.ps1";
. "$PSScriptRoot/../Software/RetroArch/Install.ps1";
. "$PSScriptRoot/../Software/reWASD/Install.ps1";
. "$PSScriptRoot/../Software/TrackMania Nations Forever/Install.ps1";
. "$PSScriptRoot/../Software/TrackMania United Forever/Install.ps1";
. "$PSScriptRoot/../Software/VisualStudio/Install.ps1";
. "$PSScriptRoot/../../Common/Scripts/Context.ps1";
. "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1";

View file

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

View file

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

View file

@ -1,344 +0,0 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../scripts/Windows/Scripts/Prerequisites.ps1";
. "$PSScriptRoot/../../Common/Scripts/Context.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1";
. "$PSScriptRoot/Manage.ps1";
. "$PSScriptRoot/User/Install.ps1";
$null = New-Module {
. "$PSScriptRoot/../Scripts/Hooks.ps1";
. "$PSScriptRoot/../Scripts/PowerManagement.ps1";
. "$PSScriptRoot/../Scripts/Update.ps1";
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Common/Scripts/Operations.ps1";
. "$PSScriptRoot/../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1";
. "$PSScriptRoot/../../Common/Types/InstallerAction.ps1";
<#
.SYNOPSIS
Finishes the installation of a running Windows machine.
#>
function Start-WindowsInstallation {
Start-Operation {
Start-InstallationLoop;
};
}
<#
.SYNOPSIS
Starts the installation loop.
#>
function Start-InstallationLoop {
while (-not (Get-IsFinished)) {
if ($null -eq (Get-Stage)) {
Set-Stage ([SetupStage]::Initialize);
} elseif ((Get-Stage) -eq ([SetupStage]::Initialize)) {
if (-not ((Test-Command "choco") -and (Test-Command "refreshenv"))) {
Invoke-Hook "Install-Chocolatey" -Fallback {
# Install chocolatey
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
Import-Module $env:ChocolateyInstall/helpers/chocolateyProfile.psm1;
refreshenv;
};
continue;
}
if (-not (Test-ChocoPackage "powershell-core")) {
Invoke-Hook "Install-PowerShellCore" -Fallback {
choco install -y powershell-core --install-arguments='"ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 REGISTER_MANIFEST=1 USER_MU=1 ENABLE_MU=1"';
};
Restart-Intermediate;
return;
}
if (Test-Path $env:PWSH_PATH) {
attrib "-R" "$env:PWSH_PATH\*" /S /D;
Remove-Item -Recurse -Force $env:PWSH_PATH;
continue;
}
Invoke-Hook "Install-PSModules" -Fallback {
Install-Module -AcceptLicense -Force PSWindowsUpdate;
Install-Module -AcceptLicense -Force PSScriptAnalyzer;
};
if (-not (Test-Winget)) {
. "$PSScriptRoot/../Software/winget/Manage.ps1";
continue;
}
if (-not (Test-PSPackage Selenium.WebDriver)) {
Install-Module -AcceptLicense -Force NuGet;
Import-Module NuGet;
$null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies;
continue;
}
Install-ChocoPackage selenium-gecko-driver firefox;
if (-not (& { wsl --status; $?; })) {
wsl --install --no-launch;
Restart-Intermediate;
return;
} else {
ubuntu install --root;
wsl -- sh `<`(curl -L https://nixos.org/nix/install`) --daemon --yes;
wsl --shutdown;
}
if (wsl --shell-type login type -t nix) {
Set-Stage ([SetupStage]::Configure);
}
} else {
$null = Import-Module PSWindowsUpdate;
Invoke-Hook "Invoke-WindowsUpdate" -Fallback {
Update-WindowsInstallation;
};
if ((Get-WURebootStatus -Silent)) {
Restart-Intermediate;
return;
}
<#
.SYNOPSIS
Deploys an action for each software.
.PARAMETER Action
The action to execute by default.
#>
function Deploy-SoftwareAction {
param(
[InstallerAction] $Action
)
$arguments = [hashtable]@{ };
if ($Action) {
$arguments.Add("action", $Action);
}
# Drivers
$null = New-Module {
$driverPath = "$PSScriptRoot/../Drivers";
$mbPath = "$driverPath/ROG Zenith Extreme Alpha";
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 (-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 (-not (Test-ChocoPackage wavelink)) {
Install-ChocoPackage wavelink -ArgumentList '--install-arguments="/norestart"';
Remove-DesktopIcon "*Wave Link*";
Restart-Intermediate;
exit;
}
}
}
if (Get-Config "valhalla.hardware.eyeX") {
. "$driverPath/Tobii EyeX/Manage.ps1" @arguments;
}
};
$null = New-Module {
# Windows Config
$softwarePath = "$PSScriptRoot/../Software";
$commonSoftware = "$PSScriptRoot/../../Common/Software";
. "$softwarePath/Windows/Manage.ps1" @arguments;
if (Test-Collection "essential") {
# Essentials
. "$softwarePath/OpenSSH/Manage.ps1" @arguments;
. "$softwarePath/PowerShell/Manage.ps1" @arguments;
. "$softwarePath/chocolatey/Manage.ps1" @arguments;
. "$commonSoftware/posh-git/Manage.ps1" @arguments;
. "$commonSoftware/Terminal-Icons/Manage.ps1" @arguments;
. "$commonSoftware/Oh My Posh/Manage.ps1" @arguments;
}
if (Test-Collection "common") {
# Common Software
. "$softwarePath/WinSCP/Manage.ps1" @arguments;
. "$softwarePath/Thunderbird/Manage.ps1" @arguments;
}
if (Test-Collection "desktopExperience") {
# Internet Access
. "$softwarePath/Firefox/Manage.ps1" @arguments;
if (Test-Collection "fileSync") {
. "$softwarePath/Nextcloud/Manage.ps1" @arguments;
}
}
};
}
switch (Get-Stage) {
([SetupStage]::Configure) {
if (Get-Config "valhalla.windows.dualboot.enable") {
# Fix synchronization between Linux and Windows clocks.
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Value 1 -Type "DWord";
# Force time resynchronization
$service = Get-Service W32Time;
$stopped = ($service.Status -eq "Stopped");
Start-Service $service;
w32tm /resync /force;
if ($stopped) {
Stop-Service $service;
}
}
Set-Stage ([SetupStage]::Install);
}
([SetupStage]::Install) {
Write-Host "Entering install phase";
Deploy-SoftwareAction;
Set-IsFinished $true;
}
}
}
}
}
function Invoke-WindowsInstallation([Context] $context) {
$Global:InformationPreference = "Continue";
$Global:ErrorActionPreference = "Inquire";
$context.UserNames ??= @("Manuel");
Start-OldWindowsInstallationScript $context;
}
function Start-OldWindowsInstallationScript([Context] $context) {
. "$PSScriptRoot/Upgrade.ps1";
$finished = $false;
Remove-Item Env:\POSH_THEME -ErrorAction SilentlyContinue;
$configPath = "$PSScriptRoot/../Config";
$softwarePath = "$PSScriptRoot/../Software";
$initialConfigStage = "InitialConfiguration";
$prerequisitesStage = "InstallationPrerequisites";
$driverStage = "DriverInstallation";
$softwareStage = "MachineWideSoftwareInstallation";
$userStage = "CreatingUser";
$restorationStage = "Restoring";
while (-not $finished) {
switch ($context.GetStage()) {
{ (-not $_) -or ($_ -eq $initialConfigStage) } {
$context.SetStage($initialConfigStage);
if ((Get-Command Initialize-Configuration -ErrorAction SilentlyContinue)) {
Write-Information "Configuration initialization function was found. Running...";
Initialize-Configuration $context;
}
$null = Enable-WindowsOptionalFeature -Online -All -FeatureName "NetFx3";
. "$configPath/Windows/Install.ps1" $context;
. "$configPath/Explorer/Install.ps1" $context;
. "$configPath/OpenSSH/Install.ps1" $context;
. "$configPath/chocolatey/Install.ps1";
$context.RemoveDesktopIcon("*Microsoft Edge*");
$context.SetStage($prerequisitesStage);
break;
}
# Always install updates
default {
Write-Host "Starting Installation and Restoration of Windows";
Update-WindowsInstallation $context;
}
$prerequisitesStage {
Write-Host "Installing prerequisites for installing software";
if (-not $(Get-Command winget)) {
choco install -y winget;
}
Install-Module -AcceptLicense -Force "NuGet";
Import-Module NuGet;
Install-Firefox $context;
choco install -y selenium-gecko-driver;
$null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies;
winget install --accept-source-agreements --accept-package-agreements -e --id AutoHotkey.AutoHotkey;
$context.SetStage($driverStage);
break;
}
$driverStage {
Write-Host "Installing drivers";
if ((Get-Command Install-PortValhallaDrivers -ErrorAction SilentlyContinue)) {
Write-Information "Driver installation function was found. Starting installation";
Install-PortValhallaDrivers $context;
}
Write-Information "Finished installing drivers";
$context.SetStage($softwareStage);
$context.Reboot();
exit;
}
$softwareStage {
Write-Host "Setting up software with default app associations";
. "$softwarePath/WinSCP/Install.ps1" $context;
. "$softwarePath/Thunderbird/Install.ps1" $context;
Write-Host "Installing default settings for new users";
. "$softwarePath/aliae/Install.ps1" $context;
. "$softwarePath/posh-git/Install.ps1";
. "$softwarePath/Terminal-Icons/Install.ps1";
. "$softwarePath/Oh My Posh/Install.ps1" $context;
$context.SetStage($userStage);
break;
}
$userStage {
Install-PersonalUsers $context;
$context.SetStage($restorationStage);
break;
}
$restorationStage {
Restore-WindowsInstallation $context;
$finished = $true;
break;
}
}
}
}
};

View file

@ -0,0 +1,63 @@
#!/bin/pwsh
. "$PSScriptRoot/../Scripts/PersonalFiles.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1";
. "$PSScriptRoot/../Software/Nextcloud/Install.ps1";
. "$PSScriptRoot/../Collections/Personal.ps1";
. "$PSScriptRoot/../../Common/Scripts/Context.ps1";
function Backup-WindowsInstallation([Context] $context) {
Write-Information "Backing up Windows";
$Global:InformationPreference = "Continue";
$Global:ErrorActionPreference = "Inquire";
. "$PSScriptRoot/../../../scripts/Windows/Scripts/Prerequisites.ps1";
$backupRoot = $context.BackupRoot();
Backup-PersonalFiles $context;
Backup-PersonalApps $context;
$context.Backup($backupRoot, "$backupRoot.7z", @("-sdel"), $false);
$context.Cleanup();
Write-Host "Never forget to store the backup somewhere safe!";
Write-Host "I mean... what kind of a dumbass would ever forget to do so, right?";
}
function Restore-WindowsInstallation([Context] $context) {
Write-Host "Restoring Windows";
choco feature enable -n useEnhancedExitCodes;
function Read-Path()
{
$backupPath = Read-Host -Prompt "Please enter the path to the archive to load the backup from.";
if ($backupPath -and (-not (Test-Path -PathType Leaf $backupPath)))
{
Write-Host "No file could be found at the specified path.";
return Read-Path;
}
else
{
return $backupPath;
}
}
Install-Firefox $context;
Restore-Nextcloud $context;
Write-Information "Determining Backup Archive Path";
$backupPath = Read-Path;
$context.BackupName ??= "PortValhalla";
$context.RootDir = $context.GetTempDirectory();
if ($backupPath)
{
$context.Restore($backupPath, $context.BackupRoot());
}
Copy-UserInternationalSettingsToSystem -WelcomeScreen $True -NewUser $False;
Restore-PersonalFiles $context;
if ((Get-Command Restore-Apps -ErrorAction SilentlyContinue)) {
Restore-Apps $context;
}
Remove-Item -Recurse $context.RootDir;
$context.Cleanup();
}

View file

@ -1,63 +1,244 @@
#!/bin/pwsh
. "$PSScriptRoot/../Scripts/PersonalFiles.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1";
. "$PSScriptRoot/../Software/Nextcloud/Install.ps1";
. "$PSScriptRoot/../Collections/Personal.ps1";
using namespace System.Security.Principal;
. "$PSScriptRoot/../../../scripts/Windows/Scripts/Prerequisites.ps1";
. "$PSScriptRoot/../../../scripts/Windows/Scripts/WSL.ps1";
. "$PSScriptRoot/../../Common/Scripts/Context.ps1";
. "$PSScriptRoot/../Scripts/Security.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1";
. "$PSScriptRoot/Legacy.ps1";
. "$PSScriptRoot/User/Install.ps1";
function Backup-WindowsInstallation([Context] $context) {
Write-Information "Backing up Windows";
$Global:InformationPreference = "Continue";
$Global:ErrorActionPreference = "Inquire";
. "$PSScriptRoot/../../../scripts/Windows/Scripts/Prerequisites.ps1";
$backupRoot = $context.BackupRoot();
Backup-PersonalFiles $context;
Backup-PersonalApps $context;
$context.Backup($backupRoot, "$backupRoot.7z", @("-sdel"), $false);
$context.Cleanup();
Write-Host "Never forget to store the backup somewhere safe!";
Write-Host "I mean... what kind of a dumbass would ever forget to do so, right?";
}
$null = New-Module {
. "$PSScriptRoot/../Scripts/Deployment.ps1";
. "$PSScriptRoot/../Scripts/Hooks.ps1";
. "$PSScriptRoot/../Scripts/PowerManagement.ps1";
. "$PSScriptRoot/../Scripts/Registry.ps1";
. "$PSScriptRoot/../Scripts/Security.ps1";
. "$PSScriptRoot/../Scripts/Update.ps1";
. "$PSScriptRoot/../Scripts/Users.ps1";
. "$PSScriptRoot/../Types/WindowsInstallerAction.ps1";
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Common/Scripts/Operations.ps1";
. "$PSScriptRoot/../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1";
. "$PSScriptRoot/../../Common/Types/InstallerAction.ps1";
function Restore-WindowsInstallation([Context] $context) {
Write-Host "Restoring Windows";
choco feature enable -n useEnhancedExitCodes;
<#
.SYNOPSIS
Finishes the installation of a running Windows machine.
#>
function Start-WindowsInstallation {
Start-Operation -NoImplicitCleanup {
Start-InstallationLoop ([WindowsInstallerAction]::Install);
};
}
<#
.SYNOPSIS
Starts the installation loop.
#>
function Start-InstallationLoop {
param(
[WindowsInstallerAction] $Action
)
function Read-Path()
{
$backupPath = Read-Host -Prompt "Please enter the path to the archive to load the backup from.";
while ((Get-Stage) -ne ([WindowsInstallerStage]::Completed)) {
switch (Get-Stage) {
($null) {
Set-Stage ([WindowsInstallerStage]::Initialize);
break;
}
([WindowsInstallerStage]::Initialize) {
$env:BACKUP_ARCHIVE = pwsh -Command Write-Host (
Read-Host (
& {
switch ($Action) {
([WindowsInstallerAction]::Backup) {
"Please select the path you wish to store your backup at"
}
([WindowsInstallerAction]::Install) {
"Please select an archive you wish to restore from, if you wish to restore from a backup"
}
}
}));
if ($backupPath -and (-not (Test-Path -PathType Leaf $backupPath)))
{
Write-Host "No file could be found at the specified path.";
return Read-Path;
}
else
{
return $backupPath;
Set-Stage ([WindowsInstallerStage]::Run);
break;
}
([WindowsInstallerStage]::Run) {
switch ($Action) {
([WindowsInstallerAction]::Install) {
while (-not (Get-IsFinished)) {
if (Test-Admin) {
$null = Import-Module PSWindowsUpdate;
Invoke-Hook "Invoke-WindowsUpdate" -Fallback {
Update-WindowsInstallation;
};
if ((Get-WURebootStatus -Silent)) {
Restart-Intermediate;
return;
}
}
switch (Get-SetupStage) {
($null) {
Set-SetupStage ([SetupStage]::Configure);
break;
}
([SetupStage]::Configure) {
if (Get-Config "valhalla.windows.dualboot.enable") {
if (-not (Test-Qemu)) {
# Fix synchronization between Linux and Windows clocks.
Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Value 1 -Type "DWord";
}
# Force time resynchronization
$timeZoneOption = "Start";
$timeZoneKey = "HKLM:\SYSTEM\CurrentControlSet\Services\tzautoupdate";
$service = Get-Service W32Time;
$autoUpdate = (Get-Item $timeZoneKey).GetValue($timeZoneOption);
$stopped = ($service.Status -eq "Stopped");
$setUpdate = { param([int] $Value) Set-ItemProperty $timeZoneKey -Name $timeZoneOption $Value };
& $setUpdate 3;
Start-Service $service;
w32tm /resync /force;
& $setUpdate $autoUpdate;
if ($stopped) {
Stop-Service $service;
}
}
Set-SetupStage ([SetupStage]::Install);
}
([SetupStage]::Install) {
Write-Host "Entering install phase";
Deploy-SoftwareAction;
Set-SetupStage ([SetupStage]::CreateUser);
}
([SetupStage]::CreateUser) {
Install-ValhallaUsers;
Set-IsFinished $true;
}
}
}
}
}
Set-Stage ([WindowsInstallerStage]::Completed);
break;
}
}
}
}
Install-Firefox $context;
Restore-Nextcloud $context;
Write-Information "Determining Backup Archive Path";
$backupPath = Read-Path;
$context.BackupName ??= "PortValhalla";
$context.RootDir = $context.GetTempDirectory();
if ($backupPath)
{
$context.Restore($backupPath, $context.BackupRoot());
function Invoke-WindowsInstallation([Context] $context) {
$Global:InformationPreference = "Continue";
$Global:ErrorActionPreference = "Inquire";
$context.UserNames ??= @("Manuel");
Start-OldWindowsInstallationScript $context;
}
Copy-UserInternationalSettingsToSystem -WelcomeScreen $True -NewUser $False;
Restore-PersonalFiles $context;
if ((Get-Command Restore-Apps -ErrorAction SilentlyContinue)) {
Restore-Apps $context;
function Start-OldWindowsInstallationScript([Context] $context) {
. "$PSScriptRoot/Upgrade.ps1";
$finished = $false;
Remove-Item Env:\POSH_THEME -ErrorAction SilentlyContinue;
$configPath = "$PSScriptRoot/../Config";
$softwarePath = "$PSScriptRoot/../Software";
$initialConfigStage = "InitialConfiguration";
$prerequisitesStage = "InstallationPrerequisites";
$driverStage = "DriverInstallation";
$softwareStage = "MachineWideSoftwareInstallation";
$userStage = "CreatingUser";
$restorationStage = "Restoring";
while (-not $finished) {
switch ($context.GetStage()) {
{ (-not $_) -or ($_ -eq $initialConfigStage) } {
$context.SetStage($initialConfigStage);
if ((Get-Command Initialize-Configuration -ErrorAction SilentlyContinue)) {
Write-Information "Configuration initialization function was found. Running...";
Initialize-Configuration $context;
}
$null = Enable-WindowsOptionalFeature -Online -All -FeatureName "NetFx3";
. "$configPath/Windows/Install.ps1" $context;
. "$configPath/Explorer/Install.ps1" $context;
. "$configPath/OpenSSH/Install.ps1" $context;
. "$configPath/chocolatey/Install.ps1";
$context.RemoveDesktopIcon("*Microsoft Edge*");
$context.SetStage($prerequisitesStage);
break;
}
# Always install updates
default {
Write-Host "Starting Installation and Restoration of Windows";
Update-WindowsInstallation $context;
}
$prerequisitesStage {
Write-Host "Installing prerequisites for installing software";
if (-not $(Get-Command winget)) {
choco install -y winget;
}
Install-Module -AcceptLicense -Force "NuGet";
Import-Module NuGet;
Install-Firefox $context;
choco install -y selenium-gecko-driver;
$null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies;
winget install --accept-source-agreements --accept-package-agreements -e --id AutoHotkey.AutoHotkey;
$context.SetStage($driverStage);
break;
}
$driverStage {
Write-Host "Installing drivers";
if ((Get-Command Install-PortValhallaDrivers -ErrorAction SilentlyContinue)) {
Write-Information "Driver installation function was found. Starting installation";
Install-PortValhallaDrivers $context;
}
Write-Information "Finished installing drivers";
$context.SetStage($softwareStage);
$context.Reboot();
exit;
}
$softwareStage {
Write-Host "Setting up software with default app associations";
. "$softwarePath/WinSCP/Install.ps1" $context;
. "$softwarePath/Thunderbird/Install.ps1" $context;
Write-Host "Installing default settings for new users";
. "$softwarePath/aliae/Install.ps1" $context;
. "$softwarePath/posh-git/Install.ps1";
. "$softwarePath/Terminal-Icons/Install.ps1";
. "$softwarePath/Oh My Posh/Install.ps1" $context;
$context.SetStage($userStage);
break;
}
$userStage {
Install-PersonalUsers $context;
$context.SetStage($restorationStage);
break;
}
$restorationStage {
Restore-WindowsInstallation $context;
$finished = $true;
break;
}
}
}
}
Remove-Item -Recurse $context.RootDir;
$context.Cleanup();
}
};

View file

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

View file

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

View file

@ -1,8 +1,9 @@
using namespace System.Xml;
$null = New-Module {
$associationElementName = "Association";
$rootSelector = "/DefaultAssociations";
$associationSelector = "./Association";
$associationSelector = "./$associationElementName";
<#
.SYNOPSIS
@ -32,7 +33,9 @@ $null = New-Module {
function Get-DefaultAppAssociations {
[OutputType([xml])]
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) {
$association = $candidates[0];
} 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;
}
@ -87,7 +95,7 @@ $null = New-Module {
$associations = $root.SelectNodes((& $getSelector));
# 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;
$writerSettings = [XmlWriterSettings]::new();
@ -96,7 +104,7 @@ $null = New-Module {
$writer = [XmlWriter]::Create($configFile.FullName, $writerSettings);
$document.Save($writer);
$writer.Dispose();
DISM /Online "/Import-DefaultAppAssociations:$($configFile.FullName)";
$null = DISM /Online "/Import-DefaultAppAssociations:$($configFile.FullName)";
Remove-Item $configFile;
}
}

View file

@ -0,0 +1,293 @@
. "$PSScriptRoot/../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Common/Scripts/SoftwareManagement.ps1";
. "$PSScriptRoot/../../Common/Types/InstallerAction.ps1";
<#
.SYNOPSIS
Deploys an action for each software selected for installation.
.PARAMETER
The action to execute.
#>
function Deploy-SoftwareAction {
param(
[System.Nullable[InstallerAction]] $Action = $null
)
[bool] $install = $false;
$arguments = [hashtable]@{ };
if ($null -ne $Action) {
$install = ($Action -eq ([InstallerAction]::Install));
$null = $arguments.Add("action", $Action);
} else {
$install = $true;
}
# Drivers
& {
$driverPath = "$PSScriptRoot/../Drivers";
$mbPath = "$driverPath/ROG Zenith Extreme Alpha";
if ($install) {
if (Get-Config "valhalla.hardware.elgatoWave") {
if (-not (Test-ChocoPackage wavelink)) {
Install-ChocoPackage wavelink -ArgumentList '--install-arguments="/norestart"';
Remove-DesktopIcon "*Wave Link*";
Restart-Intermediate;
exit;
}
}
}
foreach ($component in (Get-Config "valhalla.hardware.components")) {
switcH ($component) {
("ROG Zenith Extreme Alpha") {
& "$mbPath/MarvellEthernet/Manage.ps1" @arguments;
& "$mbPath/IntelWiFi/Manage.ps1" @arguments;
& "$mbPath/IntelBluetooth/Manage.ps1" @arguments;
& "$mbPath/AMDChipsetX399/Manage.ps1" @arguments;
& "$driverPath/AMDChipsetX399/Manage.ps1" @arguments;
}
("Predator Z301C") {
& "$driverPath/Predator Z301C/Manage.ps1" @arguments;
}
}
}
if ($install) {
if (Get-Config "valhalla.hardware.amdCPU") {
Install-ChocoPackage amd-ryzen-master;
# ToDo: backup Ryzen energy saving plan
}
if (Get-Config "valhalla.hardware.nvidiaGPU") {
Install-ChocoPackage geforce-game-ready-driver;
Remove-DesktopIcon "*Geforce*";
}
if (Get-Config "valhalla.hardware.corsairDevice") {
Install-ChocoPackage icue;
}
}
if (Get-Config "valhalla.hardware.eyeX") {
& "$driverPath/Tobii EyeX/Manage.ps1" @arguments;
}
};
& {
$softwarePath = "$PSScriptRoot/../Software";
$commonSoftware = "$PSScriptRoot/../../Common/Software";
# Windows Config
& "$softwarePath/Windows/Manage.ps1" @arguments;
if (Get-Config "valhalla.hardware.logitechG") {
& "$softwarePath/LGHub/Manage.ps1" @arguments;
}
# Essentials
if (Test-Collection "essential") {
& "$softwarePath/aliae/Main.ps1" @arguments;
& "$softwarePath/OpenSSH/Manage.ps1" @arguments;
& "$softwarePath/PowerShell/Manage.ps1" @arguments;
& "$softwarePath/chocolatey/Manage.ps1" @arguments;
& "$softwarePath/zoxide/Manage.ps1" @arguments;
& "$commonSoftware/posh-git/Manage.ps1" @arguments;
& "$commonSoftware/Terminal-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 `
;
}
}
# Common Software
if (Test-Collection "common") {
& "$softwarePath/WinSCP/Manage.ps1" @arguments;
& "$softwarePath/Thunderbird/Manage.ps1" @arguments;
& "$softwarePath/PuTTY/Manage.ps1" @arguments;
if ($install) {
Install-ChocoPackage `
7zip `
chocolateygui `
DefaultProgramsEditor `
bitwarden `
keepass `
;
Install-WingetPackage `
SomePythonThings.WingetUIStore `
;
Remove-DesktopIcon "UniGetUI*";
}
}
if (Test-Collection "desktopExperience") {
if ($install) {
# Fonts
Install-ChocoPackage nerd-fonts-CascadiaCode;
# Internet Access
Install-WingetPackage Brave.Brave kamranahmedse.pennywise;
Remove-DesktopIcon "*Brave*";
Remove-TaskbarItem "*Brave*";
Remove-DesktopIcon "Pennywise*";
# Tools
Install-SetupPackage -Source "https://github.com/mRemoteNG/mRemoteNG/releases/download/2023.03.03-v1.77.3-nb/mRemoteNG-Installer-1.77.3.nb-1784.msi" -ArgumentList "/Quiet";
Remove-DesktopIcon "mRemoteNG*";
Install-ChocoPackage `
gimp `
gpu-z `
windirstat `
winmerge `
handbrake `
hwmonitor `
qbittorrent `
imgburn `
inkscape `
krita `
MetaX `
obs-studio `
;
Remove-DesktopIcon "GIMP*";
Remove-DesktopIcon "GPU-Z*";
Remove-DesktopIcon "WinDirStat*";
Remove-DesktopIcon "*HWMonior*";
Remove-DesktopIcon "ImgBurn*";
Remove-DesktopIcon "InkScape*";
Remove-DesktopIcon "Krita*";
Remove-DesktopIcon "MetaX*";
Remove-DesktopIcon "OBS Studio*";
Install-WingetPackage `
AntSoftware.AntRenamer `
AppWork.JDownloader `
;
Remove-DesktopIcon "JDownloader*";
}
# ToDo: Consider hiding behind own config?
& "$softwarePath/Ubiquiti UniFi Controller/Manage.ps1" @arguments;
# Internet Access
& "$softwarePath/Firefox/Manage.ps1" @arguments;
& "$softwarePath/MSEdgeRedirect/Manage.ps1" @arguments;
if (Test-Collection "fileSync") {
& "$softwarePath/Nextcloud/Main.ps1" @arguments;
}
}
if (Test-Collection "socialMedia") {
if ($install) {
Install-ChocoPackage `
signal `
threema-desktop `
element-desktop `
teamspeak `
;
Remove-DesktopIcon "*Element*";
Remove-DesktopIcon "*TeamSpeak*";
Install-WingetPackage Discord.Discord;
Remove-DesktopIcon "*Discord*";
}
}
if (Test-Collection "media") {
if ($install) {
Install-ChocoPackage `
k-litecodecpackmega `
vlc `
;
Remove-DesktopIcon "VLC*";
# When installing Jellyfin Media Player after iCUE, Jellyfin will try to reboot automatically
Install-ChocoPackage jellyfin-media-player -ArgumentList "--install-args","/norestart";
Remove-DesktopIcon "Jellyfin Media Player*";
Install-WingetPackage Ytmdesktop.Ytmdesktop;
Remove-DesktopIcon "Youtube Music*";
}
}
if (Test-Collection "coding") {
if ($install) {
& "$softwarePath/vscode/Main.ps1" @arguments;
Install-ChocoPackage `
gh `
github-desktop `
ida-free `
HxD `
docker-desktop `
imhex `
dotpeek `
;
Remove-DesktopIcon "IDA *";
Remove-DesktopIcon "GitHub*";
Remove-DesktopIcon "Docker*";
}
& "$softwarePath/VisualStudio/Manage.ps1" @arguments;
# Node.js
& "$softwarePath/NVS/Manage.ps1" @arguments;
}
# Gaming
if (Test-Collection "gaming") {
if ($install) {
Install-ChocoPackage `
goggalaxy `
epicgameslauncher `
rayman-controlpanel `
ppsspp `
;
Remove-DesktopIcon "*Epic Games*";
Remove-DesktopIcon "*PPSSPP *-Bit*";
Install-ChocoPackage `
steam `
ubisoft-connect `
-ArgumentList "--ignore-checksums" `
;
Remove-DesktopIcon "*Steam*";
Remove-DesktopIcon "*Ubisoft Connect*";
Install-WingetPackage ElectronicArts.EADesktop;
Remove-DesktopIcon "EA.*";
}
& "$softwarePath/TrackMania Nations Forever/Manage.ps1" @arguments;
& "$softwarePath/TrackMania United Forever/Manage.ps1" @arguments;
& "$softwarePath/ManiaPlanet/Manage.ps1" @arguments;
& "$softwarePath/osu!/Manage.ps1" @arguments;
& "$softwarePath/osu!lazer/Manage.ps1" @arguments;
& "$softwarePath/RetroArch/Manage.ps1" @arguments;
& "$softwarePath/reWASD/Manage.ps1" @arguments;
}
};
}

View file

@ -1,17 +1,62 @@
using namespace Microsoft.Win32;
$null = New-Module {
. "$PSScriptRoot/../Scripts/Registry.ps1";
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Common/Scripts/Scripting.ps1";
[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";
$autologinOption = "AutoAdminLogon";
$domainOption = "DefaultDomainName";
$userOption = "DefaultUserName";
$passwordOption = "DefaultPassword";
<#
.SYNOPSIS
Gets the reghistry key containing the `RunOnce` commands.
#>
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:BACKUP_ARCHIVE ? "`$env:BACKUP_ARCHIVE = $(ConvertTo-Injection (Resolve-Path $env:BACKUP_ARCHIVE));" : "") +
"`$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 +68,123 @@ $null = New-Module {
#>
function Register-Setup {
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
)
$key = Get-RunOnceKey $UserKey;
if ($DefaultUser.IsPresent) {
Edit-DefaultUserKey {
param(
[RegistryKey] $Key
)
Set-ItemProperty -Path $key.PSPath -Name $runOnceName -Type "ExpandString" -Value (
"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;"
);
Register-Setup -UserKey $Key;
}
return;
}
if ($User.IsPresent -or $UserKey) {
if (-not $UserKey) {
$UserKey = Get-Item "HKCU:\";
}
$key = Get-RunOnceKey $UserKey;
} else {
$key = Get-RunOnceKey;
}
Set-ItemProperty -Path $key.PSPath -Name $runOnceName -Type "ExpandString" -Value (Get-StartupScript);
$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
Reboots the machine intermediately and restarts the setup after the next login.
#>
function Restart-Intermediate {
Register-Setup;
Restart-Computer;
param(
[Parameter(ParameterSetName="None")]
[switch] $NoRegister,
[Parameter(ParameterSetName="Default", Mandatory)]
[switch] $DefaultUser,
[Parameter(ParameterSetName="Current", Mandatory)]
[switch] $CurrentUser
)
if (-not $NoRegister.IsPresent) {
if ($DefaultUser.IsPresent) {
Register-Setup -DefaultUser;
} elseif ($CurrentUser.IsPresent) {
Register-Setup -User;
} else {
Register-Setup;
}
}
Restart-Computer -Force;
}
}

View file

@ -1,6 +1,8 @@
using namespace Microsoft.Win32;
$null = New-Module {
$wuPolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate";
function Edit-DefaultUserKey {
param(
[scriptblock] $Action
@ -16,4 +18,62 @@ $null = New-Module {
[System.GC]::Collect();
& 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,171 @@
using namespace System.Collections.Generic;
. "$PSScriptRoot/../../Common/Scripts/System.ps1";
$null = New-Module {
$pathResolver = {
param(
[string] $User,
[string] $Path
)
[string] $result = $null;
if ($User) {
$result = "Users/$User";
} else {
$result = "System";
}
if (-not $Path) {
$Path = "Files";
}
$result = Join-Path $result $Path;
return $result;
};
<#
.SYNOPSIS
Gets the name of the variable holding the path to the backup archive of the current machine.
#>
function Get-ArchiveVariableName {
return "BACKUP_ARCHIVE";
}
<#
.SYNOPSIS
Gets the path to the backup archive of the current machine.
#>
function Get-ValhallaBackupArchive {
(Get-Item "Env:\$(Get-ArchiveVariableName)").Value;
}
<#
.SYNOPSIS
Sets the path to the backup archive of the current machine.
.PARAMETER Path
The path to set.
#>
function Set-ValhallaBackupArchive {
param(
[string] $Path
)
Set-Item "Env:\$(Get-ArchiveVariableName)" $Path;
}
<#
.SYNOPSIS
Adds files to the backup archive.
.PARAMETER User
The user to add the files to.
.PARAMETER Source
The file or directory to add to the backup archive.
.PARAMETER Path
The path to the location to store the file or directory at.
.PARAMETER ArgumentList
The arguments to pass to the `7z` command.
#>
function Add-BackupArtifacts {
param(
[string] $User,
[string] $Source,
[string] $Path,
[string[]] $Include,
[string[]] $Exclude
)
if ($env:BACKUP_ARCHIVE) {
[List[string]] $argumentList = @();
$dir = New-TemporaryDirectory;
$targetPath = & $pathResolver @PSBoundParameters;
$fullPath = Join-Path $dir $targetPath;
$null = New-Item -ItemType Directory -Force (Split-Path -Parent $fullPath);
if (Test-Path -PathType Container $Source) {
$null = New-Item -ItemType Junction $fullPath -Target $Source;
} elseif (Test-Path -PathType Leaf $Source) {
Copy-Item $Source $fullPath;
}
$options = @(
@("i", $Include),
@("x", $Exclude)
);
foreach ($option in $options) {
$indicator = $option[0];
$list = $option[1];
foreach ($pattern in $list) {
$argumentList.Add("-$indicator!`"$(Join-Path $targetPath $pattern)`"");
}
}
Start-Process `
-NoNewWindow `
-Wait `
-WorkingDirectory $dir `
-FilePath 7z `
-ArgumentList (
@(
"a",
(Get-ValhallaBackupArchive),
"-xr!desktop.ini",
"-xr!thumbs.db",
"-xr!Thumbs.db"
) + $argumentList);
Remove-Item -Recurse -Force $dir;
}
}
<#
.SYNOPSIS
Extracts the specified backup artifacts to the specified target path.
.PARAMETER User
The user to restore the files for.
.PARAMETER Path
The path to restore the files from.
.PARAMETER Target
The path to restore the files to.
.PARAMETER ArgumentList
The arguments to pass to `7z`.
#>
function Expand-BackupArtifacts {
param(
[string] $User,
[string] $Path,
[string] $Target,
[Parameter(ValueFromRemainingArguments)]
[string[]] $ArgumentList
)
if ($env:BACKUP_ARCHIVE) {
$dir = New-TemporaryDirectory;
$sourcePath = & $pathResolver @PSBoundParameters;
$filePath = Join-Path $dir $sourcePath;
7z x "-o$dir" (Get-ValhallaBackupArchive) $sourcePath @ArgumentList;
if (Test-Path $filePath) {
if (Test-Path -PathType Container $filePath) {
$null = New-Item -ItemType Directory $Target -Force;
$filePath = "$filePath/*";
}
Copy-Item -Recurse $filePath $Target -Force;
}
Remove-Item -Recurse -Force $dir;
}
}
};

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

View file

@ -0,0 +1,261 @@
using namespace System.Management.Automation.Host;
using namespace System.Security.Principal;
$null = New-Module {
. "$PSScriptRoot/../Scripts/Deployment.ps1";
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../Common/Scripts/Operations.ps1";
$loggedInUserOption = "LoggedInUser";
<#
.SYNOPSIS
Installs all pending users to the system.
#>
function Install-ValhallaUsers {
$users = @(Get-Users);
$i = Get-CurrentUser;
for (; $i -lt $users.Count; $i++) {
Set-CurrentUser $i;
if (Test-Admin) {
Disable-BootMessage;
}
while ((Get-UserStage) -ne ([UserStage]::Completed)) {
switch (Get-UserStage) {
($null) {
Set-UserStage ([UserStage]::Create);
break;
}
([UserStage]::Create) {
$msAccount = Get-UserConfig -UserName $name "microsoftAccount";
if ($env:UserName -ne $name) {
$userInfo = @{
name = $name;
msAccount = $msAccount;
};
New-ValhallaUser @userInfo;
if ($msAccount) {
logoff;
} else {
Restart-Intermediate;
}
exit;
} else {
if ($msAccount) {
if (-not (Test-Admin)) {
Invoke-OneShot DisableUAC;
Restart-Intermediate -NoRegister;
exit;
}
Clear-SetupRegistration;
Disable-OneShotListener;
}
Set-UserStage ([UserStage]::Configure);
}
}
([UserStage]::Configure) {
$displayName = Get-UserConfig -UserName $name "displayName";
$userInfo = @{
name = $name;
};
if ($displayName) {
$userInfo.fullName = $displayName;
}
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
Set-LocalUser @userInfo;
Deploy-SoftwareAction -Action ConfigureUser;
Remove-LocalGroupMember -Member "$name" @adminGroup -ErrorAction SilentlyContinue;
foreach ($group in Get-UserConfig "groups") {
Add-LocalGroupMember -Member "$name" -Name "$group";
}
Set-UserStage ([UserStage]::Cleanup);
}
([UserStage]::Cleanup) {
$user = Get-SetupUser;
Disable-LocalUser $name;
Enable-LocalUser $user;
Set-AutologinUser $user;
Unregister-WslDistribution;
Set-UserStage ([UserStage]::Completed);
Restart-Intermediate;
}
}
}
}
foreach ($user in $users) {
Enable-LocalUser $user;
}
}
<#
.SYNOPSIS
Creates a new user for the PortValhalla setup.
.PARAMETER Name
The name of the user to create.
.PARAMETER MSAccount
A value indicating whether the user should be created as a Microsoft Account.
#>
function New-ValhallaUser {
param(
[string] $Name,
[switch] $MSAccount
)
function Add-MicrosoftAccount {
param(
[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);
}
if ($MSAccount) {
if (Test-Admin) {
Write-Host "Preparing environment for creating MS Account";
Register-Setup -DefaultUser;
Enable-OneShotListener;
Enable-UAC;
# Reset Windows activation status
# Otherwise the login won't work - Windows is fricking frustrating.
slmgr /upk;
slmgr /cpky;
slmgr /rearm;
Restart-Intermediate -CurrentUser;
exit;
}
}
Write-Host "Creating personal user ``$Name``";
if ($MSAccount) {
Add-MicrosoftAccount $Name;
Set-SetupOption $loggedInUserOption $env:UserName;
Invoke-OneShot ([OneShotTask]::InitializeMSAccount);
} else {
New-LocalUser -NoPassword @userArguments;
Initialize-UserCreation;
}
}
<#
.SYNOPSIS
Prepares the first login for initializing the current user under configuration.
#>
function Initialize-UserCreation {
$name = (@(Get-Users))[(Get-CurrentUser)];
$msAccount = Get-UserConfig -UserName $name "microsoftAccount";
Write-Host "Initializing user ``$name``";
$userArguments = @{
name = $name;
};
$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,115 @@
. "$PSScriptRoot/../Scripts/Security.ps1";
<#
.SYNOPSIS
Gets the name of the WSL distribution used for managing the configuration.
#>
function Get-WslDistributionName {
return "ValhallaUbuntu";
}
<#
.SYNOPSIS
Gets the path to the directory containing the WSL distribution.
#>
function Get-WslDistributionPath {
return "$env:ProgramData/PortValhalla/$(Get-WslDistributionName)";
}
<#
.SYNOPSIS
Gets the path to the virtual hard disk of the WSL distribution.
#>
function Get-WslDistributionDisk {
return "$(Get-WslDistributionPath)/ext4.vhdx";
}
<#
.SYNOPSIS
Checks whether `wsl` is installed properly.
#>
function Test-Wsl {
& { $null = wsl --status; $?; };
}
<#
.SYNOPSIS
Checks whether any WSL distributions are installed for the current user.
#>
function Test-WslDistributions {
& { $null = wsl -l; $?; };
}
<#
.SYNOPSIS
Checks whether the managed distribution is installed.
#>
function Test-WslDistribution {
& { $null = wsl -d (Get-WslDistributionName) -e true; $?; };
}
<#
.SYNOPSIS
Installs `wsl` on the system.
#>
function Install-Wsl {
wsl --install --no-launch;
}
<#
.SYNOPSIS
Installs a Ubuntu distribution to a shared directory.
#>
function Install-WslDistribution {
$dir = Get-WslDistributionPath;
$root = Split-Path -Parent $dir;
$registryPath = "HKCU:/Software/Microsoft/Windows/CurrentVersion/Lxss";
$key = Get-Item $registryPath;
if ($key) {
$key = $key | Rename-Item -NewName "$(Split-Path -Leaf $key)_" -PassThru;
}
if (-not (Test-Path $root)) {
$null = New-Item -ItemType Directory $root;
}
Copy-Item -Recurse (Get-AppxPackage "*Ubuntu*").InstallLocation $dir;
Set-UserPermissions $dir;
& "$dir\ubuntu.exe" install --root;
wsl --shutdown;
Remove-Item -Recurse -Force $registryPath;
if ($key) {
Move-Item $key.PSPath $registryPath;
}
}
<#
.SYNOPSIS
Uninstalls the managed WSL distribution.
#>
function Uninstall-WslDistribution {
wsl --unregister (Get-WslDistributionName);
}
<#
.SYNOPSIS
Registers the managed WSL distribution.
#>
function Register-WslDistribution {
wsl --import-in-place (Get-WslDistributionName) (Get-WslDistributionDisk);
wsl --set-default (Get-WslDistributionName);
}
<#
.SYNOPSIS
Unregisters the managed WSL distribution.
#>
function Unregister-WslDistribution {
$wslDisk = Get-WslDistributionDisk;
wsl --shutdown;
$tempDisk = Rename-Item $wslDisk "ext4_.vhdx" -PassThru;
Uninstall-WslDistribution;
Move-Item $tempDisk $wslDisk;
}

View file

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

View file

@ -13,7 +13,6 @@ Start-SoftwareInstaller @PSBoundParameters `
)
Install-ChocoPackage firefox;
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
Write-Host "Making Firefox the default browser…";
@ -34,10 +33,12 @@ Start-SoftwareInstaller @PSBoundParameters `
);
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) {
Set-DefaultAppAssociation -Identifier $scheme -ProgId "${appName}URL$progIdSuffix" -ApplicationName $appName;
}
Remove-TaskbarItem "*Firefox*";
};

View file

@ -0,0 +1,83 @@
param(
$Action,
[hashtable] $Arguments
)
. "$PSScriptRoot/../../Scripts/Restoration.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
$null = New-Module {
param ($Parameters)
$configPath = "$env:LocalAppData/LGHUB";
Export-ModuleMember -Function @();
<#
.SYNOPSIS
Stops the running Logitech G Hub instance.
#>
function Stop-LGHub {
[OutputType([string])]
param()
$hubName = "lghub_system_tray.exe";
$lghubPath = $(Get-Process | Where-Object { $_.Path -and ((Split-Path -Leaf $_.Path) -eq $hubName) })[0].Path;
$mainProcesses = Get-Process | Where-Object {
$_.Path -and
(@("lghub.exe", "lghub_agent.exe", $hubName) -contains (Split-Path -Leaf $_.Path)) -and
(($_.Parent.ProcessName -eq "explorer") -or ($null -eq $_.Parent))
};
$null = $mainProcesses | ForEach-Object { $_.Kill($true) };
return $lghubPath;
}
<#
.SYNOPSIS
Edits the Logitech G Hub configuration.
#>
function Edit-LGHubConfig {
param(
[scriptblock] $Action
)
Write-Host "Stopping Logitech G Hub";
$path = Stop-LGHub;
& $Action;
if ($path) {
Write-Host "Restarting Logitech G Hub";
Start-Process $path;
}
}
Start-SoftwareInstaller @Parameters `
-Installer {
Install-ChocoPackage lghub;
Remove-DesktopIcon "*G HUB*";
} `
-UserBackup {
param(
[hashtable] $Arguments
)
Edit-LGHubConfig {
Add-BackupArtifacts -User $Arguments.Name -Source $configPath -Path "LGHub" `
-Include @("settings.db", "icon_cache")
};
} `
-UserConfigurator {
param(
[hashtable] $Arguments
)
Edit-LGHubConfig {
Expand-BackupArtifacts -User $Arguments.Name -Path "LGHub" -Target $configPath;
};
};
} $PSBoundParameters;
Start-SoftwareInstaller @PSBoundParameters `
# 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,20 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
$path = "$HOME/Documents/ManiaPlanet";
$softwareName = "ManiaPlanet";
function Backup-ManiaPlanet([Context] $context) {
Write-Information "Backing up ManiaPlanet";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
function Restore-ManiaPlanet([Context] $context) {
Write-Host "Restoring ManiaPlanet";
Write-Information "Installing ManiaPlanet";
winget install --accept-source-agreements --accept-package-agreements -e --id Nadeo.ManiaPlanet;
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
}
}

View file

@ -1,20 +1,15 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param(
$Action,
[hashtable] $Arguments
)
$null = New-Module {
$path = "$HOME/Documents/ManiaPlanet";
$softwareName = "ManiaPlanet";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
function Backup-ManiaPlanet([Context] $context) {
Write-Information "Backing up ManiaPlanet";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-WingetPackage Nadeo.ManiaPlanet;
Remove-DesktopIcon "ManiaPlanet*";
};
function Restore-ManiaPlanet([Context] $context) {
Write-Host "Restoring ManiaPlanet";
Write-Information "Installing ManiaPlanet";
winget install --accept-source-agreements --accept-package-agreements -e --id Nadeo.ManiaPlanet;
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
}
}
# 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/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
& {
param($Parameters)
$base = "$PSScriptRoot/../../../Common/Software/Oh My Posh/Manage.ps1";
Install-WingetPackage JanDeDobbeleer.OhMyPosh;
& $Installer -Action ([InstallerAction]::Configure);
} `
-Configurator {
. "$PSScriptRoot/../../../Common/Software/Oh My Posh/Manage.ps1" `
-Action ([InstallerAction]::Configure);
};
Start-SoftwareInstaller @Parameters `
-Installer {
Install-WingetPackage JanDeDobbeleer.OhMyPosh -ArgumentList "--scope","machine";
} `
-Configurator {
. $base -Action ([InstallerAction]::Configure);
} `
-UserConfigurator {
. $base -Action ([InstallerAction]::ConfigureUser);
};
} $PSBoundParameters;

View file

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

View file

@ -0,0 +1,35 @@
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
)
$module = $Arguments.Name;
& $Arguments.Installer @PSBoundParameters;
if (-not (& { powershell -Command "Import-Module $module; exit ([bool]`$Error)" 2> $null; $?; })) {
$feature = "NetFx3";
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
Write-Host "Enabling ``$feature`` feature…";
choco install --source windowsFeatures -y $feature;
}
}
}

View file

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

View file

@ -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,35 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/KnownFolders.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
Import-Module "$env:ChocolateyInstall/helpers/chocolateyInstaller.psm1";
$path = "C:/tools/RetroArch-Win64";
$softwareName = "RetroArch";
function Backup-RetroArch([Context] $context) {
Write-Host "Backing up RetroArch";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
function Restore-RetroArch([Context] $context) {
Write-Host "Restoring RetroArch";
Write-Information "Installing RetroArch";
choco install -y --ignore-checksums retroarch;
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
Write-Information "Adding cloud sync folders";
$context.AddNextcloudSync(
"$path\saves",
"/Saved Games/RetroArch/Saves");
$context.AddNextcloudSync(
"$path\system",
"/Saved Games/RetroArch/System");
Write-Information "Creating a Start Menu Icon";
Install-ChocolateyShortcut -ShortcutFilePath "$((Get-KnownFolder "Common Programs").Path)/RetroArch.lnk" -TargetPath ((Get-Item "$path\retroarch.exe").FullName);
}
}

View file

@ -1,35 +1,17 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/KnownFolders.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param(
$Action,
[hashtable] $Arguments
)
$null = New-Module {
Import-Module "$env:ChocolateyInstall/helpers/chocolateyInstaller.psm1";
$path = "C:/tools/RetroArch-Win64";
$softwareName = "RetroArch";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
function Backup-RetroArch([Context] $context) {
Write-Host "Backing up RetroArch";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage retroarch;
} `
-Configurator {
Add-StartMenuIcon "RetroArch" "C:\tools\RetroArch-Win64\retroarch.exe";
};
function Restore-RetroArch([Context] $context) {
Write-Host "Restoring RetroArch";
Write-Information "Installing RetroArch";
choco install -y --ignore-checksums retroarch;
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
Write-Information "Adding cloud sync folders";
$context.AddNextcloudSync(
"$path\saves",
"/Saved Games/RetroArch/Saves");
$context.AddNextcloudSync(
"$path\system",
"/Saved Games/RetroArch/System");
Write-Information "Creating a Start Menu Icon";
Install-ChocolateyShortcut -ShortcutFilePath "$((Get-KnownFolder "Common Programs").Path)/RetroArch.lnk" -TargetPath ((Get-Item "$path\retroarch.exe").FullName);
}
}
# ToDo: Add restoration

View file

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

View file

@ -0,0 +1,31 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
$path = "$HOME/Documents/TmForever";
$softwareName = "TmNationsForever";
function Backup-TmNations([Context] $context) {
Write-Host "Backing up TrackMania Nations Forever";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
function Restore-TmNations([Context] $context) {
$features = @("DirectPlay", "NetFx3");
Write-Host "Restoring TrackMania Nations Forever";
foreach ($feature in $features) {
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
Write-Information "Enabling the ``$feature`` feature";
$null = Enable-WindowsOptionalFeature -Online -All -FeatureName $feature;
}
}
Write-Information "Installing TrackMania Nations Forever";
winget install --accept-source-agreements --accept-package-agreements -e --id Nadeo.TrackManiaNationsForever;
Write-Information "Removing Desktop Icon";
$context.RemoveDesktopIcon("*TmNationsForever*");
Write-Information "Restoring Files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
}
}

View file

@ -1,31 +1,21 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param(
$Action,
[hashtable] $Arguments
)
$null = New-Module {
$path = "$HOME/Documents/TmForever";
$softwareName = "TmNationsForever";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
function Backup-TmNations([Context] $context) {
Write-Host "Backing up TrackMania Nations Forever";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
function Restore-TmNations([Context] $context) {
$features = @("DirectPlay", "NetFx3");
Write-Host "Restoring TrackMania Nations Forever";
foreach ($feature in $features) {
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
foreach ($feature in @("DirectPlay", "NetFx3")) {
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
Write-Information "Enabling the ``$feature`` feature";
$null = Enable-WindowsOptionalFeature -Online -All -FeatureName $feature;
Write-Information "Enabling the ``$feature`` feature…";
choco install --source windowsFeatures -y $feature;
}
}
Write-Information "Installing TrackMania Nations Forever";
winget install --accept-source-agreements --accept-package-agreements -e --id Nadeo.TrackManiaNationsForever;
Write-Information "Removing Desktop Icon";
$context.RemoveDesktopIcon("*TmNationsForever*");
Write-Information "Restoring Files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
}
}
Install-WingetPackage Nadeo.TrackManiaNationsForever;
Remove-DesktopIcon "*TmNationsForever*";
};
# ToDo: Add restoration

View file

@ -0,0 +1,40 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
$path = "$HOME/Documents/TrackMania";
$softwareName = "TmUnitedForever";
function Backup-TmUnited([Context] $context) {
Write-Host "Backing up TrackMania United Forever";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
function Restore-TmUnited([Context] $context) {
$setupFile = "TmUnitedForever.exe";
$features = @("DirectPlay", "NetFx3");
Write-Host "Restoring TrackMania United Forever";
foreach ($feature in $features) {
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
Write-Information "Enabling the ``$feature`` feature";
$null = Enable-WindowsOptionalFeature -Online -All -FeatureName $feature;
}
}
$tempDir = $context.GetTempDirectory();
Push-Location $tempDir;
Write-Information "Downloading TrackMania United Forever setup";
Invoke-WebRequest "http://files.trackmaniaforever.com/tmunitedforever_setup.exe" -OutFile "$setupFile";
Write-Information "Installing TrackMania United Forever";
Start-Process -Wait -FilePath $setupFile -ArgumentList @("/Silent");
Write-Information "Removing desktop icon";
$context.RemoveDesktopIcon("*TmUnitedForever*");
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
Pop-Location;
Remove-Item -Recurse $tempDir;
}
}

View file

@ -1,40 +1,33 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param(
$Action,
[hashtable] $Arguments
)
$null = New-Module {
$path = "$HOME/Documents/TrackMania";
$softwareName = "TmUnitedForever";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
function Backup-TmUnited([Context] $context) {
Write-Host "Backing up TrackMania United Forever";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`""));
}
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
$file = "TmUnitedForever.exe";
$dir = New-TemporaryDirectory;
function Restore-TmUnited([Context] $context) {
$setupFile = "TmUnitedForever.exe";
$features = @("DirectPlay", "NetFx3");
Write-Host "Restoring TrackMania United Forever";
foreach ($feature in $features) {
foreach ($feature in @("DirectPlay", "NetFx3")) {
if ((Get-WindowsOptionalFeature -Online -FeatureName $feature).State -ne "Enabled") {
Write-Information "Enabling the ``$feature`` feature";
$null = Enable-WindowsOptionalFeature -Online -All -FeatureName $feature;
Write-Information "Enabling the ``$feature`` feature…";
choco install --source windowsFeatures -y $feature;
}
}
$tempDir = $context.GetTempDirectory();
Push-Location $tempDir;
Write-Information "Downloading TrackMania United Forever setup";
Invoke-WebRequest "http://files.trackmaniaforever.com/tmunitedforever_setup.exe" -OutFile "$setupFile";
$null = Push-Location $dir;
Write-Host "Downloading TrackMania United Forever…";
Invoke-WebRequest "http://files.trackmaniaforever.com/tmunitedforever_setup.exe" -OutFile "$file";
Write-Information "Installing TrackMania United Forever";
Start-Process -Wait -FilePath $setupFile -ArgumentList @("/Silent");
Write-Information "Removing desktop icon";
$context.RemoveDesktopIcon("*TmUnitedForever*");
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
Pop-Location;
Write-Host "Starting installation…";
Start-Process -Wait -FilePath $file -ArgumentList "/Silent";
Remove-DesktopIcon "*TmUnitedForever*";
$null = Pop-Location;
Remove-Item -Recurse $tempDir;
}
}
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,57 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/KnownFolders.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
$programs32Path = $(Get-KnownFolder "ProgramFilesX86").Path;
$vsInstaller = "$programs32Path/Microsoft Visual Studio/Installer/vs_installer.exe";
[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"));
function Get-ConfigPath([Context] $context, [string] $packageName) {
return Join-Path $($context.BackupRoot()) "Visual Studio" $packageName ".vsconfig";
}
function Backup-VisualStudio([Context] $context) {
Write-Host "Backing up Visual Studio";
foreach ($version in $versions) {
if ((choco list -e $version[0])) {
Write-Information "Backing up $($version[1]): $($version[2])";
$configPath = Get-ConfigPath $context $version[0];
$null = New-Item -Force -ItemType Directory "$(Split-Path -Parent $configPath)";
Start-Process -FilePath "$vsInstaller" `
-Wait `
-ArgumentList @(
"export",
"--channelId", "$($version[1])",
"--productId", "$($version[2])",
"--config", "`"$configPath`"",
"--quiet");
}
}
}
function Restore-VisualStudio([Context] $context) {
Write-Host "Restoring Visual Studio";
foreach ($version in $versions) {
$configFileName = Get-ConfigPath $context $version[0];
if (Test-Path $configFileName) {
Write-Information "Restoring $($version[1]): $($version[2])";
$arguments = "--config `"$configFileName`"";
choco install -y $version[0] --params "$arguments";
$context.RemoveDesktopIcon("CocosCreator*");
$context.RemoveDesktopIcon("Unity Hub*");
}
}
}
}

View file

@ -1,57 +1,34 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/KnownFolders.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param(
$Action,
[hashtable] $Arguments
)
$null = New-Module {
$programs32Path = $(Get-KnownFolder "ProgramFilesX86").Path;
$vsInstaller = "$programs32Path/Microsoft Visual Studio/Installer/vs_installer.exe";
& {
param($parameters)
[System.Tuple[string, string, string][]]$versions = @(
. "$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"));
function Get-ConfigPath([Context] $context, [string] $packageName) {
return Join-Path $($context.BackupRoot()) "Visual Studio" $packageName ".vsconfig";
}
function Backup-VisualStudio([Context] $context) {
Write-Host "Backing up Visual Studio";
foreach ($version in $versions) {
if ((choco list -e $version[0])) {
Write-Information "Backing up $($version[1]): $($version[2])";
[System.Tuple]::Create("visualstudio2022community", "VisualStudio.17.Release", "Microsoft.VisualStudio.Product.Community")
);
$configPath = Get-ConfigPath $context $version[0];
$null = New-Item -Force -ItemType Directory "$(Split-Path -Parent $configPath)";
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*";
};
Start-Process -FilePath "$vsInstaller" `
-Wait `
-ArgumentList @(
"export",
"--channelId", "$($version[1])",
"--productId", "$($version[2])",
"--config", "`"$configPath`"",
"--quiet");
}
}
}
function Restore-VisualStudio([Context] $context) {
Write-Host "Restoring Visual Studio";
foreach ($version in $versions) {
$configFileName = Get-ConfigPath $context $version[0];
if (Test-Path $configFileName) {
Write-Information "Restoring $($version[1]): $($version[2])";
$arguments = "--config `"$configFileName`"";
choco install -y $version[0] --params "$arguments";
$context.RemoveDesktopIcon("CocosCreator*");
$context.RemoveDesktopIcon("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/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../Scripts/System.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
Install-ChocoPackage winscp;
& $Installer -Action ([InstallerAction]::Configure)
} `
-Configurator {
Remove-DesktopIcon "WinSCP*";

View file

@ -0,0 +1,37 @@
Pictures/Feedback
Documents/BeamNG.drive
Documents/Default.rdp
Documents/den4b/ReNamer
Documents/Dolphin Emulator
Documents/eFisc
Documents/IISExpress
Documents/KINGDOM HEARTS HD 1.5+2.5 ReMIX
Documents/ManiaPlanet
Documents/MetaX
Documents/MuseScore3
Documents/My Web Sites
Documents/OneNote-Notizbücher
Documents/PCSX2
Documents/PowerShell
Documents/PPSSPP
Documents/PS Vita
Documents/PSV Packages
Documents/PSV Updates
Documents/Repositories
Documents/Rise of the Tomb Raider
Documents/S2
Documents/SEGA
Documents/SEGA Mega Drive Classics
Documents/SQL Server Management Studio
Documents/Square Enix
Documents/TI-Nspire CX
Documents/TmForever
Documents/TrackMania
Documents/UltraVNC
Documents/Visual Studio 2017
Documents/Visual Studio 2019
Documents/Visual Studio 2022
Documents/Viwizard M4V Converter
Documents/WindowsPowerShell
Documents/Zoom
Music/iTunes

View file

@ -5,19 +5,40 @@ param(
[hashtable] $Arguments
)
. "$PSScriptRoot/../../Scripts/Registry.ps1";
. "$PSScriptRoot/../../Scripts/Config.ps1";
. "$PSScriptRoot/../../Scripts/System.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
param(
[scriptblock] $Installer
)
$null = New-Module {
param($Parameters)
& $Installer -Action ([InstallerAction]::Configure)
. "$PSScriptRoot/../../Scripts/Registry.ps1";
. "$PSScriptRoot/../../Scripts/Restoration.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Config.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
$userFolders = @(
"Pictures",
"Documents",
"Downloads",
"Music",
"Videos"
);
$userExclusions = @(
"Documents/Eigene*",
"Documents/My Games",
"Documents/My Music",
"Documents/My Pictures",
"Documents/My Videos"
);
[string[]] $homeExclusions = Get-Content "$PSScriptRoot/Home.exclude.txt";
Start-SoftwareInstaller @Parameters `
-Backup {
Add-BackupArtifacts -Source "$env:PUBLIC" -Path "Public" `
-Include ($userFolders) `
-Exclude ($userExclusions + @("Documents/Hyper-V", "Documents/reWASD"));
} `
-Configurator {
$dir = New-TemporaryDirectory;
@ -61,7 +82,7 @@ Start-SoftwareInstaller @PSBoundParameters `
)
$path = "$($Key.PSPath)\Software\Microsoft\Lighting";
$null = New-Item $path;
$null = New-Item $path -ErrorAction SilentlyContinue;
Set-ItemProperty $path -Name "AmbientLightingEnabled" -Value 0 -Type "DWord";
};
}
@ -143,4 +164,20 @@ Start-SoftwareInstaller @PSBoundParameters `
Pop-Location;
Remove-Item -Recurse $dir;
Expand-BackupArtifacts -Path "Public" -Target $env:PUBLIC;
} `
-UserBackup {
param(
[hashtable] $Arguments
)
Add-BackupArtifacts -User $Arguments.Name -Source $HOME -Path "Home" -Include ($userFolders) -Exclude ($userExclusions + $homeExclusions);
} `
-UserConfigurator {
param(
[hashtable] $Arguments
)
Expand-BackupArtifacts -User $Arguments.Name -Path "Home" -Target $HOME;
};
} $PSBoundParameters;

View file

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

View file

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

View file

@ -0,0 +1,15 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/BashScript.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
function Backup-Git([Context] $context) {}
function Restore-Git([Context] $context) {
Write-Host "Restoring git";
Start-BashScript @(
"bash `"$PSScriptRoot/../../../Common/Config/git/install.sh`"",
"rm ~/.bashrc");
}
}

View file

@ -1,15 +1,39 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/BashScript.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param (
$Action,
[hashtable] $Arguments
)
$null = New-Module {
function Backup-Git([Context] $context) {}
. "$PSScriptRoot/../../../Common/Types/InstallerAction.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Config.ps1";
function Restore-Git([Context] $context) {
Write-Host "Restoring git";
& {
param(
[hashtable] $Parameters
)
Start-BashScript @(
"bash `"$PSScriptRoot/../../../Common/Config/git/install.sh`"",
"rm ~/.bashrc");
}
}
. "$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,36 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/KnownFolders.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
$path = "$((Get-KnownFolder -SpecialFolder ProgramFilesX86).Path)/osu!";
$softwareName = "osu!";
$genericConfigName = "osu!.User.cfg";
function Backup-Osu([Context] $context) {
Write-Host "Backing up osu!";
$archive = $context.SoftwareArchive($softwareName);
Write-Information "Backing up important files";
$context.Backup($path, $archive, @("-i@`"$PSScriptRoot/include.txt`""));
Write-Information "Renaming user configuration to $genericConfigName";
& 7z rn "$archive" "osu!.$env:USERNAME.cfg" $genericConfigName;
}
function Restore-Osu([Context] $context) {
Write-Host "Restoring osu!";
Write-Information "Installing osu!";
choco install -y osu;
$context.RemoveDesktopIcon("*osu*");
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path, @("-aos"));
$configName = "osu!.$env:USERNAME.cfg";
Write-Information "Renaming user configuration to $configName";
Push-Location $path;
if ((Test-Path $genericConfigName)) {
Rename-Item $genericConfigName $configName;
}
Pop-Location;
}
}

View file

@ -1,36 +1,14 @@
#!/bin/pwsh
. "$PSScriptRoot/../../Scripts/KnownFolders.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param(
$Action,
[hashtable] $Arguments
)
$null = New-Module {
$path = "$((Get-KnownFolder -SpecialFolder ProgramFilesX86).Path)/osu!";
$softwareName = "osu!";
$genericConfigName = "osu!.User.cfg";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
function Backup-Osu([Context] $context) {
Write-Host "Backing up osu!";
$archive = $context.SoftwareArchive($softwareName);
Write-Information "Backing up important files";
$context.Backup($path, $archive, @("-i@`"$PSScriptRoot/include.txt`""));
Write-Information "Renaming user configuration to $genericConfigName";
& 7z rn "$archive" "osu!.$env:USERNAME.cfg" $genericConfigName;
}
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-ChocoPackage osu;
Remove-DesktopIcon "*osu*";
};
function Restore-Osu([Context] $context) {
Write-Host "Restoring osu!";
Write-Information "Installing osu!";
choco install -y osu;
$context.RemoveDesktopIcon("*osu*");
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path, @("-aos"));
$configName = "osu!.$env:USERNAME.cfg";
Write-Information "Renaming user configuration to $configName";
Push-Location $path;
if ((Test-Path $genericConfigName)) {
Rename-Item $genericConfigName $configName;
}
Pop-Location;
}
}
# ToDo: Add restoration

View file

@ -0,0 +1,37 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$null = New-Module {
$path = "$env:APPDATA/osu";
$softwareName = "osu!lazer";
function Backup-OsuLazer([Context] $context) {
Write-Host "Backing up osu!lazer";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`"", "-i!*.realm", "-i!*.db"));
}
function Restore-OsuLazer([Context] $context) {
Write-Host "Restoring osu!lazer";
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
Write-Information "Installing osu!lazer";
$installerName = "osu!lazer.exe";
$processName = "osu!";
$tempDir = $context.GetTempDirectory();
Push-Location $tempDir;
Invoke-WebRequest "https://github.com/ppy/osu/releases/latest/download/install.exe" -OutFile $installerName;
Start-Process -FilePath $installerName;
while (-not (Get-Process -ErrorAction "SilentlyContinue" $processName)) {
Start-Sleep 1;
}
Start-Sleep 10;
Get-Process $processName | Stop-Process -Force;
$context.RemoveDesktopIcon("*osu*");
Pop-Location;
Remove-Item -Recurse $tempDir;
}
}

View file

@ -1,37 +1,15 @@
#!/bin/pwsh
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
param(
$Action,
[hashtable] $Arguments
)
$null = New-Module {
$path = "$env:APPDATA/osu";
$softwareName = "osu!lazer";
. "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
. "$PSScriptRoot/../../../Common/Scripts/System.ps1";
function Backup-OsuLazer([Context] $context) {
Write-Host "Backing up osu!lazer";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-i@`"$PSScriptRoot/include.txt`"", "-i!*.realm", "-i!*.db"));
}
Start-SoftwareInstaller @PSBoundParameters `
-Installer {
Install-WingetPackage "ppy.osu";
Remove-DesktopIcon "*osu*";
};
function Restore-OsuLazer([Context] $context) {
Write-Host "Restoring osu!lazer";
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path);
Write-Information "Installing osu!lazer";
$installerName = "osu!lazer.exe";
$processName = "osu!";
$tempDir = $context.GetTempDirectory();
Push-Location $tempDir;
Invoke-WebRequest "https://github.com/ppy/osu/releases/latest/download/install.exe" -OutFile $installerName;
Start-Process -FilePath $installerName;
while (-not (Get-Process -ErrorAction "SilentlyContinue" $processName)) {
Start-Sleep 1;
}
Start-Sleep 10;
Get-Process $processName | Stop-Process -Force;
$context.RemoveDesktopIcon("*osu*");
Pop-Location;
Remove-Item -Recurse $tempDir;
}
}
# ToDo: Add restoration

View file

@ -0,0 +1,31 @@
#!/bin/pwsh
$null = New-Module {
. "$PSScriptRoot/../../../Common/Scripts/BrowserAutomation.ps1";
. "$PSScriptRoot/../../../Common/Scripts/Context.ps1";
$path = "$env:PUBLIC/Documents/reWASD";
$softwareName = "reWASD";
function Backup-reWASD([Context] $context) {
Write-Host "Backing up reWASD";
$context.Backup($path, $context.SoftwareArchive($softwareName), @("-x@`"$PSScriptRoot/exclude.txt`""));
}
function Restore-reWASD([Context] $context) {
Write-Host "Restoring reWASD";
$tempDir = $context.GetTempDirectory();
Write-Information "Downloading reWASD";
$file = Start-BrowserDownload $context "https://rewasd.com/" 'a.btn-default[href="#"]' $tempDir;
Write-Information "Installing reWASD";
Start-Process -Wait -FilePath $file.FullName -ArgumentList "/S";
Write-Information "Restoring files";
$context.Restore($context.SoftwareArchive($softwareName), $path, @("-aos"));
Write-Information "Removing desktop icon";
$context.RemoveDesktopIcon("*reWASD*");
Remove-Item -Recurse $tempDir;
}
}

Some files were not shown because too many files have changed in this diff Show more