541 lines
24 KiB
PowerShell
541 lines
24 KiB
PowerShell
# 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 that normalizes line endings
|
|
function Get-FileHashQuick($filePath) {
|
|
if (Test-Path $filePath -PathType Leaf) {
|
|
$fileExt = [System.IO.Path]::GetExtension($filePath).ToLower()
|
|
|
|
# List of text file extensions that might have line ending differences
|
|
$textExtensions = @(".ps1", ".txt", ".json", ".js", ".py", ".csv", ".md", ".ini", ".sh")
|
|
|
|
if ($textExtensions -contains $fileExt) {
|
|
# For text files, normalize line endings before computing hash
|
|
$content = Get-Content -Path $filePath -Raw
|
|
if ($content) {
|
|
# Normalize to LF
|
|
$normalizedContent = $content.Replace("`r`n", "`n")
|
|
$stream = [System.IO.MemoryStream]::new([System.Text.Encoding]::UTF8.GetBytes($normalizedContent))
|
|
return (Get-FileHash -InputStream $stream -Algorithm MD5).Hash
|
|
}
|
|
}
|
|
|
|
# For binary files or if normalization failed
|
|
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
|
|
|
|
$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
|
|
}
|
|
}
|