252 lines
12 KiB
PowerShell
252 lines
12 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 SSH directory from Nextcloud synchronized location if it exists
|
|
$sshSourceDir = "C:\Users\$uid\Nextcloud\Documents\Important_Docs\.ssh"
|
|
$sshDestDir = "C:\Users\$uid\.ssh"
|
|
if (Test-Path -Path $sshSourceDir) {
|
|
Copy-Item -Path $sshSourceDir -Destination $sshDestDir -Recurse -Force
|
|
Write-Host "Copied SSH directory from Nextcloud to: $sshDestDir"
|
|
} else {
|
|
Write-Host "Important_Docs/.ssh directory not found at: $sshSourceDir. Skipping SSH key copy." -ForegroundColor Yellow
|
|
}
|
|
|
|
python "$scriptDir\Python\NextcloudClientFix.py"
|
|
|
|
# Nextcloud - Copy sync-exclude.lst to AppData
|
|
Write-Host "Configuring Nextcloud sync exclusions..."
|
|
|
|
# Define the source and destination paths for sync-exclude.lst
|
|
$syncExcludeSource = "$scriptDir\sync-exclude.lst"
|
|
$nextcloudAppDataDir = "$env:APPDATA\Nextcloud"
|
|
$syncExcludeDestination = Join-Path -Path $nextcloudAppDataDir -ChildPath "sync-exclude.lst"
|
|
|
|
# Check if the source file exists
|
|
if (Test-Path -Path $syncExcludeSource) {
|
|
# Ensure the Nextcloud AppData directory exists
|
|
if (-not (Test-Path -Path $nextcloudAppDataDir)) {
|
|
try {
|
|
New-Item -Path $nextcloudAppDataDir -ItemType Directory -Force | Out-Null
|
|
Write-Host "Created Nextcloud directory at: $nextcloudAppDataDir"
|
|
} catch {
|
|
Write-Warning "Failed to create Nextcloud directory: $_"
|
|
}
|
|
}
|
|
|
|
# Copy the sync-exclude.lst file
|
|
try {
|
|
Copy-Item -Path $syncExcludeSource -Destination $syncExcludeDestination -Force
|
|
Write-Host "Copied sync-exclude.lst to $syncExcludeDestination"
|
|
} catch {
|
|
Write-Warning "Failed to copy sync-exclude.lst: $_"
|
|
}
|
|
} else {
|
|
Write-Warning "sync-exclude.lst not found at: $syncExcludeSource"
|
|
} |