Skip to content

hcaldicott/EMCopyPasta

Repository files navigation

EMCopy PowerShell Wrapper

Version: 1.1.3 — 2025-12-11

A comprehensive PowerShell wrapper for Dell's EMCOPY64.exe with parallel job execution, real-time Terminal User Interface (TUI), and automated Excel reporting.

You must be a registered Dell customer to download and use EMCOPY. Executables will not be shared here, but can be downloaded by registered users via Dell here.

Table of Contents


Changelog (most recent)

  • 1.1.3 (2025-12-11) — Teams Webhook Notifications & Centralized Logging:
    • Added Microsoft Teams adaptive card notifications with SMB share integration for Excel report links
    • Centralized all output (logs + Excel) to single configurable directory
    • Added -LogFilePath and -ExecutablePath global parameters for consistent configuration
    • Simplified Excel output with -ExcelFileName parameter
    • Added SMB share configuration wizard for Teams Excel report hyperlinks
    • Enhanced Teams cards with success/failure indicators and comprehensive metrics
  • 1.1.2 (2025-12-10) — TUI Banner & Launcher Improvements: Fixed banner rendering inconsistencies across hosts, standardized banner generation via $BannerWidth and Write-Centered, removed fragile unparenthesized repetition, and updated batch launchers to set console width to 120 columns for reliable TUI rendering.

Overview

EMCopyPasta.ps1 is a production-ready PowerShell script that wraps the EMCopy file copying utility with enterprise features:

  • Parallel Execution: Run multiple EMCopy jobs concurrently with configurable thread and concurrency limits
  • Real-time TUI Dashboard: Live status updates with animated indicators, progress bars, and color-coded job states
  • Intelligent Scheduling: Optimize job order based on historical runtime data
  • Comprehensive Logging: Per-job detailed logs and consolidated Excel reports with conditional formatting
  • Interactive Job Selection: Choose which jobs to run from a user-friendly terminal menu
  • Flexible Configuration: YAML or JSON-based configuration supporting all EMCopy parameters (YAML recommended for easier Windows path handling)

Features

  • Multi-threaded Job Execution: Control both concurrent jobs and total thread allocation across all jobs
  • Terminal User Interface (TUI): Real-time dashboard showing job status, progress, files copied, transfer rates, and elapsed time
  • Job Caching: Tracks historical runtime to enable optimal job scheduling
  • Excel Reporting: Automated Excel workbook generation with:
    • Color-coded success/failure indicators
    • Conditional formatting for failed file counts
    • Summary statistics and wall-clock duration
    • All reports saved to centralized .\logs\ directory
  • Teams Notifications: Microsoft Teams adaptive card alerts with:
    • Batch start/completion notifications
    • Per-job start/completion alerts
    • Clickable Excel report links via SMB shares
    • Success/failure status indicators
  • Centralized Logging: All logs and Excel reports stored in single .\logs\ directory
  • Interactive Mode: Terminal-based job selector with support for single jobs, ranges, or all jobs
  • Pre-Job Scripts: Execute custom PowerShell code before job execution (e.g., stopping services, cleanup tasks)
  • Dry-Run Support: List mode for previewing changes without copying files
  • Comprehensive Error Handling: Retry logic, logging, and detailed error reporting

Prerequisites

Required Components

  1. EMCOPY64.exe
  • Download directly via Dell here.
  • Default path: .\emcopy64.exe (relative to script directory)
  • Can be customized per-job in configuration with absolute or relative paths
  1. ImportExcel PowerShell Module
  • Install: Install-Module ImportExcel -Scope CurrentUser
  • Used for Excel report generation
  • Script will prompt to install if missing when run interactively
  1. powershell-yaml Module (Recommended)
  • Install: Install-Module powershell-yaml -Scope CurrentUser
  • Used for YAML configuration file support
  • Script will prompt to install if missing when run interactively
  • Not required if using JSON configuration files

Optional Components

  • Git (for version control and repository management)
  • Task Scheduler (Windows) - for automated scheduling using included helper scripts

Quick Start

Basic Usage

Run all jobs from a configuration file (from a Windows PowerShell prompt):

# Using YAML (recommended - no need to escape backslashes!)
powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1 -ConfigFilePath "C:\EMCopy\config.yaml"

# Or using JSON (requires double backslashes in paths)
powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1 -ConfigFilePath "C:\EMCopy\config.json"

If no config file is specified, the script will prompt you:

## Troubleshooting

### Common Issues

powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1

Interactive Job Selection

Launch the interactive job selector (from PowerShell on Windows):

# Using YAML
powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1 -ConfigFilePath "C:\EMCopy\config.yaml" -Interactive

# Or using JSON
powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1 -ConfigFilePath "C:\EMCopy\config.json" -Interactive

In interactive mode, you can:

  • Select a single job: 3
  • Select multiple jobs: 1,3,5
  • Select a range: 2-5
  • Run all jobs: A or press Enter
  • Quit: Q

Run a Specific Job

Execute only one named job (from PowerShell on Windows):

powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1 -ConfigFilePath "C:\EMCopy\config.json" -JobName "MyBackupJob"

Classic Progress Display

Use traditional progress bars instead of TUI (run from PowerShell on Windows):


### Optimal Job Scheduling

Run jobs in optimal order based on historical runtime (from PowerShell on Windows):

```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1 -ConfigFilePath "C:\EMCopy\config.json" -JobExecutionMethod optimal

Configuration

Path Handling

EMCopyPasta.ps1 intelligently handles paths to make deployment flexible:

  • Relative Paths by Default: If ExecutablePath or LogFilePath are not specified, the script uses paths relative to the script directory (.\emcopy64.exe and .\logs\)
  • Automatic Directory Creation: The logs directory is created automatically if it doesn't exist
  • Global Configuration: ExecutablePath and LogFilePath are global settings that apply to all jobs
  • Portable Deployment: Place the script, emcopy64.exe, and config files in the same folder and run from anywhere

Configuration File Format

Jobs are defined in YAML (recommended) or JSON format. Each job object maps directly to EmCopyController class properties.

YAML Format (Recommended)

YAML is the recommended format because:

  • No backslash escaping needed: Use C:\Path\To\File instead of C:\\Path\\To\\File
  • More readable: Cleaner syntax with better visual hierarchy
  • Comments supported: Add documentation directly in your config
  • Human-friendly: Easier to write and maintain

Minimal YAML Configuration:

# Simple backup job
- JobName: MyBackup
  Source: \\SourceServer\Share
  Destination: \\BackupServer\Share
  ThreadCount: 32

YAML with Multiple Jobs:

# Production backups
- JobName: DailyFileServer
  Source: \\FileServer\Data
  Destination: \\BackupNAS\Data
  ThreadCount: 64
  IncludeSubdirs: true
  CopyIfDifferent: true
  ExcludeDirs:
    - Temp
    - Cache
  ExcludeFiles:
    - '*.tmp'
    - '*.log'

# Database backup with verification
- JobName: DatabaseBackup
  Source: \\DBServer\SQLBackups
  Destination: \\SecureBackup\SQL
  ThreadCount: 16
  ContentMode: md5
  Retries: 5

JSON Format (Alternative)

Minimal JSON Configuration:

[
  {
    "JobName": "MyBackup",
    "Source": "\\\\SourceServer\\Share",
    "Destination": "\\\\BackupServer\\Share",
    "ThreadCount": 32
  }
]

Note: JSON requires double backslashes (\\) for Windows paths.

Full Configuration Examples:

Notification Configuration

If you want Teams adaptive-card alerts, supply a TeamsWebhookUrl alongside your job list. The value can live directly in your YAML or JSON configuration file, so you don't need to pass -TeamsWebhookUrl every time. Use the TeamsRunContext parameter (Manual, Scheduled, or Unknown) when invoking the script to annotate the cards with how the run was started.

YAML example with webhook metadata:

TeamsWebhookUrl: https://<tenant>.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/<workflow-id>/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=<your-signature>
Jobs:
  - JobName: MyBackup
    Source: \\SourceServer\Share
    Destination: \\BackupServer\Share
    ThreadCount: 32

JSON example with webhook metadata:

{
  "TeamsWebhookUrl": "https://<tenant>.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/<workflow-id>/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=<your-signature>",
  "Jobs": [
    {
      "JobName": "MyBackup",
      "Source": "\\\\SourceServer\\Share",
      "Destination": "\\\\BackupServer\\Share",
      "ThreadCount": 32
    }
  ]
}

If both the config file and CLI define TeamsWebhookUrl, the command-line value wins. Provide -TeamsRunContext Scheduled when the script runs from Task Scheduler so the cards reflect that invocation method.

Pre-job scripting via config

You can also bake the PreJobScript into your YAML/JSON metadata so that preparation steps (e.g., stopping services, cleaning temp files) run automatically before the EMCopy jobs start. The value is treated as PowerShell code and converted into a script block at runtime.

YAML example:

PreJobScript: |
  Write-Host 'Cleaning temp cache before copy...' -ForegroundColor Yellow
  Remove-Item 'C:\Temp\*' -Recurse -Force -ErrorAction SilentlyContinue
TeamsWebhookUrl: https://<tenant>.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/<workflow-id>/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=<your-signature>
Jobs:
  - JobName: MyBackup
    Source: \\SourceServer\Share
    Destination: \\BackupServer\Share
    ThreadCount: 32

JSON example:

{
  "PreJobScript": "Write-Host 'Cleanup before copy' -ForegroundColor Yellow\nStop-Service -Name 'Parity Agent' -Force -ErrorAction SilentlyContinue",
  "TeamsWebhookUrl": "https://<tenant>.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/<workflow-id>/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=<your-signature>",
  "Jobs": [
    {
      "JobName": "MyBackup",
      "Source": "\\\\SourceServer\\Share",
      "Destination": "\\\\BackupServer\\Share",
      "ThreadCount": 32
    }
  ]
}

The script block defined this way overrides the default pre-job script and runs automatically before any EMCopy job starts.

Key Configuration Parameters

Required Parameters

  • JobName (string): Unique identifier for the job
  • Source (string): Source path (UNC or local)
  • Destination (string): Destination path (UNC or local)

Common Parameters

  • ThreadCount (int): Number of threads for this job (default: 64)
  • IncludeSubdirs (bool): Copy subdirectories (default: true)
  • CopyIfDifferent (bool): Copy only if files differ (default: true)
  • LogFileName (string): Optional custom log filename (default: {JobName}.log, saved to global log directory)

Security Parameters

  • CopyOwner (bool): Copy file ownership (default: true)
  • CopyAudit (bool): Copy audit settings (default: true)
  • CopyDAC (bool): Copy discretionary access control
  • NoSec (bool): Skip security copying

Exclusion Parameters

  • ExcludeDirs (array): Directories to exclude (e.g., ["$Recycle.Bin", "Temp"])
  • ExcludeFiles (array): Files to exclude (e.g., ["*.tmp", "Thumbs.db"])
  • CompressionMode (enum): Compression - ignore, forcefile, forcedir, or forceall
  • DiskFullAction (enum): On disk full - abort, retry, or wait
  • WaitSeconds (int): Wait time between retries (default: 5)

Example Use Cases

The included config_example.json demonstrates 15 real-world scenarios:

1. Full Backup with All Options

Use Case: Comprehensive backup showing every available configuration parameter Key Features: All security settings, detailed logging, customizable behavior Scenario: Reference template for understanding all available options Key Features: Only required parameters (source, destination, threads) Scenario: Fast setup for straightforward file copies

3. High Thread Count

Use Case: High-performance backup optimized for speed Key Features: 128 threads, excludes development artifacts Scenario: Backing up large project directories while skipping node_modules, .git, bin, obj

Use Case: Critical data backup with integrity verification Key Features: MD5 checksum validation, increased retries Scenario: Database backups requiring guaranteed data integrity

5. Security Preservation

Key Features: Copies ownership, audit settings, DAC, forced security Scenario: Domain controller SYSVOL replication or sensitive data migration

6. Purge Old Files

Use Case: Mirror synchronization that removes deleted files Key Features: Purge mode deletes destination files not in source

7. List-Only Mode

Use Case: Preview changes without executing copy Scenario: Testing configurations or auditing file differences

8. Specific File Types

Use Case: Selective backup of certain file extensions Key Features: Name filters for specific formats Scenario: Media server backup targeting only video files (.mp4, .mkv, .avi)

9. Compression Enabled

Key Features: Compression applied to all files Scenario: Archival storage where space savings are prioritized

Scenario: Copying only top-level directory structures

11. Stream Copy

Use Case: Preserve alternate data streams Key Features: Copies NTFS alternate data streams Scenario: Forensic copying or preserving extended file attributes

12. Domain Migration

Use Case: Cross-domain file migration with security remapping Key Features: SID mapping file, domain specification Scenario: Migrating file servers between Active Directory domains

13. Disk Full Retry Handling

Use Case: Robust handling of storage limitations Key Features: Retry on disk full, extended wait times Scenario: Copying large files to storage with limited space

14. Custom Log Filename

Use Case: Custom log file naming Key Features: Custom log filename (all logs save to .\logs\ directory) Scenario: Standardized naming conventions or separate logs for different job types

15. Root-Level Only Copy

Use Case: Copy files without recursing subdirectories Key Features: Subdirectory inclusion disabled Scenario: Backing up only root-level files


Script Parameters

EMCopyPasta.ps1 Parameters

Parameter Type Default Description
ConfigFilePath string (prompt) Path to YAML or JSON configuration file
ExecutablePath string .\emcopy64.exe Path to EMCOPY64.exe executable (global setting)
LogFilePath string .\logs\ Directory for all log files and Excel reports (global setting)
JobName string (all jobs) Run only the specified job
Interactive switch false Launch interactive job selector
MaxConcurrentJobs int 4 Maximum concurrent job limit
MaxTotalThreads int 256 Maximum total threads across all jobs
JobExecutionMethod enum config Job ordering: config, shortest-first, or optimal
NoTUI switch false Disable TUI, use classic progress bars
ExcelFileName string EMCopyPasta_Summary.xlsx Excel report filename (saved to log directory)
ExcelWorksheet string Summary_<timestamp> Worksheet name in Excel file
PreJobScript scriptblock (see script) PowerShell code to run before jobs start
TeamsWebhookUrl string (none) Microsoft Teams webhook URL for notifications
TeamsRunContext enum Manual Run context: Manual, Scheduled, or Unknown

Parameter Examples

Limit concurrency:

.\EMCopyPasta.ps1 -ConfigFilePath "config.yaml" -MaxConcurrentJobs 2 -MaxTotalThreads 128

Custom Excel filename:

.\EMCopyPasta.ps1 -ConfigFilePath "config.yaml" -ExcelFileName "Monthly_Backup_$(Get-Date -Format 'yyyyMM').xlsx"

Teams notifications:

.\EMCopyPasta.ps1 -ConfigFilePath "config.yaml" -TeamsWebhookUrl "https://..." -TeamsRunContext Scheduled

Disable pre-job script:

.\EMCopyPasta.ps1 -ConfigFilePath "config.yaml" -PreJobScript {}

Job Execution Methods

The script supports three job ordering strategies:

1. Config Order (Default)

Method: -JobExecutionMethod config Behavior: Execute jobs in the order defined in the JSON configuration Use Case: Manual control over execution order

2. Shortest First

Method: -JobExecutionMethod shortest-first Behavior: Start with fastest jobs based on historical runtime Use Case: Quickly complete simple jobs, finish with long-running tasks Requires: Cache file from previous runs

3. Optimal (Recommended)

Method: -JobExecutionMethod optimal Behavior: Start longest jobs first to maximize parallel efficiency Use Case: Minimize total wall-clock time for job sets Requires: Cache file from previous runs

Job Cache

Runtime data is stored in <ConfigBaseName>.emcopycache.json:

{
  "JobName1": {
    "ElapsedTimeSeconds": 1234,
    "LastRun": "2025-12-10T10:30:00Z"
  },
  "JobName2": {
    "ElapsedTimeSeconds": 567,
    "LastRun": "2025-12-10T10:30:00Z"
  }
}

The cache updates automatically after each run. The cache file uses the base name of your config file (without extension), so config.yaml and config.json share the same cache file config.emcopycache.json.


Terminal User Interface

TUI Dashboard Features

The real-time TUI displays:

  • Overall Progress Bar: Visual completion percentage with job count
  • Per-Job Status: Color-coded indicators
    • 🟢 Running (Green): Active jobs with animated spinner
    • 🔵 Completed (Cyan): Successfully finished
    • 🔴 Failed (Red): Encountered errors
    • Pending (Gray): Queued, waiting to start
  • Live Metrics:
    • Elapsed time (HH:mm or mm:ss format)
    • Files copied count
    • Bytes transferred
    • Transfer rate (KB/s, MB/s, GB/s)
    • Thread count
  • Refresh Rate: Updates every 500ms

TUI Screenshot Example

================================================================================
                          EMCopy Job Status Dashboard
================================================================================

  Overall Progress: [====================..................] 3/5 jobs (60.0%)

  Job Name                 Status     Elapsed  Files      Bytes Copied     Rate    Thrd
  --------------------------------------------------------------------------------
  BackupJob1               Completed  05m:23s  1,234      125.4 GB         450 MB/s  64
  BackupJob2               Running /  02m:15s  567        45.2 GB          310 MB/s  64
  BackupJob3               Completed  12m:45s  5,678      890.1 GB         120 MB/s  128
  BackupJob4               Pending    0s       0          0                0 KB/s    32
  BackupJob5               Failed     01m:10s  45         2.3 GB           35 MB/s   32

  --------------------------------------------------------------------------------
  Last Update: 2025-12-10 14:35:42

Logging and Reporting

Centralized Output Directory

All output files are stored in the .\logs\ directory (relative to script location):

logs/
├── Job1.log
├── Job2.log
├── custom_backup.log
└── EMCopy_Summary.xlsx

Benefits:

  • Single location for all logs and reports
  • Easy SMB sharing for Teams integration
  • Simplified backup and archival
  • Consistent organization

Per-Job Logs

Each job generates a detailed log file:

  • Location: .\logs\{JobName}.log or .\logs\{LogFileName} if custom name specified
  • Format: EMCOPY native output format
  • Options:
    • LogFileName: Optional custom filename (job parameter)
    • Tee: Display output to console (default: true)
    • AppendLog: Append to existing log (default: true)
    • UnicodeLog: Use Unicode encoding
    • FullPathPrint: Display full paths in logs

Excel Summary Report

Automatically generated after each run:

  • File: .\logs\{ExcelFileName} (default: EMCopy_Summary.xlsx)
  • Worksheet: Summary_yyyyMMdd_HHmmss (timestamped)
  • Contents:
    • Job name, source, destination
    • Start/finish times, duration
    • Files copied, recovered, failed
    • Bytes transferred, transfer rate
    • Success/failure status
    • Exit codes

Conditional Formatting

  • 🟢 Green: Successful jobs (Success = TRUE)
  • 🔴 Red: Failed jobs (Success = FALSE)
  • 🟠 Orange: Jobs with failed files (FilesFailed > 0)

Summary Row

The report includes a wall-clock duration calculation:

  • Measures total time from first job start to last job finish
  • Displayed in hours for capacity planning

Teams Notifications

When configured with a Teams webhook URL, the script sends adaptive card notifications:

Batch Start Alert

  • Job queue preview (first 10 jobs)
  • Total job count
  • Invocation type (Manual/Scheduled)
  • Hostname
  • Start timestamp

Job Completion Alert

  • Success/failure status with emoji
  • Duration, files copied, transfer rate
  • Directories created, files failed
  • Warning for failed files
  • Jobs remaining in queue

Batch Completion Alert

  • Overall success/failure status
  • Success rate percentage
  • Total duration
  • Clickable Excel report link (when SMB share configured)
  • Summary statistics

SMB Share Integration

For Teams Excel report links to work, configure an SMB share for the logs directory.

Automatic Setup:

When running interactively with Teams notifications enabled, you'll be prompted:

Teams notifications are enabled, but the logs folder is not shared on the network.
Sharing the logs folder allows Teams notifications to include direct links to Excel reports.

Logs directory: C:\path\to\logs

Would you like to create an SMB share for the logs directory? (Y/N)

If you choose Yes, you can:

  • Accept the default share name (EMCopyLogs) or specify a custom name
  • The script creates the share with read-only access for Everyone
  • The SMB path will be: \\COMPUTERNAME\ShareName

How It Works:

When a Teams webhook URL is configured, the script automatically:

  1. Checks for existing SMB shares pointing to the logs directory
  2. If found: Uses the existing share and displays the SMB path
  3. If not found: Prompts the user to create a new share (interactive mode only)

Once configured, the Batch Completion notification will include:

📊 Excel Report: [EMCopyPasta_Summary.xlsx](\\COMPUTERNAME\EMCopyLogs\EMCopyPasta_Summary.xlsx)

Click the link above to open the detailed report

Users can click the link directly in Teams to open the Excel report from the network share.

Manual Configuration:

If you prefer to create the SMB share manually:

# Create share manually
New-SmbShare -Name "EMCopyLogs" `
    -Path "C:\path\to\logs" `
    -ReadAccess "Everyone" `
    -Description "EMCopy logs and reports"

The script will automatically detect the existing share on the next run.

Requirements:

  • Windows SMB/CIFS file sharing must be enabled
  • Administrator privileges may be required to create SMB shares
  • The share is created with read-only permissions for security
  • Network users must have access to the computer's file shares

Security Considerations:

  • The share is created with read-only access
  • Only the logs directory is shared, not the entire script directory
  • Consider restricting permissions to specific users/groups if needed:
# Example: Grant access to specific users only
New-SmbShare -Name "EMCopyLogs" `
    -Path "C:\path\to\logs" `
    -ReadAccess "DOMAIN\BackupAdmins" `
    -Description "EMCopy logs and reports"

Scheduled Tasks:

When running as a scheduled task (non-interactive), the script will:

  • Detect existing SMB shares automatically
  • Skip the interactive prompt if no share exists
  • Continue running normally without Excel report links in Teams notifications

Troubleshooting:

Issue Solution
"Access Denied" when creating share Run PowerShell as Administrator; Ensure SMB services are running: Get-Service -Name LanmanServer
Share not detected Verify the share path matches exactly: Get-SmbShare | Format-Table Name, Path
Links don't work in Teams Ensure network users can access \\COMPUTERNAME\ShareName; Test the UNC path manually; Check Windows Firewall settings for File and Printer Sharing

Advanced Usage

Custom Pre-Job Script

Define custom actions before job execution:

$customPreJob = {
    Write-Host "Stopping backup service..." -ForegroundColor Yellow
    Stop-Service -Name "MyBackupService" -ErrorAction SilentlyContinue

    Write-Host "Cleaning temporary files..." -ForegroundColor Yellow
    Remove-Item "C:\Temp\BackupCache\*" -Recurse -Force -ErrorAction SilentlyContinue

    Write-Host "Mounting network share..." -ForegroundColor Yellow
    net use Z: \\BackupServer\Share /user:domain\serviceaccount
}

.\EMCopyPasta.ps1 -ConfigFilePath "config.json" -PreJobScript $customPreJob

Scheduled Task Setup

Use the included helper scripts to create Windows scheduled tasks:

.\Setup-EMCopyTask.ps1

Or use the batch launcher:

Launch-SetupEMCopyTask.bat

Programmatic Job Creation

Generate configurations dynamically:

$jobs = @(
    @{
        JobName = "DailyBackup_$(Get-Date -Format 'yyyyMMdd')"
        Source = "\\FileServer\Data"
        Destination = "\\BackupNAS\Data"
        ThreadCount = 64
        ExcludeDirs = @("Temp", "Cache")
    },
    @{
        JobName = "WeeklyArchive"
        Source = "\\FileServer\Archive"
        Destination = "\\TapeLibrary\Archive"
        ThreadCount = 32
        CompressionMode = "forceall"
    }
)

$jobs | ConvertTo-Json | Set-Content "generated_config.json"

Dry-Run Testing

Test configurations without copying:

{
  "JobName": "TestRun",
  "Source": "\\\\SourceServer\\Share",
  "Destination": "\\\\BackupServer\\Share",
  "ListMode": true,
  "ThreadCount": 4
}

Troubleshooting

Common Issues

ImportExcel Module Missing

Error: The PowerShell module 'ImportExcel' is required

Solution:

Install-Module ImportExcel -Scope CurrentUser -Force

EMCOPY64.exe Not Found

Error: EMCOPY64.exe not found at path

Solutions:

  1. Place emcopy64.exe in the same directory as the script (default behavior)
  2. Specify custom path in configuration using absolute or relative paths:
    {
      "JobName": "MyJob",
      "ExecutablePath": "D:\\Tools\\EMCopy\\emcopy64.exe",
      "Source": "...",
      "Destination": "..."
    }
    Or use a relative path:
    {
      "JobName": "MyJob",
      "ExecutablePath": ".\\tools\\emcopy64.exe",
      "Source": "...",
      "Destination": "..."
    }

Permission Denied Errors

Issue: The default PreJobScript may attempt privileged operations

Solutions:

  • Run PowerShell as Administrator
  • Modify or disable PreJobScript:
    .\EMCopyPasta.ps1 -ConfigFilePath "config.json" -PreJobScript {}

Jobs Not Starting

Check:

  1. Thread limits: Ensure MaxTotalThreads is sufficient
.\EMCopyPasta.ps1 -MaxTotalThreads 512 -ConfigFilePath "config.json"
  1. Job configuration: Verify Source and Destination paths exist
  2. Network connectivity: Test UNC path accessibility

Parse Errors in Output

Issue: Statistics not appearing in Excel report

Solution: The script uses regex patterns to parse EMCOPY output. If EMCOPY version differs, update patterns in the # Parse Copy engine Statistics section of EMCopyPasta.ps1.

Debug Mode

Enable detailed output:

$VerbosePreference = "Continue"
$DebugPreference = "Continue"
.\EMCopyPasta.ps1 -ConfigFilePath "config.json" -Verbose

Platform Support

This project and EMCOPY64.exe are intended to run on Windows hosts. The script builds and validates arguments and configuration on any platform that runs PowerShell, but the EMCOPY engine (EMCOPY64.exe) is a Windows-native executable and must be run on Windows (or within a Windows VM/container).


File Structure

EMCopy/
├── EMCopyPasta.ps1                    # Main script with EmCopyController class
├── EMCopyPastaSchedule.ps1            # GUI for scheduled task creation
├── config_example.yaml                # Comprehensive YAML example (recommended)
├── config_example.json                # Comprehensive JSON example (legacy)
├── Launch-EMCopyPasta.bat             # Windows batch launcher
├── Launch-EMCopyPastaSchedule.bat     # Scheduled task setup launcher
├── emcopy64.exe                       # EMCopy executable (Windows binary)
├── README.md                          # This file
├── LOGFILEPATH_CONFIGURATION.md       # LogFilePath configuration guide
└── .gitignore                         # Git ignore rules (excludes config files)

Contributing

Contributions are welcome! Please follow these guidelines:

Reporting Issues

  • Provide PowerShell version ($PSVersionTable)
  • Include error messages and stack traces
  • Share relevant configuration (sanitize sensitive paths)
  • Describe expected vs. actual behavior

Submitting Pull Requests

  • Focus changes on specific features/fixes
  • Update documentation for new parameters
  • Test on Windows with actual EMCOPY64.exe
  • Follow existing code style and naming conventions
  • Update config_example.yaml (and config_example.json) if adding new parameters

Development Tips

  • Quick Testing: Use -JobName to test single jobs
  • Dry Runs: Enable ListMode in configuration
  • Private Configs: Store environment-specific configs outside the repository
  • Mock Testing: Create mock EMCOPY scripts for cross-platform development

Repository Notes

.gitignore Configuration

The repository .gitignore excludes config files (.json, .yaml, .yml) except example files (config_example.json and config_example.yaml). This prevents accidental commits of environment-specific configurations that may contain:

  • Internal network paths
  • Server names
  • Credential references

To track additional configs: Edit .gitignore and add exceptions:

# Track specific config
!production_config.yaml

License

This repository does not currently include a license file. If you plan to distribute or publish this code, consider adding an appropriate license (MIT, Apache 2.0, GPL, etc.) to clarify usage terms.


Author

Harrison Caldicott Email: harrison@itsfubar.com.au


Version History

  • 1.1.1 (2025-12-10)

    • Windows GUI File Picker: Added an optional Windows-only OpenFileDialog to pick a configuration file when -ConfigFilePath is omitted. The dialog restricts selection to .json, .yml, and .yaml files. (GUI selection is not supported on macOS.)
  • 1.1.0 (2025-12-10)

    • YAML Configuration Support: Added native support for YAML configuration files (.yaml, .yml)
    • Improved Path Handling: YAML eliminates the need for double-backslash escaping in Windows paths
    • Backward Compatible: Existing JSON configurations continue to work without changes
    • Auto-Detection: Script automatically detects and loads YAML or JSON based on file extension
    • Enhanced GUI: Updated scheduled task setup GUI to support both YAML and JSON file selection
    • Documentation: Added comprehensive YAML examples and migration guidance
    • Module Support: Added optional powershell-yaml module with installation prompts
  • 1.0.0 (2025-12-01)

    • Initial release
    • Terminal User Interface (TUI)
    • Parallel job execution with thread management
    • Interactive job selection
    • Excel reporting with conditional formatting
    • Job caching and optimal scheduling
    • Comprehensive JSON configuration support

Additional Resources


Support

For questions, issues, or feature requests, please open an issue on the repository or contact the author directly.

Happy Copying! 🚀

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published