publish/Genesis.psm1
#Requires -RunAsAdministrator #Requires -Version 5.0 #Requires -Modules FXPSYaml # We want to handle errors explicitly. $ErrorActionPreference = "Stop" function Update-SystemConfiguration { <# .SYNOPSIS Updates the system configuration and installs the required applications by processing a Genesis configuration file. .DESCRIPTION This script is currently very opinionated on where to put things and it can make you lose data. DO NOT RUN ON YOUR MACHINE unless you know what you're doing. To customize the behavior you can edit SampleConfig.yaml .NOTES Author: Sedat Kapanoglu #> [CmdletBinding()] param( # YAML Configuration file to use for setup. [Parameter(Mandatory)] [ValidateScript({ Test-Path -PathType Leaf $_ })] [System.IO.FileInfo]$ConfigFile, # Set computer name, otherwise you get prompted # for a new name if it's a random Windows 10 PC name # such as DESKTOP-ABC123. [string]$ComputerName ) Write-Debug "Reading configuration file $ConfigFile" $Config = ConvertFrom-Yaml -Path $ConfigFile if ($null -eq $Config) { throw "Configuration file $ConfigFile cannot be loaded" } Write-Debug "Starting asserts" Assert-Configuration "Computer name" { $computerName = $env:ComputerName if ($computerName -like 'DESKTOP-*') { Write-Output "not set" $computerName = Read-Host "Enter a computer name" Rename-Computer -NewName $computerName Write-Output "Issued rename request. Will probably take effect after restart" Set-RestartNeeded } } Write-Output "Working on $env:ComputerName" Assert-Configuration "Keyboard" { [void] (Assert-RegistryValue -Path "HKCU:\Control Panel\Keyboard" -Name "KeyboardDelay" -Type Dword ` -Value $Config.Keyboard.Delay) [void] (Assert-RegistryValue -Path "HKCU:\Control Panel\Input Method" -Name "EnableHexNumPad" -Type String ` -Value $Config.Keyboard.HexNumPad.ToString()) # crash on Ctrl+ScrollLock handling $prefix = "HKLM:\System\CurrentControlSet\Services" [void] (Assert-RegistryValue -Path "$prefix\kbdhid\Parameters" -Name "CrashOnCtrlScroll" -Type Dword ` -Value $Config.Keyboard.CrashOnCtrlScroll) [void] (Assert-RegistryValue -Path "$prefix\i8042prt\Parameters" -Name "CrashOnCtrlScroll" -Type Dword ` -Value $Config.Keyboard.CrashOnCtrlScroll) [void] (Assert-RegistryValue -Path "$prefix\hyperkbd\Parameters" -Name "CrashOnCtrlScroll" -Type Dword ` -Value $Config.Keyboard.CrashOnCtrlScroll) } $category = $Config.Network.ActiveConnectionNetworkCategory if ($category) { Assert-Configuration "Network" { $profileName = Get-NetConnectionProfile if ($profileName.Count -eq 0) { Write-Warning "no active connections found...skipping" return } if ($profileName.Count -eq 1) { Write-Warning "multiple connections found...ambigious...skipping" return } if ($profileName -and $category -and ($profileName.NetworkCategory -ne $category)) { Write-Output "changing from $($profileName.NetworkCategory) to $category" Set-NetConnectionProfile -InterfaceIndex $profileName.InterfaceIndex -NetworkCategory $category return } Write-Output "already $($profileName.NetworkCategory)..." } } Assert-Configuration "Explorer" { # file extensions Assert-RegistryValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` -Name "HideFileExt" -Type Dword -Value $Config.Explorer.ShowFileExtensions # recycle bin capacity Get-ChildItem "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Bitbucket\Volume" ` | ForEach-Object { Set-RecycleBinCapacity -Volume (Split-Path $_.Name -Leaf) -Capacity $Config.Explorer.MaxRecycleBinCapacity } } Assert-Configuration "Taskbar" { Assert-RegistryValue -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` -Name "People" -Type Dword -Value $Config.TaskBar.ShowPeopleButton Assert-RegistryValue -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` -Name "ShowTaskViewButton" -Type Dword -Value $Config.TaskBar.ShowTaskViewButton Assert-RegistryValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search" ` -Name "SearchboxTaskbarMode" -Type Dword -Value $Config.TaskBar.SearchboxTaskbarMode } if ($Config.SpecialFolders) { Assert-Configuration "Special Folders" { Write-Output "" $Config.SpecialFolders.Keys | ForEach-Object { Assert-SpecialFolder -Name $_ -PreferredLocation $Config.SpecialFolders[$_] } } } Assert-Configuration "Chocolatey" { if (!(Test-Path -Path "$env:ProgramData\Chocolatey")) { # install chocolatey Set-ExecutionPolicy Bypass -Scope Process -Force Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) } } Assert-Configuration "Default browser" { $browser = $Config.DefaultBrowser Write-Debug "Checking if default browser is $browser" $defaultBrowser = (Get-Browser $Config.DefaultBrowser) $builtIn = !($defaultBrowser.LocalPath); if (!$builtIn -and !(Test-Path $defaultBrowser.LocalPath)) { Write-Output "installing external $browser..." & choco install $defaultBrowser.ChocolateyPackage -y } else { Write-Output "$browser is already installed" if (-not (Test-DefaultBrowser $defaultBrowser.Tag)) { Write-Output "Please ensure $browser is the default browser - opening settings app" Start-Process "ms-settings:defaultapps" } } } if ($Config.WindowsFeatures) { Assert-Configuration "Windows features" { $Config.WindowsFeatures | ForEach-Object { Assert-WindowsFeature $_ } } } Assert-Configuration "Common Microsoft Store apps" { [void] (Assert-StoreAppsInstalled $Config.CommonStoreApps) } Assert-Configuration "Desktop shortcuts" { $Config.DesktopUrlShortcuts.Keys | ForEach-Object { [void] (Assert-DesktopShortcut $_ $Config.DesktopUrlShortcuts[$_]) } } ### Development Environment Setup ### if ($Config.Linux -eq 1) { Assert-Configuration "Windows Subsystem for Linux" { $feature = Get-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online if ($feature -and ($feature.State -eq "Disabled")) { Write-Progress "enabling..." Enable-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online -All ` -LimitAccess -NoRestart } } } Assert-Configuration "Developer mode" { Assert-RegistryValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" ` -Name AllowDevelopmentWithoutDevLicense -Type Dword -Value $Config.DeveloperMode } Assert-Configuration "Windows capabilities" { $Config.WindowsCapabilities.Keys | ForEach-Object { $id = $Config.WindowsCapabilities[$_] Assert-WindowsCapability -Name $_ -Id $id } } if ($Config.IgnoreKeepAwakeRequestsFromProcesses) { Assert-Configuration "Ignore keep awake requests" { $Config.IgnoreKeepAwakeRequestsFromProcesses.Keys | ForEach-Object { $mode = $Config.IgnoreKeepAwakeRequestsFromProcesses[$_] Assert-NoKeepAwake -Process $_ -Mode $mode } } } Assert-Configuration "Windows Defender exclusions" { $exclusions = $WindowsDefender.ExclusionPaths foreach ($path in $exclusions) { Add-MpPreference -ExclusionPath $path } } Assert-Configuration "Development related Microsoft Store apps" { Assert-StoreAppsInstalled $Config.DevStoreApps } if ($Config.ChocolateyPackages) { Assert-Configuration "Chocolatey packages" { Assert-ChocolateyPackages $Config.ChocolateyPackages } } ### End of Configuration ### Write-Output "Well, that's been a pleasure!" if (Get-RestartNeeded) { Write-Output "Please restart the computer to ensure changes take effect" } } |