Skip to main content
3 of 6
edited tags; edited title
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Script which migrates files to secondary storage and symlinks them

I wrote this code to clean up some of the space on our file server. We've got 15 years of legacy data that nobody accesses or changes or cares about that we have to keep regardless. I'd rather have it not sitting on our main file server so that I don't have to add an additional TB to it annually. This script goes through the file structure, finds files that haven't been touched in 4 years and copies them to slower storage, then replaces the source file with a symlink.

I'm new to PowerShell, so any pointers regarding style or a better way to do things would be nice. I know that my way of bracing things is wrong and that closing curly braces should be indented one less level, but I don't care and find this easier to deal with.

# This script requires the PowerShell community exchange add on scripts to be installed.
# The script package can be installed by going here and downloading it: 
# http://pscx.codeplex.com/releases
#
# It also requires the New-Symlink script that was written by Boe Prox and is available
# for download here: http://gallery.technet.microsoft.com/scriptcenter/New-SymLink-60d2531e
# There is also an extremely informative blog post regarding the script available here:
# http://learn-powershell.net/2013/07/16/creating-a-symbolic-link-using-powershell/
#
# Everything else should be relatively easy to understand/customize for use outside of
# our environment. The code should work on anything above Win7/Server 2008. 

param(
    $Dir = "",
    $ArchiveDrive = "\\remote\path\to\archives\"+$dir[0]+"\"
    )

import-module PSCX
import-module New-SymLink.ps1

$SourceDrive = $dir[0] + ":\"
$date = Get-Date -Format yyyy-MM-dd
$ErrLog = "D:\ErrorLog $date.txt"
$DelLog = "D:\DelLog $date.txt"

function BuildLists($dir){
    $FileList = @()
    foreach ($item in (dir $dir -recurse)){
        if ( ((get-date).Subtract($item.LastWriteTime).Days-gt 1460) -eq $True) { 
            $FileList += $item
            }  
        }
    return $FileList
    }

function ArchiveFile($SourceFile){
    $DestFile = $SourceFile.fullname.replace($SourceDrive, $ArchiveDrive)
    $DestDir = $SourceFile.DirectoryName.replace($SourceDrive, $ArchiveDrive)
    mkdir -Path $DestDir 2>>$ErrLog
    copy $SourceFile.FullName $DestFile
    }
    
function HashCheckFile($SourceFile){
    $DestFile = $SourceFile.FullName.replace($SourceDrive, $ArchiveDrive)
    $SourceHash = get-hash($SourceFile.fullname)
    $DestHash = get-hash("$DestFile")
    return $SourceHash.HashString -eq $DestHash.HashString
    }
    
function DeleteFIle($File){
    rm $file.fullname 1>>$DelLog #-whatif
    }
    
function LinkFile($Sourcefile){
    $DestFile = $SourceFile.fullname.replace($SourceDrive, $ArchiveDrive)
    New-Symlink $SourceFile.fullname $DestFile 1>>$errlog #-whatif
    }
    
function ReplicateFile($file){
    if ($file.Attributes -eq "Directory"){continue}
    ArchiveFile($File)
    if (HashCheckFile($File)){
        DeleteFile($File)
        LinkFile($File)
        }
    }
    
function Archive($FileList){
    foreach ($File in $FileList){
        ReplicateFile($File)
        }
    }

function RunArchiving($dir){
    $FileList = BuildLists($dir)
    Archive($FileList)
    }
    
RunArchiving($dir)