I wrote a PowerShell script that archives a user's files from two network locations to a NAS. It validates the source paths, uses Robocopy with retries and logging, stages the results, compresses them into a ZIP, and removes the staging folder only after compression succeeds. The archive is intended to avoid exposing real infrastructure names and includes the Robocopy log for auditing.
The problem is that some users have very large numbers of files and folders, so the process can take a long time. The current workflow copies everything to a staging directory, scans the directory to count files and folders, then reads the entire tree again while creating the ZIP. It also uses a fixed archive name that is replaced on each run.
The sources and archive are network paths, with the final destination located on a NAS. I need to preserve the important safeguards: Robocopy exit-code handling, retries, logging, validation before compression, protection against losing an existing archive, and cleanup only after a successful archive. What changes would make this more efficient, particularly for large user shares?
2 Answers
The main optimization is changing the workflow rather than tweaking PowerShell syntax. At the moment, the data is copied once to staging, scanned again for counts, and then read again to build the ZIP. Those extra passes are expensive over SMB and with large directory trees.
Consider copying directly to a timestamped archive folder on the NAS and keeping that folder as the archive. It is resumable, easier to inspect, and avoids creating one huge compression step. If a ZIP is mandatory, use a dedicated archiver such as 7-Zip, write to a temporary archive, validate it, and replace the final file only after validation succeeds.
Robocopy already provides useful statistics in its log, so the recursive Get-ChildItem counts can usually be removed. Also consider /MT:8 or /MT:16 for parallel copying, then adjust based on NAS performance. More threads are not always faster. Keep /XJ to prevent junctions from causing profile-related loops, and continue treating Robocopy exit codes below 8 as nonfatal results.
I would also avoid a fixed archive name when possible. A timestamped run directory makes retries safer and preserves previous runs if something goes wrong. If overwriting is required, copy or compress to a temporary path first, verify the result, and then rename it to the final path.
The biggest bottlenecks here are network I/O, the second full read required for compression, and the extra recursive scan. Robocopy itself is generally the right tool; reducing those additional passes should have a much larger impact.

Related Questions
How To: Running Codex CLI on Windows with Azure OpenAI
Set Wordpress Featured Image Using Javascript
How To Fix PHP Random Being The Same
Why no WebP Support with Wordpress
Replace Wordpress Cron With Linux Cron
Customize Yoast Canonical URL Programmatically