Genesis.psm1
#Requires -RunAsAdministrator #Requires -Version 5.0 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 #> param( # YAML Configuration file to use for setup. [Parameter(Mandatory)] [ValidateScript( { if (Test-Path -PathType Leaf $_) { return $true } throw "File not found: $_" })] [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 ) # We want to handle errors explicitly. $ErrorActionPreference = "Stop" $Config = ConvertFrom-Yaml -Path $ConfigFile 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 "Setting up $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" { $profile = Get-NetConnectionProfile if ($profile.Count -eq 0) { Write-Warning "no active connections found...skipping" return $false } if ($profile.Count -eq 1) { Write-Warning "multiple connections found...ambigious...skipping" return $false } if ($profile -and $category -and ($profile.NetworkCategory -ne $category)) { Write-Output "changing from $($profile.NetworkCategory) to $category" Set-NetConnectionProfile -InterfaceIndex $profile.InterfaceIndex -NetworkCategory $category return $true } Write-Output "already $($profile.NetworkCategory)..." return $false } } Assert-Configuration "Explorer" { # file extensions [void] (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" { [void] (Assert-RegistryValue -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` -Name "People" -Type Dword -Value $Config.TaskBar.ShowPeopleButton) [void] (Assert-RegistryValue -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" ` -Name "ShowTaskViewButton" -Type Dword -Value $Config.TaskBar.ShowTaskViewButton) [void] (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')) return $true } return $false } Assert-Configuration "Default browser" { $defaultBrowser = (Get-Browser $Config.DefaultBrowser) $builtIn = !($defaultBrowser.LocalPath); if (!$builtIn -and !(Test-Path $defaultBrowser.LocalPath)) { Write-Output "installing..." & choco install $defaultBrowser.ChocolateyPackage -y } else { Write-Output "$($Config.DefaultBrowser) is already installed, checking if it's the default..." if (!(Test-DefaultBrowser $defaultBrowser.Tag)) { Write-Output "nope :(" Write-Output "Please ensure $($defaultBrowser.Name) is the default browser - opening settings app" Start-Process "ms-settings:defaultapps" Wait-ForEnter } } } 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 return $true } } } Assert-Configuration "Developer mode" { return (Assert-RegistryValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" ` -Name AllowDevelopmentWithoutDevLicense -Type Dword -Value $Config.DeveloperMode) } Assert-Configuration "Windows capabilities" { $result = $false $Config.WindowsCapabilities.Keys | ForEach-Object { $id = $Config.WindowsCapabilities[$_] $result = $result -or (Assert-WindowsCapability -Name $_ -Id $id) } return $result } 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 } return !!$exclusions } Assert-Configuration "Development related Microsoft Store apps" { [void] (Assert-StoreAppsInstalled $Config.DevStoreApps) } if ($Config.ChocolateyPackages) { Assert-Configuration "Chocolatey packages" { return 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" } } |