Scripting Games 2013 - Advanced Event 1 - An Archival Atrocity
Last week I was one of the lucky PowerShell Summit attendees and had the chance to assist to the official launch of the Scripting Games 2013 !! (with a special video created by Sean ;-)
Apart from the PowerShell stars like Ed Wilson, Don Jones, Bruce Payette, Alan Renouf, Lee Holmes, Richard Siddaway, Jeffery Snover…. I met some awesome people there and It was really cool to talk about our passion for PowerShell, How this amazing tool is saving our life each days! Scripting Games 2013 - Advanced Event #1 - An Archival Atrocity
For the first time, I decided this year to participate to the Scripting Games 2013 organize and hosted by the PowerShell.org team.
I chose the Advanced Track and here is the first script I submitted yesterday.
Feel free to comment and send me your critics.
Instruction
Download the instruction here (skydrive)
Dr.Scripto is in a tizzy! It seems that someone has allowed a series of application log files to pile up for around two years, and they're starting to put the pinch on free disk space on a server. Your job is to help get the old files off to a new location. Actually, this happened last week, too. You might as well create a tool to do the archiving. The current sets of log files are located in C:\Application\Log. There are three applications that write logs here, and each uses its own subfolder. For example: * C:\Application\Log\App1, * C:\Application\Log\OtherApp, * C:\Application\Log\ThisAppAlso. Within those subfolders, the filenames are random GUIDs with a .LOG filename extension. Once created on disk, the files are never touched again by the applications. Your goal is to grab all of the files older than 90 days and move them to \\NASServer\Archives - although that path will change from time to time. You need to maintain the subfolder structure, so that files from C:\Application\Log\App1 get moved to\\NASServer\Archives\App1, and so forth. Make those paths parameters, so that Dr.Scripto can just run this tool with whatever paths are appropriate at the time. The 90-day period should be a parameter too. You want to ensure that any errors that happen during the move are clearly displayed to whoever is running your command. If no errors occur, your command doesn't need to display any output - "no news is good news."
VOTE :-) Anybody can vote even if you do not participate to the Scripting Games
Annotations
-
Line 75 - Adding Support to Verbose/Debug…
-
Line 76 - Adding Support to WhatIf/Confirm parameters
-
Line 85 and 92 - Adding Validation to verify that the path specified by the user exist. I have to admit I could have gone a bit deeper on that :-/
-
Line 110 - Bad Bad Baaaaad… I used the back tick! I know… I should had use splatting instead… I’m learning!
-
Line 125 - Here I use a small shortcut to get the parent folder name for the current file (inside the foreach loop), then verify if this folder exist in the Archive destination folder at the line 131
Script
function Move-Log { <# .SYNOPSIS Move logs between two specified locations. .DESCRIPTION Move logs between two specified locations Optionaly, you can specify the age in day(s) of the file(s) that need be moved (default = 90) and their File Extention (default = *.log) If directories are present in the path, those will be re-created in the destination path. .PARAMETER Path Location path where the logs are located. Default value is current folder (.\) .PARAMETER Destination Location path where the logs will be moved. .PARAMETER Type Type of File Extention that need to be moved. Default value is *.log .PARAMETER OlderThan Age in Day(s) of the file(s) that need to be moved. Default value is 90. .EXAMPLE PS C:\> Move-Log -Path "c:\Applications" -Destination "\\Server\Share" This example shows how to call the Move-Log function with Path and Destination parameters to move old logs from the local directory C:\Applications to the remote share \\server\share. .EXAMPLE PS C:\> Move-Log -Path "c:\Applications" -Destination "x:\Backup\Apps\Archives" This example shows how to call the Move-Log function with Path and Destination parameters to move old logs from C:\Applications to x:\Backup\Apps\Archives .EXAMPLE PS C:\> Get-Location | Move-Log -Destination "\\Server\Share" This example shows how to call the Move-Log function with Path and Destination parameters, using the pipeline input for the Path parameter. .EXAMPLE PS C:\> "C:\Applications","D:\Applications" | Move-Log -Destination "\\Server\Share" This example shows how to call the Move-Log function with Path and Destination parameters, using the pipeline input for the Path parameter. .EXAMPLE PS C:\> Move-Log -Path "C:\Applications" -Destination "\\Server\Share" -OlderThan 90 -type *.log This example shows how to call the Move-Log function with Path, Destination, OlderThan and type parameters. This will move logs with the extention *.log older than 90 days from c:\Application to the remote share \\server\share. .INPUTS System.String .OUTPUTS None, only if Errors occure .NOTES NAME : Move-Log.ps1 AUTHOR : Francois-Xavier Cat TWITTER : @lazywinadmin WWW : lazywinadmin.com #> [CmdletBinding( SupportsShouldProcess=$true, ConfirmImpact="Medium")] param( [Parameter(Mandatory=$true, Position = 0, ValueFromPipeline=$true, HelpMessage="Enter the Path where your Application folders are located. Default is the current location")] [ValidateScript({Test-Path $_})] [alias("Source")] [System.String] $Path = ".\", [Parameter(Mandatory=$true, HelpMessage="Enter the Path where your logs will be moved")] [ValidateScript({Test-Path $_})] [string] $Destination, [Parameter(HelpMessage="Enter the file(s) extentions. Default value is `"*.log`"")] [string[]] $Type = "*.log", [Parameter(HelpMessage="Enter the age of the file(s) that need to be archive. Default value is 90 days")] [Int] $OlderThan = 90 ) PROCESS { try { # Get the Logs Write-Verbose "PROCESS - Looking for Logs older than $OlderThan days..." $Files= Get-ChildItem ` -Path $Path ` -include $Type ` -Recurse ` -File | Where-Object {$_.LastWriteTime -lt (get-date).AddDays(-$OlderThan) } # If Logs are found if ($Files){ foreach ($File in $Files){ Write-Verbose "PROCESS - Logs found!" # Get the Name of the Parent Folder $ParentFolder = Split-Path -Path (Split-Path $File -Parent) -Leaf # Build the Destination Path for the current $file $DestinationFolder = Join-Path -Path $Destination -ChildPath $ParentFolder # Verify this Folder Name exist in the Destination Path if (-not(Test-Path -Path $DestinationFolder)){ # Creating the Folder in the $destination if does not exist Write-Verbose -Message "PROCESS - Creating folder in the Destination path: $ParentFolder" New-Item -Name $ParentFolder -ItemType directory -Path $Destination | Out-Null }#if # Move the file Write-Verbose -Message "PROCESS - Moving $File to $DestinationFolder" Move-Item -Path $File.FullName -Destination $DestinationFolder -Force }#foreach ($file in $files) }#if($files) # If no old logs are found, do the following else{ Write-Verbose -Message "PROCESS - No Logs to move" }#else }#try catch { Throw "An Error occured during the PROCESS Block" }#catch }#Process }#function Move-Log ``` Thanks for reading! Feel free to contact me or leave me a comment below! Twitter: @lazywinadmin
Leave a comment