-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBackup-Folder.ps1
More file actions
66 lines (53 loc) · 1.9 KB
/
Copy pathBackup-Folder.ps1
File metadata and controls
66 lines (53 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#Requires -Version 5.1
<#
.SYNOPSIS
Copies a folder into <DestinationRoot>\yyyy_MM_dd.
.DESCRIPTION
PowerShell port of src/vbs/BackupFolder.vbs. Emits the DirectoryInfo of the
folder it created, so it composes with Remove-Item, Compress-Archive and the
rest of the pipeline.
.PARAMETER Path
Folder to back up.
.PARAMETER DestinationRoot
Folder that receives the dated snapshot folder. Created when missing.
.PARAMETER Retain
Keep only the newest N dated folders under DestinationRoot. 0 keeps all.
.EXAMPLE
.\Backup-Folder.ps1 -Path "$env:USERPROFILE\Downloads" -DestinationRoot D:\backup -Retain 30
#>
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[ValidateScript({ Test-Path -LiteralPath $_ -PathType Container })]
[string]$Path,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$DestinationRoot,
[ValidateRange(0, 3650)]
[int]$Retain = 0
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
if (-not (Test-Path -LiteralPath $DestinationRoot)) {
New-Item -Path $DestinationRoot -ItemType Directory -Force | Out-Null
}
$stamp = Get-Date -Format 'yyyy_MM_dd'
$target = Join-Path -Path $DestinationRoot -ChildPath $stamp
if ($PSCmdlet.ShouldProcess($target, "copy $Path into")) {
if (-not (Test-Path -LiteralPath $target)) {
New-Item -Path $target -ItemType Directory | Out-Null
}
Copy-Item -LiteralPath $Path -Destination $target -Recurse -Force
}
if ($Retain -gt 0) {
Get-ChildItem -LiteralPath $DestinationRoot -Directory |
Where-Object { $_.Name -match '^\d{4}_\d{2}_\d{2}$' } |
Sort-Object Name -Descending |
Select-Object -Skip $Retain |
ForEach-Object {
if ($PSCmdlet.ShouldProcess($_.FullName, 'remove expired backup')) {
Remove-Item -LiteralPath $_.FullName -Recurse -Force
}
}
}
Get-Item -LiteralPath $target