File servers do not get cleaner on their own. When policy says “anything older than N years belongs in cold storage,” you need a repeatable way to find, prove, and move data—without guesswork. Archive Old Files is one PowerShell script for Windows PowerShell 5.1 (no extra runtimes, no agents): aim it at a source tree and an archive root, set the age threshold, and get a preview-by-default plan before a single file moves. When you commit, it mirrors folder layout, avoids overwrites, summarizes how much space leaves the source, and can emit a polished HTML report plus a per-run log—so you, your team, and auditors can see exactly what ran. If you maintain shares or compliance windows, this is the kind of tool you keep in the kit.
Manual cleanup does not scale: you miss folders, misread dates, and you cannot show your work. This script gives you a consistent, documented workflow:
.ps1 you can read, sign, and run under normal Windows tooling.Recursive scan from -InputPath. Every file is compared to a cutoff (now minus -Years). Choose what timestamp drives age: last modified (default), last opened (NTFS last access time), the newer of modified or last access (so a recent open keeps the file), plus created or older of created vs modified when copies have refreshed “modified” dates.
-Commit — Creates archive folders as needed, moves files, optional empty-folder cleanup under the source (never the source root).Settings can be saved to JSON next to the script for the next run; a run log records parameters and each file that met the age rule.
LastWriteTime (default), LastAccessTime (opened / access), LatestWriteOrAccess (newer of the two), CreationTime, Earliest; shortcuts A/B/C and names like Modified, Opened, ModifiedOrOpened.-Force enumeration)._2, _3, … not silent overwrites.-Output Text for a classic on-screen table.-NoRunLog / -NoSaveConfig — Turn off log append or JSON save when you need to.-All — Preview every published folder share on the server; never commits (moves disabled even if JSON or prompts say otherwise). One HTML report per share under ArchivePath; shares that contain the archive path are skipped.Recurse the source; probe permissions; list every file.
Keep files whose chosen timestamp is strictly older than the cutoff.
Archive path = archive root + path relative to input root.
Console summary; optional HTML. Add -Commit to move.
-Commit. Try preview on a narrow path first if you are validating policy.
Existing files at the destination are never overwritten; a new numbered name is chosen instead.
-InputPath — Root to scan (UNC or local).-ArchivePath — Archive root (must exist for preview; created on commit if missing).-Years — Threshold in years (decimals allowed, e.g. 7.5).-Commit — Perform moves.-Output Text or -Output HTML — Skip the end prompt.-AgeBasis LastAccessTime or LatestWriteOrAccess — Last-opened style rules (see NTFS last-access note in script output).-AgeBasis Earliest — When copies refreshed “modified” but content is old.-RemoveEmptyFolders Yes / No — After commit, prune empty dirs under source (not the root).-ConfigPath — Alternate JSON settings path.-SkipShareMenu — Disable share picker (automation / plain prompts).Safe preview (nothing moves):
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\Archive-OldFiles.ps1 `
-InputPath 'D:\Data' -ArchivePath '\\nas\archive' -Years 7
Commit, HTML report, no empty-folder prune prompt:
.\Archive-OldFiles.ps1 -InputPath 'D:\Data' -ArchivePath '\\nas\archive' -Years 7 `
-Commit -Output HTML -RemoveEmptyFolders No
All shares, preview only (run on the file server):
.\Archive-OldFiles.ps1 -All -ArchivePath 'D:\ArchiveReports' -Years 7
Full parameter documentation:
Get-Help .\Archive-OldFiles.ps1 -Full
When you do not pass all core paths on the command line, the script can list published disk shares on the machine so you can pick the source share or type a path. The archive defaults to the local path of the share named Archive (override with -ArchiveShareName). Use -SkipShareMenu for silent / scripted runs.
HTML (optional): self-contained page with a compact header (server, domain, paths, counts, reclaim size) and a table grouped by full folder path. Columns include file name, owner, the date used for the age rule (header matches -AgeBasis), and size. Failed rows are highlighted; hover file names for full paths and errors. Folders with more than twenty files start collapsed; hover the folder block to expand.
Run log (Archive-OldFiles.run.log next to the config file, unless -NoRunLog): each run appends parameters plus a tab-separated list of every file that met the age rule. -All runs add SHARE_BEGIN / SHARE_END sections per share.
Config JSON (Archive-OldFiles.config.json): saves last-used settings; includes AllShares when you last used -All.
Archive-OldFiles.ps1 (v1.7.2)
Save the script as Archive-OldFiles.ps1 (not .txt), then run from that folder.
Unblock-File -Path .\Archive-OldFiles.ps1powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\Archive-OldFiles.ps1 (add your parameters), or Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.ps1.txtInputPath is the tree that actually holds the files; check permissions and the on-screen scan counts.-All missing argument: Use script v1.7.1+ (download again). Use -All with no value, or on an old file -All:$true.Repository (script + README): https://github.com/hesseltined/ServerCleanUpTools