# 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))) { # Copy all files except .git directory to current location Write-Host "Installing updates from $($extractedDir.FullName)..." -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 } # Record the update time Get-Date -Format "yyyy-MM-dd HH:mm:ss" | Out-File -FilePath $updateCheckFile -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 "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 $uid = $Env:UserName # Get the directory where this script is located $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path Copy-Item -Path "$scriptDir\FastStone" -Destination "C:\Users\$uid\AppData\Local\" -Recurse -Force # Define the Firefox installation directory $firefoxPath = "C:\Program Files\Mozilla Firefox" $distributionPath = Join-Path -Path $firefoxPath -ChildPath "distribution" # Ensure the distribution folder exists if (-not (Test-Path -Path $distributionPath)) { New-Item -Path $distributionPath -ItemType Directory | Out-Null } # Define the source and destination paths for policies.json $sourceFile = "$scriptDir\Firefox\policies.json" $destinationFile = Join-Path -Path $distributionPath -ChildPath "policies.json" # Copy/replace the policies.json file Copy-Item -Path $sourceFile -Destination $destinationFile -Force Write-Host "policies.json has been copied/replaced in the distribution folder." $forgePath = "C:\ProgramData\miniforge3" $systemPathReference = [System.Environment]::GetEnvironmentVariable("Path", "Machine") # Check if the path already contains $forgePath if (-not ($systemPathReference -split ";" | Where-Object { $_ -eq $forgePath })) { # Append $forgePath to the existing path, with proper separation by semicolon $newPath = $systemPathReference + ";" + $forgePath [System.Environment]::SetEnvironmentVariable("Path", $newPath, "Machine") } # Define the base Firefox profiles directory $profilesDir = "$env:APPDATA\Mozilla\Firefox\Profiles" # Define the source user.js file $sourceFile = "$scriptDir\Firefox\user.js" # Use absolute path based on script location # Check if the source file exists if (-not (Test-Path -Path $sourceFile)) { Write-Error "Source user.js file not found at $sourceFile" exit } # Loop through all subdirectories in the profiles folder Get-ChildItem -Path $profilesDir -Directory | ForEach-Object { $profilePath = $_.FullName $destinationFile = Join-Path -Path $profilePath -ChildPath "user.js" # Copy the user.js file to the profile directory Copy-Item -Path $sourceFile -Destination $destinationFile -Force Write-Host "user.js has been placed in: $profilePath" } Write-Host "Operation completed for all Firefox profiles." # Path to the CSV file $csvFilePath = "$scriptDir\registry.csv" $entries = Import-Csv -Path $csvFilePath foreach ($entry in $entries) { # Trim fields to remove extra spaces $registryPath = $entry.registryPath.Trim() $propertyName = $entry.propertyName.Trim() $propertyType = $entry.propertyType.Trim() $propertyValue = $entry.propertyValue.Trim() # Validate required fields if (-not $registryPath -or -not $propertyName -or -not $propertyType -or -not $propertyValue) { Write-Warning "Skipping row with incomplete data: $($entry | Out-String)" continue } # Print debug info #Write-Host "Processing: Path=$registryPath Name=$propertyName Type=$propertyType Value=$propertyValue" # Check if registry path exists, create if necessary if (-not (Test-Path $registryPath)) { try { New-Item -Path $registryPath -Force | Out-Null Write-Host "Created missing path: $registryPath" } catch { Write-Warning "Failed to create path: $registryPath. $_" continue } } # Set the registry property try { Set-ItemProperty -Path $registryPath -Name $propertyName -Type $propertyType -Value $propertyValue # Write-Host "Successfully set $propertyName in $registryPath to $propertyValue." } catch { Write-Warning "Failed to set $propertyName in $registryPath. $_" } } # ShareX - Remove "Capture Entire Screen" shortcut Write-Host "Configuring ShareX shortcuts..." # Find ShareX settings directory in Documents folder $shareXSettingsDir = "$env:USERPROFILE\Documents\ShareX" $settingsFile = Join-Path -Path $shareXSettingsDir -ChildPath "HotkeysConfig.json" if (Test-Path -Path $settingsFile) { try { # Load the current hotkeys configuration $hotkeysConfig = Get-Content -Path $settingsFile -Raw | ConvertFrom-Json # Find and modify the "Capture entire screen" hotkey to disable it foreach ($hotkey in $hotkeysConfig) { if ($hotkey.TaskSettings.Description -eq "Capture entire screen") { $hotkey.HotkeyInfo.IsActive = $false Write-Host "Disabled 'Capture entire screen' hotkey in ShareX" } } # Save the modified configuration back to file $hotkeysConfig | ConvertTo-Json -Depth 10 | Set-Content -Path $settingsFile Write-Host "ShareX hotkeys configuration updated successfully" } catch { Write-Warning "Failed to update ShareX hotkey configuration: $_" } } else { Write-Warning "ShareX settings file not found at: $settingsFile" } # ShareX - Modify PrintScreen shortcuts Write-Host "Configuring ShareX shortcuts..." # Find ShareX settings directory in Documents folder $shareXSettingsDir = "$env:USERPROFILE\Documents\ShareX" $settingsFile = Join-Path -Path $shareXSettingsDir -ChildPath "HotkeysConfig.json" if (Test-Path -Path $settingsFile) { try { # Load the current hotkeys configuration $hotkeysConfig = Get-Content -Path $settingsFile -Raw | ConvertFrom-Json # Find the Ctrl+PrintScreen entry (usually for rectangle region) $ctrlPrintscreenEntry = $hotkeysConfig.Hotkeys | Where-Object { $_.HotkeyInfo.Hotkey -eq "PrintScreen, Control" } if ($ctrlPrintscreenEntry) { $ctrlPrintscreenEntry.HotkeyInfo.Hotkey = "PrintScreen" Write-Host "Changed 'Ctrl+PrintScreen' to just 'PrintScreen'" } # Find the PrintScreen only entry (usually "Capture entire screen") and disable it $printscreenEntry = $hotkeysConfig.Hotkeys | Where-Object { $_.HotkeyInfo.Hotkey -eq "PrintScreen" -and $_ -ne $ctrlPrintscreenEntry } if ($printscreenEntry) { # Remove the entry from the array $newHotkeys = $hotkeysConfig.Hotkeys | Where-Object { $_ -ne $printscreenEntry } $hotkeysConfig.Hotkeys = $newHotkeys Write-Host "Removed entry with just PrintScreen shortcut" } # Save the modified configuration back to file $hotkeysConfig | ConvertTo-Json -Depth 10 | Set-Content -Path $settingsFile Write-Host "ShareX hotkeys configuration updated successfully" } catch { Write-Warning "Failed to update ShareX hotkey configuration: $_" } } else { Write-Warning "ShareX settings file not found at: $settingsFile" } # ShareX - Replace configuration files and remove backup folder Write-Host "Configuring ShareX..." # Define the source and destination paths $shareXSourceDir = ".\ShareX" $shareXDestDir = "$env:USERPROFILE\Documents\ShareX" $backupDir = Join-Path -Path $shareXDestDir -ChildPath "Backup" $shareXExePath = "C:\Program Files\ShareX\ShareX.exe" # Close ShareX if it's running $shareXProcess = Get-Process -Name "ShareX" -ErrorAction SilentlyContinue if ($shareXProcess) { Write-Host "Closing ShareX process..." $shareXProcess | Stop-Process -Force Start-Sleep -Seconds 1 # Give it a moment to close } # Check if the source directory exists if (-not (Test-Path -Path $shareXSourceDir)) { Write-Warning "ShareX source directory not found at: $shareXSourceDir" } else { # Ensure the destination directory exists if (-not (Test-Path -Path $shareXDestDir)) { New-Item -Path $shareXDestDir -ItemType Directory -Force | Out-Null Write-Host "Created ShareX directory at: $shareXDestDir" } # Delete Backup folder first if it exists if (Test-Path -Path $backupDir) { try { Remove-Item -Path $backupDir -Recurse -Force Write-Host "Removed ShareX Backup folder" } catch { Write-Warning "Failed to remove ShareX Backup folder: $_" } } # Copy ApplicationConfig.json $sourceAppConfig = Join-Path -Path $shareXSourceDir -ChildPath "ApplicationConfig.json" $destAppConfig = Join-Path -Path $shareXDestDir -ChildPath "ApplicationConfig.json" if (Test-Path -Path $sourceAppConfig) { Copy-Item -Path $sourceAppConfig -Destination $destAppConfig -Force Write-Host "Copied ApplicationConfig.json to $shareXDestDir" } else { Write-Warning "ApplicationConfig.json not found in source directory" } # Copy HotkeysConfig.json $sourceHotkeysConfig = Join-Path -Path $shareXSourceDir -ChildPath "HotkeysConfig.json" $destHotkeysConfig = Join-Path -Path $shareXDestDir -ChildPath "HotkeysConfig.json" if (Test-Path -Path $sourceHotkeysConfig) { Copy-Item -Path $sourceHotkeysConfig -Destination $destHotkeysConfig -Force Write-Host "Copied HotkeysConfig.json to $shareXDestDir" } else { Write-Warning "HotkeysConfig.json not found in source directory" } } # Restart ShareX if it was running if ($shareXProcess -and (Test-Path -Path $shareXExePath)) { Write-Host "Restarting ShareX with silent flag..." Start-Process -FilePath $shareXExePath -ArgumentList "-s" } elseif ($shareXProcess) { Write-Warning "Could not restart ShareX: Executable not found at $shareXExePath" } # XMouseButtonControl - Replace configuration files Write-Host "Configuring XMouseButtonControl..." # Define the source and destination paths $xmbcSourceDir = ".\XMouseButtonControl" $xmbcDestDir = "$env:APPDATA\Highresolution Enterprises\XMouseButtonControl" # Ensure the destination directory exists if (-not (Test-Path -Path $xmbcDestDir)) { New-Item -Path $xmbcDestDir -ItemType Directory -Force | Out-Null Write-Host "Created XMouseButtonControl directory at: $xmbcDestDir" } # Copy XMBCSettings.xml $sourceSettings = Join-Path -Path $xmbcSourceDir -ChildPath "XMBCSettings.xml" $destSettings = Join-Path -Path $xmbcDestDir -ChildPath "XMBCSettings.xml" if (Test-Path -Path $sourceSettings) { Copy-Item -Path $sourceSettings -Destination $destSettings -Force Write-Host "Copied XMBCSettings.xml to $xmbcDestDir" } else { Write-Warning "XMBCSettings.xml not found in source directory" } # Copy profile file $sourceProfile = Join-Path -Path $xmbcSourceDir -ChildPath "psymon's XMBC Settings.xmbcp" $destProfile = Join-Path -Path $xmbcDestDir -ChildPath "psymon's XMBC Settings.xmbcp" if (Test-Path -Path $sourceProfile) { Copy-Item -Path $sourceProfile -Destination $destProfile -Force Write-Host "Copied 'psymon's XMBC Settings.xmbcp' to $xmbcDestDir" } else { Write-Warning "psymon's XMBC Settings.xmbcp not found in source directory" } # Update Windows hosts file with entries to block license servers Write-Host "Updating Windows hosts file..." # Define the hosts file path $hostsFile = "$env:SystemRoot\System32\drivers\etc\hosts" # Define the input file path (relative to script location) $hostsInputFile = "$scriptDir\hosts.txt" # Check if the input file exists if (-not (Test-Path -Path $hostsInputFile)) { Write-Warning "hosts.txt file not found at $hostsInputFile" } else { try { # Read the current hosts file $hostsContent = Get-Content -Path $hostsFile -ErrorAction Stop # Read the hostnames to block from the input file $hostnamesToBlock = Get-Content -Path $hostsInputFile | Where-Object { $_ -and $_.Trim() -ne "" -and -not $_.Trim().StartsWith("#") } | ForEach-Object { $_.Trim() } # Create a backup of the original hosts file $backupFile = "$hostsFile.backup.$(Get-Date -Format 'yyyyMMdd-HHmmss')" Copy-Item -Path $hostsFile -Destination $backupFile -Force Write-Host "Created backup: $backupFile" # Track if any changes were made $changesMade = $false # Check each hostname and add if not already present foreach ($hostname in $hostnamesToBlock) { # Check if this hostname is already in the hosts file (case-insensitive) $existingEntry = $hostsContent | Where-Object { $_ -match "^\s*127\.0\.0\.1\s+$([regex]::Escape($hostname))\s*$" -or $_ -match "^\s*127\.0\.0\.1\s+.*\b$([regex]::Escape($hostname))\b" } if (-not $existingEntry) { # Add the entry $hostsContent += "127.0.0.1 $hostname" Write-Host "Added: $hostname" $changesMade = $true } else { Write-Host "Already exists: $hostname" -ForegroundColor DarkGray } } # Write the updated hosts file if changes were made if ($changesMade) { $hostsContent | Set-Content -Path $hostsFile -Encoding ASCII -Force Write-Host "Hosts file updated successfully with $($hostnamesToBlock.Count) entries processed" } else { Write-Host "No changes needed - all entries already exist in hosts file" } # Flush DNS cache to apply changes immediately Write-Host "Flushing DNS cache..." & ipconfig /flushdns | Out-Null Write-Host "DNS cache flushed" } catch { Write-Error "Failed to update hosts file: $_" Write-Host "Make sure the script is running with administrator privileges" -ForegroundColor Red } }