woensdag 10 april 2013

Windows 2008: PowerShell File Archiving script

I wrote a powershell script which archives files not accessed within a period of days, it first determines which files meet the criteria, then it moves the file to the archive location leaving a shortcut in the original location. Very user-friendly :)


Usage is:

<SCRIPT NAME>.ps1 -source <target-dir> -days <not accessed days>

For example if we want to archive a directory called Software and all the files that are not accessed for one year would make:

./archive_folder.ps1 -source d:\software -day 365

There are 2 phases, an inventory phasa and an archive phase.

Here is a screenshot of Phase 1











In between you need to enter the location where the archived files needs to be placed.
Here is a screenshot of Phase 2

 
 
 
SCRIPT
 

#====================================================================#
#   SCRIPT:        ARCHIVE_LAST_ACCESSED.ps1                
#   FUNCTION:      Archive files not Accessed within last ... days  
#   OWNER:         Ravi Krishnasing                                 
#   CREATED:       10/04/2013                                        
#   MODIFIED:      10/04/2013                                       
#   VERSION:       v.1.0                                            
#====================================================================# 
#   CHANGELOG:                                                      
#                                                                   
#   v.1.0                                                           
#   - Script created;                                              
#                    
# NEEDS TO BE ADDED:            
# - Mail function             
#   - HTML report function           
#                                                                   
#====================================================================#

param(
    [Parameter(
        Mandatory = $true,
        Position = 0,
        HelpMessage = "Root of the folders or share to archive"
    )]
     [String] $source, 
    [Parameter(
        Mandatory = $true,
        Position = 1,
        HelpMessage = "Path of the folder or share of archive"
    )]

   [int] $days = 30
)
 $error_moving = 0

 function Get-DirectorySize() {
  param ([string]$root = $(resolve-path .))
  gci -re $root |
    ?{ -not $_.PSIsContainer } |
    measure-object -sum -property Length
}


 cls
 write-host "##           File Archive script v1.0           ##"
 write-host "# Target  : $source"

 write-host "# Not accessed in : $days days"
 write-host "# Inventory......"
 $total_source_size = (Get-DirectorySize "$source").Sum / 1GB
 Get-ChildItem $source -Recurse -ErrorAction silentlycontinue|  
        Where-Object {!$_.psiscontainer -and $_.extension -ne ".lnk"} |
        ForEach-Object {
        $totalfiles = $totalfiles + 1
 }
 Get-ChildItem $source -Recurse -ErrorAction silentlycontinue |  
        Where-Object {!$_.psiscontainer -and ((get-date) - $_.LastAccessTime).totaldays -gt $days -and $_.extension -ne ".lnk"} |
        ForEach-Object {
 Select-Object Length
 $filesizetotal = $filesizetotal + $_.Length
 $filesizeMB = $filesizetotal / 1GB
 $files = $files + 1
 Select-Object name

 cls
 write-host "##           File Archive script v1.0           ##"
 write-host "# Target Directory : $source"
 write-host "# Not accessed in : $days days"
 write-host "# Total in target : $totalfiles files"
 write-host "# Total size target(GB) : $total_source_size"
 write-host "# Total match  : $files files"

 write-host "# Current file  : $_"
 }
 write-host "##########################################################"
 write-host "# Total match : $files"
 write-host "# Total size : $filesizeMB GB"
 write-host "##########################################################"
 write-host "# USE UNC PATH with SHARE NAME when its need to be "
 write-host "# available to end users on your network.......... "
 $continue = read-host  "# Do you want to Archive? Type YES else NO "
  If($continue -eq "YES")
    {
        $arch_target = Read-Host "# To which location do you want to Archive?"
    # Object created for shortcut creation
 $wsh = new-object -comobject wscript.shell  
     # Get all the files from the source path, that are not shortcuts and older than the days set
   Get-ChildItem $source -Recurse -ErrorAction silentlycontinue |  
        Where-Object {!$_.psiscontainer -and ((get-date) - $_.lastaccesstime).totaldays -gt $days -and $_.extension -ne ".lnk" } |
            ForEach-Object {
  # For each file build the destination path 
                $dest = $_.fullname -replace ([regex]::escape($source)), $arch_target 
  # Check if the destination file path has the parent directory, if not create it
                $parent = split-path $dest 
                if(!(test-path $parent)){
                    [void] (new-item -Path (split-path $parent) -Name (split-path $parent -leaf) -ItemType directory -ErrorAction silentlycontinue)
                }
                 # Add file to file moved variable
                 $FileMoved = $FileMoved + 1
   cls
    write-host "##           File Archive script v1.0           ##"
    write-host "# Target  : $source"
                write-host "# Total match  : $files files"
    write-host "# Not accessed in : $days days"
                write-host "######################################################"
    write-host " Dest. Folder : $arch_target"
                write-host "  Moving file : $_ "
                
   write-host "  To  : $dest" 
                 write-host "Processing file : $FileMoved of $files"
                 Move-Item -Path $_.fullname -Destination $dest -ErrorAction silentlycontinue
  # If successful create shortcut
                if($?){
                    $shortCut = $wsh.CreateShortCut("$($_.fullname).lnk")    
                    $shortCut.TargetPath = $dest 
                    $shortCut.Save()
     $shortcuts_created = $shortcuts_created + 1
  }
     else {
     write-host "Error moving $_" -ForegroundColor red  
                        $error_moving = $error_moving + 1
                       $continue_error = Read-Host "# Do you want to continue? YES/NO"
       If ($continue_error -eq "NO")
        { return
    }               
                 }
  }
       
        write-host "# Total errors $errors of $files"
  write-host "$ There are $shortcuts_created shortcuts created!"
  write-host "#"
        write-host "# TILL NEXT TIME!!!!"
  write-host "##########################################################"
}


2 opmerkingen:

  1. Hello woensdag,
    Great script, it works perfectly.
    Do you know how to keep the original date stamp to the archived file?
    thanks

    BeantwoordenVerwijderen