Skip to content

Instantly share code, notes, and snippets.

@garyo
Last active January 14, 2025 13:52
Show Gist options
  • Save garyo/875fd912fa1174fdcb0ad10a8d9fcc72 to your computer and use it in GitHub Desktop.
Save garyo/875fd912fa1174fdcb0ad10a8d9fcc72 to your computer and use it in GitHub Desktop.
# Script to set up Windows 11 admin configuration for software development
# Author: Gary Oberbrunner, [email protected]
# License: MIT
# Requires elevation
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "This script requires admin privileges. Please run PowerShell as Administrator and try again."
Exit 1
}
# Enable Developer Mode
Write-Host "Enabling Developer Mode..."
$RegistryKeyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock"
if (-NOT(Test-Path -Path $RegistryKeyPath)) {
New-Item -Path $RegistryKeyPath -ItemType Directory -Force
}
Set-ItemProperty -Path $RegistryKeyPath -Name "AllowDevelopmentWithoutDevLicense" -Value 1
Set-ItemProperty -Path $RegistryKeyPath -Name "AllowAllTrustedApps" -Value 1
# Install Developer Mode package
Write-Host "Installing Windows Developer Mode package..."
try {
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-DeveloperMode -All -NoRestart
Write-Host "Developer Mode package installed successfully"
} catch {
Write-Host "Error installing Developer Mode package: $_"
}
# Enable End Task in Task Manager
Write-Host "Enabling End Task in Task Manager..."
$endTaskPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\TaskManager"
if (-NOT(Test-Path -Path $endTaskPath)) {
New-Item -Path $endTaskPath -ItemType Directory -Force
}
Set-ItemProperty -Path $endTaskPath -Name "EnableEndTask" -Value 1
# Enable symlink creation without admin privileges
Write-Host "Enabling symlink creation for non-admin users..."
$symlinkKeyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
Set-ItemProperty -Path $symlinkKeyPath -Name "EnableLinksAcrossUserAccounts" -Value 1
# Set HOME environment variable
Write-Host "Setting HOME environment variable..."
[System.Environment]::SetEnvironmentVariable('HOME', $env:USERPROFILE, [System.EnvironmentVariableTarget]::User)
$env:HOME = $env:USERPROFILE
########################################################################
# Unlink standard folders from OneDrive, store them locally
########################################################################
# Stop OneDrive process before unlinking folders
Stop-Process -Name "OneDrive" -Force -ErrorAction SilentlyContinue
# Registry paths for Known Folders
$RegistryPaths = @(
"HKCU:\Software\Microsoft\OneDrive\Accounts\Business1\Tenants",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{018D5C66-4533-4307-9B53-224DE2ED1FE6}",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\OneDrive",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
)
# Default folder locations
$DefaultFolders = @{
"Desktop" = [Environment]::GetFolderPath("Desktop")
"Documents" = [Environment]::GetFolderPath("MyDocuments")
"Pictures" = [Environment]::GetFolderPath("MyPictures")
}
# Update Shell Folders registry keys to default locations
foreach ($Path in $RegistryPaths) {
if (Test-Path $Path) {
foreach ($Folder in $DefaultFolders.Keys) {
$DefaultLocation = $DefaultFolders[$Folder]
try {
Set-ItemProperty -Path $Path -Name $Folder -Value $DefaultLocation -ErrorAction SilentlyContinue
Write-Host "Updated $Folder to $DefaultLocation"
}
catch {
Write-Host "Could not update $Folder location: $_"
}
}
}
}
# Remove OneDrive sync relationships
$OneDrivePath = "$env:USERPROFILE\OneDrive"
if (Test-Path $OneDrivePath) {
Remove-Item -Path "$OneDrivePath\Desktop" -Force -Recurse -ErrorAction SilentlyContinue
Remove-Item -Path "$OneDrivePath\Documents" -Force -Recurse -ErrorAction SilentlyContinue
Remove-Item -Path "$OneDrivePath\Pictures" -Force -Recurse -ErrorAction SilentlyContinue
Write-Host "Removed OneDrive sync folders"
}
# Configure File Explorer settings
Write-Host "Configuring File Explorer settings..."
$explorerPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
# Show file extensions
Set-ItemProperty -Path $explorerPath -Name "HideFileExt" -Value 0
# Show hidden files
Set-ItemProperty -Path $explorerPath -Name "Hidden" -Value 1
# Show system files
Set-ItemProperty -Path $explorerPath -Name "ShowSuperHidden" -Value 1
# Show full path in title bar
Set-ItemProperty -Path $explorerPath -Name "ShowFullPath" -Value 1
# Restart Explorer to apply changes
Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue
Start-Process "explorer"
Write-Host "OneDrive folders have been unlinked. Please verify your files are in the correct locations."
Write-Host "Setting ssh-agent service to start manually"
Get-Service -Name ssh-agent | Set-Service -StartupType Manual
Write-Host @"
Admin setup complete! Now please:
1. Open a regular (non-admin) PowerShell window
2. Run WinDevSetup-user.ps1 to install and configure all software:
irm https://tinyurl.com/WinDevSetup-user | iex
"@
# Script to install and configure Windows 11 development software
# Author: Gary Oberbrunner, [email protected]
# License: MIT
## Verify we're NOT running as admin (hmm, this doesn't work -- just comment out for now)
#if ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") {
# Write-Host "This script must NOT run with admin privileges. Please run in a regular PowerShell window."
# Exit 1
#}
# Install Scoop if not already installed
if (!(Get-Command scoop -ErrorAction SilentlyContinue)) {
Write-Host "Installing Scoop..."
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod get.scoop.sh | Invoke-Expression
}
# Install aria2 for parallel downloads first
if (!(Get-Command aria2c -ErrorAction SilentlyContinue)) {
Write-Host "Installing aria2 for faster downloads..."
scoop install aria2
scoop config aria2-enabled true
scoop config aria2-warning-enabled false
}
# Add scoop buckets (need git first)
Write-Host "Adding Scoop buckets with git and 7zip..."
scoop install 7zip git
$buckets = @('extras', 'sysinternals', 'nerd-fonts', 'nonportable')
foreach ($bucket in $buckets) {
Write-Host "Adding $bucket bucket..."
scoop bucket add $bucket
}
# Latest emacs build:
scoop bucket add kiennq-scoop-misc https://github.com/kiennq/scoop-misc
# Install all packages in parallel
Write-Host "Installing all packages..."
scoop install `
vscode vim rapidee emacs-kl `
cppcheck clangd gh diffutils kdiff3 uv `
everything-np debugview procmon sysmon dependencies `
fd ripgrep eza fzf delta msys2 `
logseq synctrayzor Hack-NF CascadiaCode-NF
# Define MSYS2 paths for Scoop installation
$msys2Root = "$env:USERPROFILE\scoop\apps\msys2\current"
$msys2Shell = "$msys2Root\msys2.exe"
# Update nsswitch.conf using bash
Write-Host "Configuring nsswitch.conf..."
$bashCommand = 'sed -i "/^db_home:/c\db_home: windows" /etc/nsswitch.conf'
Start-Process -FilePath $msys2Shell -ArgumentList "-defterm", "-no-start", "-here", "-c", $bashCommand -Wait
# Configure Git line endings
Write-Host "Configuring Git line endings..."
git config --global core.autocrlf false
# Post-installation configurations
Write-Host "Applying post-installation configurations..."
# VSCode extensions and settings
Write-Host "Installing VSCode extensions..."
$vsCodeExtensions = @(
'ms-vscode.cpptools',
'eamodio.gitlens',
'GitHub.copilot',
'ms-python.python',
'rust-lang.rust-analyzer',
'vadimcn.vscode-lldb'
)
foreach ($extension in $vsCodeExtensions) {
code --install-extension $extension
}
# Configure Everything
Write-Host "Configuring Everything search..."
Start-Process "$env:USERPROFILE\scoop\shims\everything.exe" -ArgumentList "-startup"
Start-Sleep -Seconds 2
# Configure fzf and other tools in $PROFILE
Write-Host "Configuring fzf and other tools in user profile..."
$profileContent = @"
# fzf configuration
`$env:FZF_DEFAULT_COMMAND = 'fd --type f --hidden --follow --exclude .git'
`$env:FZF_DEFAULT_OPTS = '--height 40% --layout=reverse --border'
# Set eza as default list command
Set-Alias -Name ls -Value eza -Option AllScope
Set-Alias -Name ll -Value 'eza -l' -Option AllScope
Set-Alias -Name la -Value 'eza -la' -Option AllScope
Set-Alias -Name lt -Value 'eza --tree' -Option AllScope
Set-Alias -Name msys -Value 'msys2 -full-path -shell zsh' -Option AllScope
Write-Host "⮕Use msys alias to run msys2 zsh"
"@
# Create PowerShell profile directory if it doesn't exist
$profileDir = Split-Path $PROFILE -Parent
if (!(Test-Path $profileDir)) {
New-Item -Path $profileDir -ItemType Directory -Force
}
Add-Content $PROFILE $profileContent
# Install commonly needed MSYS2 packages
Write-Host "Installing common MSYS2 packages..."
Start-Process -FilePath $msys2Shell -ArgumentList "-defterm", "-no-start", "-here", "-c", "pacman -S --noconfirm mingw-w64-x86_64-toolchain base-devel zsh" -Wait
Write-Host @"
Setup complete! Additional notes:
1. VSCode: Log in to GitHub to activate Copilot
2. Everything: The service is now running in the background
3. PowerShell: New aliases and fzf configuration added to profile
4. MSYS2: Basic development tools installed
Please log out and back in for all changes to take effect.
GitHub CLI: Run 'gh auth login' to authenticate.
Create a Dev Drive on d: for source and tools.
"@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment