aboutsummaryrefslogtreecommitdiff
path: root/documents
diff options
context:
space:
mode:
authorsrdusr <trevorgray@srdusr.com>2024-06-02 00:38:50 +0200
committersrdusr <trevorgray@srdusr.com>2024-06-02 00:38:50 +0200
commit9495b7740ef6484661d79515848e0c563b40b3f3 (patch)
tree0f96243aa31934ba1accf3838047c7c841df6d4d /documents
parentd0644b9938157c3e92cd35ce8fa36657c91a0436 (diff)
downloaddotfiles-9495b7740ef6484661d79515848e0c563b40b3f3.tar.gz
dotfiles-9495b7740ef6484661d79515848e0c563b40b3f3.zip
Add bootstrap.ps1
Diffstat (limited to 'documents')
-rw-r--r--documents/powershell/bootstrap.ps1511
1 files changed, 511 insertions, 0 deletions
diff --git a/documents/powershell/bootstrap.ps1 b/documents/powershell/bootstrap.ps1
new file mode 100644
index 0000000..4ae88e6
--- /dev/null
+++ b/documents/powershell/bootstrap.ps1
@@ -0,0 +1,511 @@
+# Requires -RunAsAdministrator
+
+# Variables
+#$newUsername = "srdusr"
+$dotfiles_url = 'https://github.com/srdusr/dotfiles.git'
+$dotfiles_dir = "$HOME\.cfg"
+$oldUsername = $env:USERNAME
+
+# Function to handle errors
+function handle_error {
+ param ($message)
+ Write-Host $message -ForegroundColor Red
+ exit 1
+}
+
+# Function to check if the current session is elevated
+function Test-IsAdmin {
+ $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
+ $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
+ return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
+}
+
+# Ensure the script is run as administrator
+if (-not (Test-IsAdmin)) {
+ handle_error "This script must be run as an administrator."
+}
+
+$bloatware = @(
+ #"Anytime"
+ "BioEnrollment"
+ #"Browser"
+ "ContactSupport"
+ "Cortana"
+ #"Defender"
+ "Feedback"
+ "Flash"
+ #"Gaming" # Breaks Xbox Live Account Login
+ #"Holo"
+ #"InternetExplorer"
+ "Maps"
+ #"MiracastView"
+ "OneDrive"
+ #"SecHealthUI"
+ "Wallet"
+ #"Xbox" # Causes a bootloop since upgrade 1511?
+)
+
+# Helper functions ------------------------
+function force-mkdir($path) {
+ if (!(Test-Path $path)) {
+ #Write-Host "-- Creating full path to: " $path -ForegroundColor White -BackgroundColor DarkGreen
+ New-Item -ItemType Directory -Force -Path $path
+ }
+}
+
+function Takeown-Registry($key) {
+ # TODO does not work for all root keys yet
+ switch ($key.split('\')[0]) {
+ "HKEY_CLASSES_ROOT" {
+ $reg = [Microsoft.Win32.Registry]::ClassesRoot
+ $key = $key.substring(18)
+ }
+ "HKEY_CURRENT_USER" {
+ $reg = [Microsoft.Win32.Registry]::CurrentUser
+ $key = $key.substring(18)
+ }
+ "HKEY_LOCAL_MACHINE" {
+ $reg = [Microsoft.Win32.Registry]::LocalMachine
+ $key = $key.substring(19)
+ }
+ }
+
+ # get administraor group
+ $admins = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
+ $admins = $admins.Translate([System.Security.Principal.NTAccount])
+
+ # set owner
+ $key = $reg.OpenSubKey($key, "ReadWriteSubTree", "TakeOwnership")
+ $acl = $key.GetAccessControl()
+ $acl.SetOwner($admins)
+ $key.SetAccessControl($acl)
+
+ # set FullControl
+ $acl = $key.GetAccessControl()
+ $rule = New-Object System.Security.AccessControl.RegistryAccessRule($admins, "FullControl", "Allow")
+ $acl.SetAccessRule($rule)
+ $key.SetAccessControl($acl)
+}
+
+function Takeown-File($path) {
+ takeown.exe /A /F $path
+ $acl = Get-Acl $path
+
+ # get administraor group
+ $admins = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
+ $admins = $admins.Translate([System.Security.Principal.NTAccount])
+
+ # add NT Authority\SYSTEM
+ $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($admins, "FullControl", "None", "None", "Allow")
+ $acl.AddAccessRule($rule)
+
+ Set-Acl -Path $path -AclObject $acl
+}
+
+function Takeown-Folder($path) {
+ Takeown-File $path
+ foreach ($item in Get-ChildItem $path) {
+ if (Test-Path $item -PathType Container) {
+ Takeown-Folder $item.FullName
+ }
+ else {
+ Takeown-File $item.FullName
+ }
+ }
+}
+
+function Elevate-Privileges {
+ param($Privilege)
+ $Definition = @"
+ using System;
+ using System.Runtime.InteropServices;
+
+ public class AdjPriv {
+ [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
+ internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr rele);
+
+ [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
+ internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
+
+ [DllImport("advapi32.dll", SetLastError = true)]
+ internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ internal struct TokPriv1Luid {
+ public int Count;
+ public long Luid;
+ public int Attr;
+ }
+
+ internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
+ internal const int TOKEN_QUERY = 0x00000008;
+ internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
+
+ public static bool EnablePrivilege(long processHandle, string privilege) {
+ bool retVal;
+ TokPriv1Luid tp;
+ IntPtr hproc = new IntPtr(processHandle);
+ IntPtr htok = IntPtr.Zero;
+ retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
+ tp.Count = 1;
+ tp.Luid = 0;
+ tp.Attr = SE_PRIVILEGE_ENABLED;
+ retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
+ retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
+ return retVal;
+ }
+ }
+"@
+ $ProcessHandle = (Get-Process -id $pid).Handle
+ $type = Add-Type $definition -PassThru
+ $type[0]::EnablePrivilege($processHandle, $Privilege)
+}
+
+# Elevate so I can run everything ------------------------
+Write-Output "Elevating priviledges for this process"
+do { } until (Elevate-Privileges SeTakeOwnershipPrivilege)
+
+# Remove Features ------------------------
+foreach ($bloat in $bloatware) {
+ Write-Output "Removing packages containing $bloat"
+ $pkgs = (Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" |
+ Where-Object Name -Like "*$bloat*")
+
+ foreach ($pkg in $pkgs) {
+ $pkgname = $pkg.Name.split('\')[-1]
+ Takeown-Registry($pkg.Name)
+ Takeown-Registry($pkg.Name + "\Owners")
+ Set-ItemProperty -Path ("HKLM:" + $pkg.Name.Substring(18)) -Name Visibility -Value 1
+ New-ItemProperty -Path ("HKLM:" + $pkg.Name.Substring(18)) -Name DefVis -PropertyType DWord -Value 2
+ Remove-Item -Path ("HKLM:" + $pkg.Name.Substring(18) + "\Owners")
+ dism.exe /Online /Remove-Package /PackageName:$pkgname /NoRestart
+ }
+}
+
+
+# Remove default apps and bloat ------------------------
+Write-Output "Uninstalling default apps"
+foreach ($app in $apps) {
+ Write-Output "Trying to remove $app"
+ Get-AppxPackage -Name $app -AllUsers | Remove-AppxPackage -AllUsers
+ Get-AppXProvisionedPackage -Online |
+ Where-Object DisplayName -EQ $app |
+ Remove-AppxProvisionedPackage -Online
+}
+
+# Prevents "Suggested Applications" returning
+force-mkdir "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Cloud Content"
+Set-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Cloud Content" "DisableWindowsConsumerFeatures" 1
+
+# Kill OneDrive with fire ------------------------
+Write-Output "Kill OneDrive process"
+taskkill.exe /F /IM "OneDrive.exe"
+taskkill.exe /F /IM "explorer.exe"
+
+Write-Output "Remove OneDrive"
+if (Test-Path "$env:systemroot\System32\OneDriveSetup.exe") {
+ & "$env:systemroot\System32\OneDriveSetup.exe" /uninstall
+}
+if (Test-Path "$env:systemroot\SysWOW64\OneDriveSetup.exe") {
+ & "$env:systemroot\SysWOW64\OneDriveSetup.exe" /uninstall
+}
+
+Write-Output "Removing OneDrive leftovers"
+Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:localappdata\Microsoft\OneDrive"
+Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:programdata\Microsoft OneDrive"
+Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:systemdrive\OneDriveTemp"
+# check if directory is empty before removing:
+If ((Get-ChildItem "$env:userprofile\OneDrive" -Recurse | Measure-Object).Count -eq 0) {
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:userprofile\OneDrive"
+}
+
+Write-Output "Disable OneDrive via Group Policies"
+force-mkdir "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\OneDrive"
+Set-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\OneDrive" "DisableFileSyncNGSC" 1
+
+Write-Output "Remove Onedrive from explorer sidebar"
+New-PSDrive -PSProvider "Registry" -Root "HKEY_CLASSES_ROOT" -Name "HKCR"
+force-mkdir "HKCR:\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}"
+Set-ItemProperty "HKCR:\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" "System.IsPinnedToNameSpaceTree" 0
+force-mkdir "HKCR:\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}"
+Set-ItemProperty "HKCR:\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" "System.IsPinnedToNameSpaceTree" 0
+Remove-PSDrive "HKCR"
+
+# Thank you Matthew Israelsson
+Write-Output "Removing run hook for new users"
+reg load "hku\Default" "C:\Users\Default\NTUSER.DAT"
+reg delete "HKEY_USERS\Default\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "OneDriveSetup" /f
+reg unload "hku\Default"
+
+Write-Output "Removing startmenu entry"
+Remove-Item -Force -ErrorAction SilentlyContinue "$env:userprofile\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk"
+
+Write-Output "Removing scheduled task"
+Get-ScheduledTask -TaskPath '\' -TaskName 'OneDrive*' -ea SilentlyContinue | Unregister-ScheduledTask -Confirm:$false
+
+Write-Output "Restarting explorer"
+Start-Process "explorer.exe"
+
+Write-Output "Waiting for explorer to complete loading"
+Start-Sleep 10
+
+Write-Output "Removing additional OneDrive leftovers"
+foreach ($item in (Get-ChildItem "$env:WinDir\WinSxS\*onedrive*")) {
+ Takeown-Folder $item.FullName
+ Remove-Item -Recurse -Force $item.FullName
+}
+
+# As a last step, disable UAC ------------------------
+#New-ItemProperty -Path HKLM:Software\Microsoft\Windows\CurrentVersion\policies\system -Name EnableLUA -PropertyType DWord -Value 0 -Force
+
+
+# Remove OneDrive directory
+Write-Host "Removing OneDrive directory"
+cd $HOME
+rm OneDrive -r -force
+
+ Configure PowerShell
+Write-Host "Configuring PowerShell"
+Write-Host "----------------------------------------"
+
+# Get the "MyDocuments" path for the current user, excluding OneDrive
+$UserMyDocumentsPath = [System.Environment]::GetFolderPath('MyDocuments').Replace("OneDrive", "") + "\Documents"
+
+$PowerShellProfileDirectory = "$UserMyDocumentsPath\PowerShell"
+$PowerShellLegacySymlink = "$UserMyDocumentsPath\WindowsPowerShell"
+
+$PowerShellProfileTemplate = "$PSScriptRoot\$USERNAME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1"
+$env:PSModulePath = $env:PSModulePath -replace "\\OneDrive\\Documents\\WindowsPowerShell\\","\.powershell\"
+
+# Set documents path to user's local Documents folder
+$documentsPath = "$UserMyDocumentsPath"
+$powerShellProfileDir = "$documentsPath\PowerShell"
+
+# Output the chosen PowerShell profile directory
+$PROFILE = "$powerShellProfileDir\Microsoft.PowerShell_profile.ps1"
+Write-Host "PowerShell profile directory set to: $powerShellProfileDir"
+
+if (-not (Test-Path -Path $powerShellProfileDir)) {
+ New-Item -ItemType Directory -Path $powerShellProfileDir -Force
+}
+
+New-Item -ItemType HardLink -Force `
+ -Path "$powerShellProfileDir\Microsoft.PowerShell_profile.ps1" `
+ -Target "$home\.config\powershell\Microsoft.PowerShell_profile.ps1"
+
+# Set environment variable
+[System.Environment]::SetEnvironmentVariable('PowerShellProfileDir', $powerShellProfileDir, [System.EnvironmentVariableTarget]::User)
+
+Write-Host "PowerShell profile directory set to: $powerShellProfileDir"
+Write-Host "Environment variable 'PowerShellProfileDir' set to: $powerShellProfileDir"
+
+# Verify profile sourcing
+if (!(Test-Path -Path "$home\.config\powershell\Microsoft.PowerShell_profile.ps1")) {
+ handle_error "PowerShell profile does not exist. Please create it at $home\.config\powershell\Microsoft.PowerShell_profile.ps1"
+}
+
+# Define the `config` alias in the current session
+function global:config {
+ git --git-dir="$env:USERPROFILE\.cfg" --work-tree="$env:USERPROFILE" $args
+}
+
+# Add .gitignore entries
+Add-Content -Path "$HOME\.gitignore" -Value ".cfg"
+Add-Content -Path "$HOME\.gitignore" -Value "install.bat"
+Add-Content -Path "$HOME\.gitignore" -Value ".config/powershell/bootstrap.ps1"
+
+## Check if the profile exists, otherwise create it
+#if (!(Test-Path -Path $PROFILE)) {
+# New-Item -Type File -Path $PROFILE -Force
+#}
+#Add-Content -Path $PROFILE -Value "`nfunction config { git --git-dir=`$env:USERPROFILE/.cfg/ --work-tree=`$env:USERPROFILE @args }"
+#Add-Content -Path $PROFILE -Value "`n. $PROFILE"
+
+# Source the profile immediately to make the alias available
+
+#echo '. "$HOME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1"' >> $PROFILE
+
+# Function to install dotfiles
+function install_dotfiles {
+ if (Test-Path -Path $dotfiles_dir) {
+ config pull | Out-Null
+ $update = $true
+ } else {
+ git clone --bare $dotfiles_url $dotfiles_dir | Out-Null
+ $update = $false
+ }
+
+ $std_err_output = config checkout 2>&1
+
+ if ($std_err_output -match "following untracked working tree files would be overwritten") {
+ if (-not $update) {
+ config checkout | Out-Null
+ }
+ }
+ config config status.showUntrackedFiles no
+
+ git config --global include.path "$HOME\.gitconfig.aliases"
+
+ if ($update -or (Read-Host "Do you want to overwrite existing files and continue with the dotfiles setup? [Y/n]" -eq "Y")) {
+ config fetch origin main:main | Out-Null
+ config reset --hard main | Out-Null
+ config checkout -f
+ if ($?) {
+ Write-Host "Successfully imported $dotfiles_dir."
+ } else {
+ handle_error "Mission failed."
+ }
+ } else {
+ handle_error "Aborted by user. Exiting..."
+ }
+}
+
+install_dotfiles
+
+#. $PROFILE
+
+# Install Chocolatey if not installed
+Write-Host "Installing Chocolatey"
+Write-Host "----------------------------------------"
+
+Set-ExecutionPolicy Bypass -Scope Process -Force
+
+if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
+ [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
+ Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
+
+ # Check if Chocolatey installed successfully
+ if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
+ handle_error "Chocolatey installation failed."
+ }
+} else {
+ Write-Host "Chocolatey is already installed."
+}
+
+# Install Applications
+Write-Host "Installing Applications"
+Write-Host "----------------------------------------"
+
+# Define the list of applications to install
+$apps = @("ripgrep", "fd", "sudo", "win32yank", "neovim", "microsoft-windows-terminal")
+
+foreach ($app in $apps) {
+ # Check if the application is already installed
+ if (-not (choco list --local-only | Select-String -Pattern "^$app\s")) {
+ Write-Host "Installing $app"
+ choco install $app -y
+
+ if ($LASTEXITCODE -ne 0) {
+ handle_error "Installation of $app failed."
+ } else {
+ Write-Host "$app installed successfully."
+ }
+ } else {
+ Write-Host "$app is already installed."
+ }
+}
+
+## WSL
+#Write-Host "Configuring WSL"
+#wsl --install -d Ubuntu
+
+## Function to install SSH
+#function install_ssh {
+# Write-Host "Setting Up SSH"
+# Start-Service ssh-agent
+# Start-Service sshd
+# Set-Service -Name ssh-agent -StartupType 'Automatic'
+# Set-Service -Name sshd -StartupType 'Automatic'
+#
+# # Generate SSH key if not exists
+# if (-not (Test-Path -Path "$env:USERPROFILE\.ssh\id_rsa.pub")) {
+# ssh-keygen -t rsa -b 4096 -C "$env:USERNAME@$(hostname)" -f "$env:USERPROFILE\.ssh\id_rsa" -N ""
+# }
+#
+# # Start ssh-agent and add key
+# eval $(ssh-agent -s)
+# ssh-add "$env:USERPROFILE\.ssh\id_rsa"
+#
+# # Display the SSH key
+# $sshKey = Get-Content "$env:USERPROFILE\.ssh\id_rsa.pub"
+# Write-Host "Add the following SSH key to your GitHub account:"
+# Write-Host $sshKey
+#}
+#
+#install_ssh
+
+# Configure Neovim
+Write-Host "Configuring Neovim"
+Write-Host "----------------------------------------"
+
+$neovimLocalPath = "$home\AppData\Local\nvim"
+$neovimConfigPath = "$home\.config\nvim"
+
+# Check if nvim directory already exists in AppData\Local
+if (-not (Test-Path -Path $neovimLocalPath)) {
+ New-Item -ItemType Junction -Force -Path $neovimLocalPath -Target $neovimConfigPath
+} else {
+ Write-Host "Neovim directory ($neovimLocalPath) already exists."
+}
+
+# Install Windows Terminal, and configure
+Write-Host "Install Windows Terminal, and configure"
+Write-Host "----------------------------------------"
+
+$windowsTerminalSettingsPath = "$home\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
+$windowsTerminalConfigPath = "$home\.config\windows-terminal\settings.json"
+
+# Check if Windows Terminal settings.json already exists
+if (Test-Path -Path $windowsTerminalSettingsPath) {
+ # Backup existing settings.json
+ Move-Item -Force $windowsTerminalSettingsPath "$windowsTerminalSettingsPath.old"
+} else {
+ Write-Host "Windows Terminal settings.json not found."
+}
+
+# Create a hard link to the settings.json file in .config\windows-terminal
+New-Item -ItemType HardLink -Force -Path $windowsTerminalSettingsPath -Target $windowsTerminalConfigPath
+
+
+# Registry Tweaks
+Write-Host "Registry Tweaks"
+Write-Host "----------------------------------------"
+
+# Show hidden files
+Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name Hidden -Value 1
+
+# Show file extensions for known file types
+Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name HideFileExt -Value 0
+
+# Never Combine taskbar buttons when the taskbar is full
+Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name TaskbarGlomLevel -Value 2
+
+# Taskbar small icons
+Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name TaskbarSmallIcons -Value 1
+
+# Set Windows to use UTC time instead of local time for system clock
+Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name RealTimeIsUniversal -Value 1
+
+## Function to disable the Windows key
+#function Disable-WindowsKey {
+# $scancodeMap = @(
+# 0x00000000, 0x00000000, 0x00000003, 0xE05B0000, 0xE05C0000, 0x00000000
+# )
+#
+# $binaryValue = New-Object byte[] ($scancodeMap.Length * 4)
+# [System.Buffer]::BlockCopy($scancodeMap, 0, $binaryValue, 0, $binaryValue.Length)
+#
+# Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Keyboard Layout" -Name "Scancode Map" -Value $binaryValue
+#
+# Write-Output "Windows key has been disabled. Please restart your computer for the changes to take effect."
+#}
+#
+## Check if running as Administrator and call the function
+#if (Test-IsAdmin) {
+# Disable-WindowsKey
+#} else {
+# Write-Output "You need to run this script as Administrator to disable the Windows key."
+#}
+# Restart to apply changes
+#Write-Host "Restarting system to apply changes..."
+#Restart-Computer -Force