# set-executionpolicy unrestricted # Check if running as administrator if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "This script requires administrator privileges. Attempting to restart as administrator..." -ForegroundColor Yellow # Get the current script path $scriptPath = $MyInvocation.MyCommand.Path # Restart the script with administrator privileges try { Start-Process PowerShell -Verb RunAs -ArgumentList "-ExecutionPolicy Bypass -File `"$scriptPath`"" exit } catch { Write-Error "Failed to restart as administrator. Please run this script as administrator manually." Write-Host "Right-click on PowerShell and select 'Run as administrator', then run this script again." -ForegroundColor Red pause exit 1 } } Write-Host "Running with administrator privileges." -ForegroundColor Green # Self-update function for the script function Update-Scripts { Write-Host "Checking for updates..." -ForegroundColor Cyan $updateScriptDir = $PSScriptRoot $lastUpdateCheck = $null $updateCheckFile = Join-Path -Path $updateScriptDir -ChildPath "last_update_check.txt" $zipUrl = "https://gitea.andrewspolytechnic.com/public/windows-install/archive/master.zip" try { # Check if we've checked for updates in the last 24 hours if (Test-Path $updateCheckFile) { $lastUpdateCheck = Get-Content $updateCheckFile | Get-Date $timeSinceLastCheck = (Get-Date) - $lastUpdateCheck if ($timeSinceLastCheck.TotalHours -lt 24) { Write-Host "Last update check was less than 24 hours ago. Skipping update check." -ForegroundColor DarkGray return $false # No update performed } } # Create a temporary directory in the script folder (will be ignored by git) $tempDir = Join-Path -Path $updateScriptDir -ChildPath "temp" if (Test-Path $tempDir) { Remove-Item $tempDir -Recurse -Force } New-Item -ItemType Directory -Path $tempDir -Force | Out-Null $zipPath = Join-Path -Path $tempDir -ChildPath "update.zip" $ProgressPreference = 'SilentlyContinue' # Hide progress bar to speed up download Write-Host "Downloading updates from $zipUrl..." -ForegroundColor Cyan try { Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath -UseBasicParsing -TimeoutSec 30 } catch { Write-Host "Failed to download from URL: $_" -ForegroundColor DarkGray return $false # Failed to download } # Check if the download was successful (file exists and is not empty) if ((Test-Path $zipPath) -and ((Get-Item $zipPath).Length -gt 0)) { Write-Host "Download successful!" -ForegroundColor Green try { # Extract the zip file Write-Host "Extracting update package..." -ForegroundColor Cyan Expand-Archive -Path $zipPath -DestinationPath $tempDir -Force # Based on our analysis, the zip extracts to a "windows-install" directory $extractedDir = Get-ChildItem -Path $tempDir -Directory | Where-Object { $_.Name -eq "windows-install" } | Select-Object -First 1 if (($extractedDir) -and ((Test-Path $extractedDir.FullName))) { Write-Host "Comparing update files with current installation..." -ForegroundColor Cyan # Function to get file hash function Get-FileHashQuick($filePath) { if (Test-Path $filePath -PathType Leaf) { return (Get-FileHash -Path $filePath -Algorithm MD5).Hash } return $null } $differentFiles = @() $newFiles = @() $unchangedFiles = @() # Compare files from the extracted directory with existing files Get-ChildItem -Path $extractedDir.FullName -Recurse | Where-Object { !$_.PSIsContainer -and $_.Name -ne ".git" } | ForEach-Object { $relativePath = $_.FullName.Substring($extractedDir.FullName.Length + 1) $currentFilePath = Join-Path -Path $updateScriptDir -ChildPath $relativePath if (Test-Path $currentFilePath) { $newHash = Get-FileHashQuick $_.FullName $currentHash = Get-FileHashQuick $currentFilePath if ($newHash -ne $currentHash) { $differentFiles += $relativePath } else { $unchangedFiles += $relativePath } } else { $newFiles += $relativePath } } # Display the results Write-Host "`nUpdate analysis complete!" -ForegroundColor Green if ($differentFiles.Count -gt 0) { Write-Host "`nFiles with changes ($($differentFiles.Count)):" -ForegroundColor Yellow foreach ($file in $differentFiles) { Write-Host " - $file" -ForegroundColor Yellow } } if ($newFiles.Count -gt 0) { Write-Host "`nNew files ($($newFiles.Count)):" -ForegroundColor Cyan foreach ($file in $newFiles) { Write-Host " - $file" -ForegroundColor Cyan } } if ($unchangedFiles.Count -gt 0) { Write-Host "`nUnchanged files: $($unchangedFiles.Count)" -ForegroundColor DarkGray } # Record the update check time Get-Date -Format "yyyy-MM-dd HH:mm:ss" | Out-File -FilePath $updateCheckFile -Force # Only ask to apply changes if there are differences if ($differentFiles.Count -gt 0 -or $newFiles.Count -gt 0) { $applyChoice = Read-Host "`nWould you like to apply these changes? (Y/N)" if ($applyChoice -eq "Y" -or $applyChoice -eq "y") { Write-Host "Installing updates..." -ForegroundColor Cyan # Copy files from the extracted directory directly Get-ChildItem -Path $extractedDir.FullName | Where-Object { $_.Name -ne ".git" } | ForEach-Object { $destPath = Join-Path -Path $updateScriptDir -ChildPath $_.Name Copy-Item -Path $_.FullName -Destination $destPath -Recurse -Force } Write-Host "Update completed successfully!" -ForegroundColor Green # Suggest restarting the script with the updated version $restartChoice = Read-Host "The script has been updated. Would you like to restart the script to use the updated version? (Y/N)" if ($restartChoice -eq "Y" -or $restartChoice -eq "y") { Write-Host "Restarting script..." -ForegroundColor Cyan Start-Process PowerShell -Verb RunAs -ArgumentList "-ExecutionPolicy Bypass -File `"$PSCommandPath`"" exit } return $true # Update performed successfully } else { Write-Host "Update cancelled. No changes were made." -ForegroundColor Yellow return $false } } else { Write-Host "`nNo changes detected. Your installation is up to date!" -ForegroundColor Green return $false # No changes to apply } } else { Write-Host "Could not find extracted update directory." -ForegroundColor Yellow } } catch { Write-Host "Error extracting or installing updates: $_" -ForegroundColor Yellow } } else { Write-Host "Could not download updates. Please check your internet connection." -ForegroundColor Yellow } # Clean up if (Test-Path $tempDir) { try { Remove-Item $tempDir -Recurse -Force -ErrorAction SilentlyContinue } catch { Write-Host "Could not clean up temp directory: $_" -ForegroundColor DarkGray } } return $false # Update failed } catch { Write-Host "Error checking for updates: $_" -ForegroundColor Yellow Write-Host "Continuing with current version..." -ForegroundColor Yellow return $false # Update failed } } # Call the update function at the beginning $scriptUpdated = Update-Scripts [Environment]::UserName $uid = $Env:UserName # Get current username for use in paths reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve Add-WindowsCapability -Online -Name 'OpenSSH.Client~~~~0.0.1.0' Enable-WindowsOptionalFeature -FeatureName ServicesForNFS-ClientOnly, ClientForNFS-Infrastructure -Online -NoRestart winget source remove msstore winget import -i .\winget.json winget pin add Discord.Discord #RDP Magic Enable-NetFirewallRule -DisplayGroup "Remote Desktop" Set-Service -Name TermService -StartupType Automatic Start-Service -Name TermService # Font Install $fontSourceFolder = ".\Fonts" $fontDestFolder = "C:\Windows\Fonts" $regPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" # Process each TTF file Get-ChildItem -Path $fontSourceFolder -Filter "*.ttf" | ForEach-Object { $fontFile = $_.FullName $fontName = $_.BaseName $destFile = Join-Path -Path $fontDestFolder -ChildPath $_.Name Copy-Item -Path $fontFile -Destination $destFile -Force New-ItemProperty -Path $regPath -Name "$fontName (TrueType)" -Value $_.Name -PropertyType String -Force } Write-Host "Fonts installed for all users. Restart may be required."