Skip to content

Instantly share code, notes, and snippets.

@zudsniper
Last active August 17, 2023 05:35
Show Gist options
  • Save zudsniper/31369714cb85afdc147734aa8b80097f to your computer and use it in GitHub Desktop.
Save zudsniper/31369714cb85afdc147734aa8b80097f to your computer and use it in GitHub Desktop.
⓽ 10ZIPPER.ps1 -> the final iteration of the (7+n)ZIPPER.ps1 saga, this will be used for data duplicate detection and archival onto an external drive for system recovery.
# 10ZIPPER.ps1
# v2.0.3
# -----------
#
# @zudsniper
# @openai
param(
[Parameter(Mandatory=$true)]
[Alias("s")]
[string[]]$source,
[Parameter(Mandatory=$true)]
[Alias("d", "dest")]
[string]$destination,
[switch]$ignoreOS,
[Alias("dbg")]
[switch]$debugMode
)
# Spinner setup
$spinner = '|','/','-','\'
$spinIndex = 0
# Check if script is running with administrative privileges
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdministrator = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdministrator) {
Write-Host "This script must be run as an Administrator. Please re-run the script as an Administrator." -ForegroundColor Red
exit
}
if ($debug) {
Write-Host "Script is running with administrative privileges." -ForegroundColor Green
}
# Check if 7zip is installed
$7zipPath = "C:\Program Files\7-Zip\7z.exe"
if (!(Test-Path $7zipPath)) {
Write-Host "7zip is not installed. Installing 7zip..." -ForegroundColor Yellow
# Download and install 7zip
$url64 = "https://www.7-zip.org/a/7z1900-x64.msi"
$url32 = "https://www.7-zip.org/a/7z1900.msi"
$output = "$env:TEMP\7zip.msi"
try {
Invoke-WebRequest -Uri $url64 -OutFile $output
Start-Process -FilePath $output -ArgumentList "/qn" -Wait
} catch {
Write-Host "Failed to install 64-bit 7zip. Trying to install 32-bit 7zip..." -ForegroundColor Yellow
Invoke-WebRequest -Uri $url32 -OutFile $output
Start-Process -FilePath $output -ArgumentList "/qn" -Wait
}
if (!(Test-Path $7zipPath)) {
Write-Host "Failed to install 7zip. Please install it manually and re-run the script." -ForegroundColor Red
exit
}
if ($debug) {
Write-Host "7zip installed successfully." -ForegroundColor Green
}
}
if ($debug) {
Write-Host "7zip is installed." -ForegroundColor Green
}
$timer = [Diagnostics.Stopwatch]::StartNew()
if ($debug) {
Write-Host "Starting script with source directories: $source and destination directory: $destination" -ForegroundColor Cyan
}
# Check if source and destination are external drives
$sourceDriveType = Get-WmiObject -Query "SELECT DriveType FROM Win32_LogicalDisk WHERE DeviceID = '$($source[0].Substring(0,2))'"
$destinationDriveType = Get-WmiObject -Query "SELECT DriveType FROM Win32_LogicalDisk WHERE DeviceID = '$($destination.Substring(0,2))'"
$compress = $sourceDriveType.DriveType -eq 2 -and $destinationDriveType.DriveType -eq 2
if ($compress) {
if ($debug) {
Write-Host "Source and destination are external drives. Files will be compressed before transfer." -ForegroundColor Cyan
}
}
# Create a log file for failed transfers
$failuresLog = Join-Path $destination "failures.log"
if (Test-Path $failuresLog) {
$i = 1
while (Test-Path (Join-Path $destination ("failures_" + $i + ".log"))) {
$i++
}
$failuresLog = Join-Path $destination ("failures_" + $i + ".log")
}
Add-Content -Path $failuresLog -Value ("Script started at: " + (Get-Date).ToString() + "`nOS: " + [System.Environment]::OSVersion.VersionString + "`n")
foreach ($srcDir in $source) {
if ($debug) {
Write-Host "`rProcessing source directory: $($spinner[$spinIndex % $spinner.Length]) $srcDir" -NoNewline
}
$files = Get-ChildItem -Path $srcDir -Recurse -ErrorAction SilentlyContinue | Where-Object {
if ($ignoreOS) {
$_.FullName -notmatch 'Windows|Program Files|Program Files (x86)'
} else {
$true
}
}
if ($debug) {
Write-Host "`rProcessing source directory: $($spinner[$spinIndex % $spinner.Length]) $srcDir - Done!" -ForegroundColor Green
}
$totalFiles = $files.Count
$processedFiles = 0
foreach ($file in $files) {
$dest = Join-Path $destination $file.FullName.Substring($srcDir.Length)
if (!(Test-Path $dest)) {
try {
if ($debug) {
Write-Host "`rCopying file: $($spinner[$spinIndex % $spinner.Length]) $file.FullName to destination: $dest" -NoNewline
}
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $dest) | Out-Null
if ($compress) {
# Compress file
& $7zipPath a -t7z "$file.7z" $file.FullName
robocopy "$file.7z" $dest /MT:16 /R:0 /W:0 /NP /ETA > $null
Remove-Item "$file.7z"
} else {
robocopy $file.FullName $dest /MT:16 /R:0 /W:0 /NP /ETA > $null
}
$processedFiles++
$elapsedTime = $timer.Elapsed.TotalSeconds
$averageTimePerFile = $elapsedTime / $processedFiles
$remainingFiles = $totalFiles - $processedFiles
$eta = (Get-Date).AddSeconds($averageTimePerFile * $remainingFiles)
Write-Progress -Activity "Copying files" -Status ("{0:N0} of {1:N0} files processed, ETA: {2}" -f $processedFiles, $totalFiles, $eta) -PercentComplete (($processedFiles / $totalFiles) * 100)
if ($debug) {
Write-Host "`rCopying file: $($spinner[$spinIndex % $spinner.Length]) $file.FullName to destination: $dest - Done!" -ForegroundColor Green
}
$spinIndex++
} catch {
Write-Host "Error copying file: $file.FullName to destination: $dest" -ForegroundColor Red
Write-Host "Error details: $_.Exception.Message" -ForegroundColor Red
Add-Content -Path $failuresLog -Value ("Failed to copy file: " + $file.FullName + " to destination: " + $dest + ". Error details: " + $_.Exception.Message)
}
} else {
if ($debug) {
Write-Host "File already exists in destination: $dest" -ForegroundColor Yellow
}
}
}
}
$timer.Stop()
Write-Host "Script completed in $($timer.Elapsed.ToString("hh\:mm\:ss"))" -ForegroundColor Green
# 10ZIPPER.ps1
# v1.8.0
# -----------
#
# @zudsniper
# @openai
param(
[Parameter(Mandatory=$true)]
[string[]]$source,
[Parameter(Mandatory=$true)]
[string]$destination,
[switch]$ignoreOS,
[switch]$debug
)
# Spinner setup
$spinner = '|','/','-','\'
$spinIndex = 0
# Check if script is running with administrative privileges
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdministrator = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdministrator) {
Write-Host "This script must be run as an Administrator. Please re-run the script as an Administrator." -ForegroundColor Red
exit
}
if ($debug) {
Write-Host "Script is running with administrative privileges." -ForegroundColor Green
}
# Check if 7zip is installed
$7zipPath = "C:\Program Files\7-Zip\7z.exe"
if (!(Test-Path $7zipPath)) {
Write-Host "7zip is not installed. Installing 7zip..." -ForegroundColor Yellow
# Download and install 7zip
$url64 = "https://www.7-zip.org/a/7z1900-x64.msi"
$url32 = "https://www.7-zip.org/a/7z1900.msi"
$output = "$env:TEMP\7zip.msi"
try {
Invoke-WebRequest -Uri $url64 -OutFile $output
Start-Process -FilePath $output -ArgumentList "/qn" -Wait
} catch {
Write-Host "Failed to install 64-bit 7zip. Trying to install 32-bit 7zip..." -ForegroundColor Yellow
Invoke-WebRequest -Uri $url32 -OutFile $output
Start-Process -FilePath $output -ArgumentList "/qn" -Wait
}
if (!(Test-Path $7zipPath)) {
Write-Host "Failed to install 7zip. Please install it manually and re-run the script." -ForegroundColor Red
exit
}
if ($debug) {
Write-Host "7zip installed successfully." -ForegroundColor Green
}
}
if ($debug) {
Write-Host "7zip is installed." -ForegroundColor Green
}
$timer = [Diagnostics.Stopwatch]::StartNew()
if ($debug) {
Write-Host "Starting script with source directories: $source and destination directory: $destination" -ForegroundColor Cyan
}
# Check if source and destination are external drives
$sourceDriveType = Get-WmiObject -Query "SELECT DriveType FROM Win32_LogicalDisk WHERE DeviceID = '$($source[0].Substring(0,2))'"
$destinationDriveType = Get-WmiObject -Query "SELECT DriveType FROM Win32_LogicalDisk WHERE DeviceID = '$($destination.Substring(0,2))'"
$compress = $sourceDriveType.DriveType -eq 2 -and $destinationDriveType.DriveType -eq 2
if ($compress) {
if ($debug) {
Write-Host "Source and destination are external drives. Files will be compressed before transfer." -ForegroundColor Cyan
}
}
foreach ($srcDir in $source) {
if ($debug) {
Write-Host "`rProcessing source directory: $($spinner[$spinIndex % $spinner.Length]) $srcDir" -NoNewline
}
$files = Get-ChildItem -Path $srcDir -Recurse -ErrorAction SilentlyContinue | Where-Object {
if ($ignoreOS) {
$_.FullName -notmatch 'Windows|Program Files|Program Files (x86)'
} else {
$true
}
}
if ($debug) {
Write-Host "`rProcessing source directory: $($spinner[$spinIndex % $spinner.Length]) $srcDir - Done!" -ForegroundColor Green
}
$totalFiles = $files.Count
$processedFiles = 0
foreach ($file in $files) {
$dest = Join-Path $destination $file.FullName.Substring($srcDir.Length)
if (!(Test-Path $dest)) {
try {
if ($debug) {
Write-Host "`rCopying file: $($spinner[$spinIndex % $spinner.Length]) $file.FullName to destination: $dest" -NoNewline
}
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $dest) | Out-Null
if ($compress) {
# Compress file
& $7zipPath a -t7z "$file.7z" $file.FullName
robocopy "$file.7z" $dest /MT:16 /R:0 /W:0 > $null
Remove-Item "$file.7z"
} else {
robocopy $file.FullName $dest /MT:16 /R:0 /W:0 > $null
}
$processedFiles++
$elapsedTime = $timer.Elapsed.TotalSeconds
$averageTimePerFile = $elapsedTime / $processedFiles
$remainingFiles = $totalFiles - $processedFiles
$eta = (Get-Date).AddSeconds($averageTimePerFile * $remainingFiles)
Write-Progress -Activity "Copying files" -Status ("{0:N0} of {1:N0} files processed, ETA: {2}" -f $processedFiles, $totalFiles, $eta) -PercentComplete (($processedFiles / $totalFiles) * 100)
if ($debug) {
Write-Host "`rCopying file: $($spinner[$spinIndex % $spinner.Length]) $file.FullName to destination: $dest - Done!" -ForegroundColor Green
}
$spinIndex++
} catch {
Write-Host "Error copying file: $file.FullName to destination: $dest" -ForegroundColor Red
Write-Host "Error details: $_.Exception.Message" -ForegroundColor Red
}
} else {
if ($debug) {
Write-Host "File already exists at destination: $dest" -ForegroundColor Yellow
}
}
}
}
$timer.Stop()
Write-Host "Total elapsed time: $($timer.Elapsed.TotalSeconds) seconds" -ForegroundColor Cyan
# 9ZIPPER.ps1
# v1.2.0
# -----------
#
# @zudsniper
# Define the source directories
$srcDirs = @("G:\\", "C:\\", "G:\\OneDrive")
$temp = "E:\\Temp\\MyTempFolder" # Change this to the path of your external SSD
$logFile = "{0}.log" -f [int][double]::Parse((Get-Date (Get-Date).ToUniversalTime() -UFormat %s))
$summaryFile = "{0}.summary.8zip.md" -f [int][double]::Parse((Get-Date (Get-Date).ToUniversalTime() -UFormat %s))
# Create the temporary directory if it doesn't exist
if (!(Test-Path $temp)) { New-Item -ItemType Directory -Force -Path $temp }
# Define counters and hashtables
$errorCount = 0
$duplicateCount = 0
$filetypeSizes = @{}
$totalSize = 0
$processedSize = 0
$lastCopiedFiles = New-Object System.Collections.Queue
# Start time
$startTime = Get-Date
Write-Host "Starting file copy process..." -ForegroundColor Green
# Copy files from the source directories to the temporary directory
foreach ($srcDir in $srcDirs) {
$files = Get-ChildItem -Path $srcDir -Recurse
$totalFiles = $files.Count
$processedFiles = 0
foreach ($file in $files) {
$dest = Join-Path $temp $file.FullName.Substring($srcDir.Length)
if (!(Test-Path $dest)) {
try {
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $dest) | Out-Null
robocopy $file.FullName $dest /MT:16 /R:0 /W:0
$totalSize += $file.Length
$processedSize += $file.Length
if ($lastCopiedFiles.Count -eq 15) {
$lastCopiedFiles.Dequeue()
}
$lastCopiedFiles.Enqueue($file.FullName)
} catch {
$errorCount++
Add-Content -Path $logFile -Value ("Error copying {0} to {1}: {2}" -f $file.FullName, $dest, $_.Exception.Message)
}
} else {
$duplicateCount++
}
$processedFiles++
$elapsedTime = (Get-Date) - $startTime
$averageTimePerFile = $elapsedTime.TotalSeconds / $processedFiles
$remainingFiles = $totalFiles - $processedFiles
$eta = (Get-Date).AddSeconds($averageTimePerFile * $remainingFiles)
Write-Progress -Activity "Copying files" -Status ("{0:N0} of {1:N0} files processed, ETA: {2}" -f $processedFiles, $totalFiles, $eta) -PercentComplete (($processedFiles / $totalFiles) * 100)
Write-Host ("Last 15 files copied: {0}" -f ($lastCopiedFiles -join ", "))
}
}
Write-Host "File copy process finished. Generating summary..." -ForegroundColor Green
# Generate summary
$endTime = Get-Date
$duration = $endTime - $startTime
Add-Content -Path $summaryFile -Value ("Start time: {0}" -f $startTime)
Add-Content -Path $summaryFile -Value ("End time: {0}" -f $endTime)
Add-Content -Path $summaryFile -Value ("Duration: {0}" -f $duration)
Add-Content -Path $summaryFile -Value ("Number of errors: {0:N0}" -f $errorCount)
Add-Content -Path $summaryFile -Value ("Number of duplicates: {0:N0}" -f $duplicateCount)
Add-Content -Path $summaryFile -Value ("Total size transferred: {0:N0}" -f $totalSize)
Write-Host "Summary generated. Process completed." -ForegroundColor Green
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment