Skip to content

Instantly share code, notes, and snippets.

@JohnLBevan
Last active February 2, 2023 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohnLBevan/ac71613f778f5e6e21ea1291200005dd to your computer and use it in GitHub Desktop.
Save JohnLBevan/ac71613f778f5e6e21ea1291200005dd to your computer and use it in GitHub Desktop.
A powershell script to help in many scenarios where you need to get older files elsewhere; e.g. archive scenarios (though doesn't include compression) / cases where you have a fileshare with too many historic files to be workable
function Get-FilesInDirectory {
[CmdletBinding()]
Param (
[Parameter(Mandatory)]
[string]$Path
,
[Parameter(Mandatory)]
[string]$SearchPattern
,
[Parameter()]
[Switch]$Recursive
)
[System.IO.SearchOption]$SearchOption = @([System.IO.SearchOption]::TopDirectoryOnly,[System.IO.SearchOption]::AllDirectories)[[int]$Recursive.IsPresent]
# use enumerate so we get ienumerable instead of array / can start moving files as soon as we get results.
[string]$absPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) # use this instead of resolve-path so things work with UNC paths
[System.IO.Directory]::EnumerateFiles($absPath, $SearchPattern, $SearchOption)
}
Function Skip-RecentFiles {
[CmdletBinding()]
Param (
[Parameter(Mandatory, ValueFromPipeline)]
[System.IO.FileInfo]$InputObject
,
[Parameter()]
[int]$RecentDays = 90
)
Begin {
$Until = (Get-Date).AddDays(0-$RecentDays).ToUniversalTime()
}
Process {
if ($InputObject.CreationTimeUtc -lt $Until) {
$InputObject
}
}
}
Function ConvertTo-FolderStructure {
[CmdletBinding()]
Param (
[Parameter(Mandatory, ValueFromPipeline)]
[System.IO.FileInfo]$InputObject
,
[Parameter()]
[string]$ArchiveRootPath = '.'
,
[Parameter()]
[string]$ArchivePathFormat = '{0:yyyy/MM/dd}'
,
[Parameter()]
[string]$DatePropertyName = 'CreationTimeUtc'
,
[Parameter()]
[Switch]$PassThru
)
Begin {
$archiveRoot = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($ArchiveRootPath) #note: the archive path may not exist - this caters for that scenario
$previousArchivePath = $null # used as a minor optimisation to avoid the overhead of recreating folders if our last folder was the same
}
Process {
$itemArchivePath = Join-Path (Join-Path -Path $archiveRoot -ChildPath ($ArchivePathFormat -f ($InputObject | Select-Object -ExpandProperty $DatePropertyName))) -ChildPath ''
if ($itemArchivePath -ne $previousArchivePath) {
if (-Not (Test-Path -Path $itemArchivePath -PathType Container)) {
New-Item -Path $itemArchivePath -Type Directory -Force | Out-Null
}
$previousArchivePath = $itemArchivePath
}
if ($PassThru.IsPresent) {
([PSCustomObject]@{
Item = $InputObject
ItemArchivePath = $itemArchivePath
})
} else {
$itemArchivePath
}
}
}
Get-FilesInDirectory -Path 'c:\temp\' -SearchPattern *.* |
Skip-RecentFiles -RecentDays 600 |
ConvertTo-FolderStructure -ArchiveRootPath 'c:\temp\archivedemo' -PassThru |
ForEach-Object {Move-Item -Path $_.Item.FullName -Destination $_.ItemArchivePath}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment