Advertisement
J2897

Robocopy for Flash Drive Backup

Mar 28th, 2025 (edited)
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Path to CSV file
  2. $csvFile = "C:\Users\J2897\Code\PowerShell\DriveSync\DeviceMapping.csv"
  3.  
  4. # Function to perform device scan and output details
  5. function Scan-Devices {
  6.     try {
  7.         $devices = Import-Csv -Path $csvFile
  8.  
  9.         $pnpDevices = Get-WmiObject -Class Win32_PnPEntity | Where-Object { $_.DeviceID -like "USBSTOR*" }
  10.         $diskDrives = Get-WmiObject -Class Win32_DiskDrive | Where-Object { $_.PNPDeviceID -like "USBSTOR*" }
  11.  
  12.         Clear-Host
  13.         Write-Host "`n--- DEBUG OUTPUT ---"
  14.         Write-Host "Detected PnP Devices: $($pnpDevices.Count)"
  15.         Write-Host "Detected Disk Drives: $($diskDrives.Count)"
  16.         Write-Host "`n--- STARTING DEVICE SCAN ---"
  17.  
  18.         foreach ($device in $devices) {
  19.             $csvDeviceID = $device.DeviceID
  20.             $sourceDir = $device.SourceDirectory
  21.             $targetDir = $device.TargetDirectory
  22.  
  23.             Write-Host "`nDevice ID: $csvDeviceID"
  24.             Write-Host "  Source: $sourceDir"
  25.             Write-Host "  Target: $targetDir"
  26.  
  27.             $pnpDevice = $pnpDevices | Where-Object { $_.DeviceID -eq $csvDeviceID }
  28.             if (-not $pnpDevice) {
  29.                 Write-Host "  -> Device not found."
  30.                 continue
  31.             }
  32.  
  33.             $diskDrive = $diskDrives | Where-Object { $_.PNPDeviceID -eq $csvDeviceID }
  34.             if (-not $diskDrive) {
  35.                 Write-Host "  -> No disk drive found."
  36.                 continue
  37.             }
  38.  
  39.             Write-Host "  -> Found disk drive: $($diskDrive.DeviceID)"
  40.  
  41.             $partitions = $diskDrive.GetRelated("Win32_DiskPartition")
  42.             if (-not $partitions) {
  43.                 Write-Host "  -> No partitions found."
  44.                 continue
  45.             }
  46.  
  47.             $driveLetters = @()
  48.  
  49.             foreach ($partition in $partitions) {
  50.                 $logicalDisks = $partition.GetRelated("Win32_LogicalDisk")
  51.                 if ($logicalDisks) {
  52.                     foreach ($disk in $logicalDisks) {
  53.                         $driveLetters += $disk.DeviceID
  54.                         Write-Host "    -> Drive letter: $($disk.DeviceID)"
  55.                     }
  56.                 } else {
  57.                     Write-Host "    -> No logical disks found for partition $($partition.DeviceID)"
  58.                 }
  59.             }
  60.  
  61.             if ($driveLetters.Count -eq 0) {
  62.                 Write-Host "    -> No drive letter found"
  63.                 continue
  64.             }
  65.  
  66.             # Execute Robocopy properly with correct parameters
  67.             # Execute Robocopy properly with correct parameters
  68.             foreach ($letter in $driveLetters) {
  69.                 $sourcePath = "$letter\$sourceDir"
  70.  
  71.                 if (Test-Path $sourcePath) {
  72.                     Write-Host "    -> Syncing $sourcePath to $targetDir"
  73.  
  74.                     # Ensure the target directory exists before executing Robocopy
  75.                     if (-not (Test-Path $targetDir)) {
  76.                         Write-Host "    -> Target directory does not exist. Creating: $targetDir"
  77.                         New-Item -ItemType Directory -Path $targetDir -Force | Out-Null
  78.                     }
  79.  
  80.                     # Use Join-Path to prevent double backslashes in log path
  81.                     $logPath = Join-Path -Path $targetDir -ChildPath "RobocopyLog.txt"
  82.  
  83.                     # Normalize backslashes in paths to prevent issues
  84.                     $sourceQuoted = "`"$($sourcePath -replace '\\', '\\')`""
  85.                     $targetQuoted = "`"$($targetDir -replace '\\', '\\')`""
  86.                     $logQuoted = "`"$($logPath -replace '\\', '\\')`""
  87.  
  88.                     # Robocopy arguments with corrected log path
  89.                     $robocopyArgs = @(
  90.                         $sourceQuoted,
  91.                         $targetQuoted,
  92.                         "/E",                      # Copy all subdirectories, including empty ones
  93.                         "/COPY:DAT",               # Correct syntax for data, attributes, timestamps
  94.                         "/R:3",                    # Retry 3 times on failure
  95.                         "/W:5",                    # Wait 5 seconds between retries
  96.                         "/LOG+:$logQuoted",        # Append log output
  97.                         "/TEE"                     # Display output in console as well
  98.                     )
  99.  
  100.                     # Execute Robocopy properly using call operator '&'
  101.                     try {
  102.                         Write-Host "`n[EXECUTING]: Robocopy $($robocopyArgs -join ' ')"
  103.                         & "Robocopy" $robocopyArgs
  104.                     } catch {
  105.                         Write-Host "Failed to execute Robocopy: $_"
  106.                     }
  107.  
  108.                 } else {
  109.                     Write-Host "    -> Source directory not found: $sourcePath"
  110.                 }
  111.             }
  112.  
  113.         }
  114.     } catch {
  115.         Write-Host "An error occurred: $_"
  116.     }
  117. }
  118.  
  119. # Remove any existing event subscriptions with the same SourceIdentifier
  120. Get-EventSubscriber | Where-Object { $_.SourceIdentifier -eq "USBInserted" } | Unregister-Event
  121.  
  122. # Register WMI event for USB disk drive insertions
  123. Register-WmiEvent -Query "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_DiskDrive' AND TargetInstance.InterfaceType = 'USB'" `
  124.     -SourceIdentifier "USBInserted"
  125.  
  126. Write-Host "`nMonitoring for USB device insertions. Press Ctrl+C to exit."
  127.  
  128. # Use trap to handle Ctrl+C
  129. trap {
  130.     Write-Host "`n[INFO] Script interrupted by user."
  131.     break
  132. }
  133.  
  134. # Wait for events and process them synchronously
  135. try {
  136.     while ($true) {
  137.         $event = Wait-Event -SourceIdentifier "USBInserted"
  138.         Write-Host "`n[EVENT] USB device inserted."
  139.         Scan-Devices
  140.         Remove-Event -EventIdentifier $event.EventIdentifier
  141.     }
  142. } catch {
  143.     Write-Host "An error occurred: $_"
  144. } finally {
  145.     Write-Host "`n[INFO] Cleaning up and exiting..."
  146.     Unregister-Event -SourceIdentifier "USBInserted"
  147. }
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement