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.
- Overview
- Features
- Prerequisites
- Quick Start
- Configuration
- Example Use Cases
- Script Parameters
- Job Execution Methods
- Terminal User Interface
- Logging and Reporting
- Advanced Usage
- Troubleshooting
- Cross-Platform Notes
- Contributing
- 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
-LogFilePathand-ExecutablePathglobal parameters for consistent configuration - Simplified Excel output with
-ExcelFileNameparameter - 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
$BannerWidthandWrite-Centered, removed fragile unparenthesized repetition, and updated batch launchers to set console width to 120 columns for reliable TUI rendering.
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)
- 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
- 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
- ImportExcel PowerShell Module
- Install:
Install-Module ImportExcel -Scope CurrentUser - Used for Excel report generation
- Script will prompt to install if missing when run interactively
- 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
- Git (for version control and repository management)
- Task Scheduler (Windows) - for automated scheduling using included helper scripts
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.ps1Launch 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" -InteractiveIn interactive mode, you can:
- Select a single job:
3 - Select multiple jobs:
1,3,5 - Select a range:
2-5 - Run all jobs:
Aor press Enter - Quit:
Q
Execute only one named job (from PowerShell on Windows):
powershell -NoProfile -ExecutionPolicy Bypass -File .\EMCopyPasta.ps1 -ConfigFilePath "C:\EMCopy\config.json" -JobName "MyBackupJob"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
EMCopyPasta.ps1 intelligently handles paths to make deployment flexible:
- Relative Paths by Default: If
ExecutablePathorLogFilePathare not specified, the script uses paths relative to the script directory (.\emcopy64.exeand.\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
Jobs are defined in YAML (recommended) or JSON format. Each job object maps directly to EmCopyController class properties.
YAML is the recommended format because:
- No backslash escaping needed: Use
C:\Path\To\Fileinstead ofC:\\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: 32YAML 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: 5Minimal JSON Configuration:
[
{
"JobName": "MyBackup",
"Source": "\\\\SourceServer\\Share",
"Destination": "\\\\BackupServer\\Share",
"ThreadCount": 32
}
]Note: JSON requires double backslashes (\\) for Windows paths.
Full Configuration Examples:
- See config_example.yaml for comprehensive YAML examples (recommended)
- See config_example.json for comprehensive JSON examples
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: 32JSON 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.
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: 32JSON 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.
JobName(string): Unique identifier for the jobSource(string): Source path (UNC or local)Destination(string): Destination path (UNC or local)
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)
CopyOwner(bool): Copy file ownership (default: true)CopyAudit(bool): Copy audit settings (default: true)CopyDAC(bool): Copy discretionary access controlNoSec(bool): Skip security copying
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, orforceallDiskFullAction(enum): On disk full -abort,retry, orwaitWaitSeconds(int): Wait time between retries (default: 5)
The included config_example.json demonstrates 15 real-world scenarios:
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
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
Key Features: Copies ownership, audit settings, DAC, forced security Scenario: Domain controller SYSVOL replication or sensitive data migration
Use Case: Mirror synchronization that removes deleted files Key Features: Purge mode deletes destination files not in source
Use Case: Preview changes without executing copy Scenario: Testing configurations or auditing file differences
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)
Key Features: Compression applied to all files Scenario: Archival storage where space savings are prioritized
Scenario: Copying only top-level directory structures
Use Case: Preserve alternate data streams Key Features: Copies NTFS alternate data streams Scenario: Forensic copying or preserving extended file attributes
Use Case: Cross-domain file migration with security remapping Key Features: SID mapping file, domain specification Scenario: Migrating file servers between Active Directory domains
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
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
Use Case: Copy files without recursing subdirectories Key Features: Subdirectory inclusion disabled Scenario: Backing up only root-level files
| 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 |
Limit concurrency:
.\EMCopyPasta.ps1 -ConfigFilePath "config.yaml" -MaxConcurrentJobs 2 -MaxTotalThreads 128Custom 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 ScheduledDisable pre-job script:
.\EMCopyPasta.ps1 -ConfigFilePath "config.yaml" -PreJobScript {}The script supports three job ordering strategies:
Method: -JobExecutionMethod config
Behavior: Execute jobs in the order defined in the JSON configuration
Use Case: Manual control over execution order
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
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
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.
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
================================================================================
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
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
Each job generates a detailed log file:
- Location:
.\logs\{JobName}.logor.\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 encodingFullPathPrint: Display full paths in logs
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
- 🟢 Green: Successful jobs (Success = TRUE)
- 🔴 Red: Failed jobs (Success = FALSE)
- 🟠 Orange: Jobs with failed files (FilesFailed > 0)
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
When configured with a Teams webhook URL, the script sends adaptive card notifications:
- Job queue preview (first 10 jobs)
- Total job count
- Invocation type (Manual/Scheduled)
- Hostname
- Start timestamp
- Success/failure status with emoji
- Duration, files copied, transfer rate
- Directories created, files failed
- Warning for failed files
- Jobs remaining in queue
- Overall success/failure status
- Success rate percentage
- Total duration
- Clickable Excel report link (when SMB share configured)
- Summary statistics
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:
- Checks for existing SMB shares pointing to the logs directory
- If found: Uses the existing share and displays the SMB path
- 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 |
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 $customPreJobUse the included helper scripts to create Windows scheduled tasks:
.\Setup-EMCopyTask.ps1Or use the batch launcher:
Launch-SetupEMCopyTask.batGenerate 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"Test configurations without copying:
{
"JobName": "TestRun",
"Source": "\\\\SourceServer\\Share",
"Destination": "\\\\BackupServer\\Share",
"ListMode": true,
"ThreadCount": 4
}Error: The PowerShell module 'ImportExcel' is required
Solution:
Install-Module ImportExcel -Scope CurrentUser -ForceError: EMCOPY64.exe not found at path
Solutions:
- Place
emcopy64.exein the same directory as the script (default behavior) - Specify custom path in configuration using absolute or relative paths:
Or use a relative path:
{ "JobName": "MyJob", "ExecutablePath": "D:\\Tools\\EMCopy\\emcopy64.exe", "Source": "...", "Destination": "..." }{ "JobName": "MyJob", "ExecutablePath": ".\\tools\\emcopy64.exe", "Source": "...", "Destination": "..." }
Issue: The default PreJobScript may attempt privileged operations
Solutions:
- Run PowerShell as Administrator
- Modify or disable
PreJobScript:.\EMCopyPasta.ps1 -ConfigFilePath "config.json" -PreJobScript {}
Check:
- Thread limits: Ensure
MaxTotalThreadsis sufficient
.\EMCopyPasta.ps1 -MaxTotalThreads 512 -ConfigFilePath "config.json"- Job configuration: Verify Source and Destination paths exist
- Network connectivity: Test UNC path accessibility
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.
Enable detailed output:
$VerbosePreference = "Continue"
$DebugPreference = "Continue"
.\EMCopyPasta.ps1 -ConfigFilePath "config.json" -VerboseThis 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).
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)
Contributions are welcome! Please follow these guidelines:
- Provide PowerShell version (
$PSVersionTable) - Include error messages and stack traces
- Share relevant configuration (sanitize sensitive paths)
- Describe expected vs. actual behavior
- 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(andconfig_example.json) if adding new parameters
- Quick Testing: Use
-JobNameto test single jobs - Dry Runs: Enable
ListModein configuration - Private Configs: Store environment-specific configs outside the repository
- Mock Testing: Create mock EMCOPY scripts for cross-platform development
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.yamlThis 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.
Harrison Caldicott Email: harrison@itsfubar.com.au
-
1.1.1 (2025-12-10)
- Windows GUI File Picker: Added an optional Windows-only OpenFileDialog to pick a configuration file when
-ConfigFilePathis omitted. The dialog restricts selection to.json,.yml, and.yamlfiles. (GUI selection is not supported on macOS.)
- Windows GUI File Picker: Added an optional Windows-only OpenFileDialog to pick a configuration file when
-
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-yamlmodule with installation prompts
- YAML Configuration Support: Added native support for YAML configuration files (
-
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
- EMCopy Documentation - Official EMCopy documentation
- PowerShell Gallery - ImportExcel - Excel module used for reporting
- PowerShell GitHub - PowerShell releases
For questions, issues, or feature requests, please open an issue on the repository or contact the author directly.
Happy Copying! 🚀