This repository has been archived on 2024-09-20. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
powershell_backupscript/backup.ps1

224 lines
6.4 KiB
PowerShell

param (
[cmdletbinding()]
[string]$conf= "",
[switch]$debug = $false,
[switch]$log = $false
)
Set-StrictMode -Version 2
#$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
#$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
$net_default_letter = "S"
$global:logfile = $false
$tmp_path = "$PSScriptRoot\tmp"
$global:bin_path = "$PSScriptRoot\bin"
$ProgressPreference = "SilentlyContinue"
$ErrorActionPreference = "Stop"
$DebugPreference = "SilentlyContinue"
if ( $debug ) {
$DebugPreference = "Continue"
}
Import-Module -Name "$PSScriptRoot\lib\backupscript-global_utils.psm1" -Scope Global -Force
function json_to_hash () {
[CmdletBinding()]
Param(
[Parameter(
Mandatory=$True,
ValueFromPipeline=$True
)]
$json
)
Write-Debug "Call json_to_hash with $json"
$r = @{}
$json.psobject.properties | Foreach {
Write-Debug "Found value $_"
$r[$_.Name] = $_.Value
}
Write-debug "End json_to_hash"
return $r
}
function eval_var () {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]
$var
)
Write-Debug "$var Need to be evaluated"
$var = $ExecutionContext.InvokeCommand.ExpandString($var)
Write-Debug "Result $var"
return $var
}
if ( -not $conf ) {
$conf = "$PSScriptRoot\etc\backup.json"
Write-Debug "Configuration file not provided, use $conf"
}
if ( $log ) {
$logname = (Get-Item $conf ).Basename
$global:logfile = "$PSScriptRoot\log\$((Get-Date).ToString("yyyy.MM.dd"))_$($logname).log"
write-debug "Write to logfile: $($global:logfile) "
# Zip old messah=ges (Archives)
# TODO: Test this functionnality
if ( Test-Path "$($PSScriptRoot)/bin/7za.exe") {
$command = -join( $PSScriptRoot, "/bin/7za.exe", " u")
Write-Debug " Archive old loh file with $($command)"
# Select Set-Message file older than 15 days
Get-ChildItem "$($PSScriptRoot)\log\*$($logname).log" -Recurse -File | Where CreationTime -lt (Get-Date).AddDays(-15) | % {
# Put file in the right zip file by name
$execute = -join(
$command,
" `"",
$PSScriptRoot,
"\log\",
$logname,
".archives.",
($_.CreationTime).ToString("yyyy.MM"),
".log.7z`"",
" `"",
$_.FullName,
"`""
)
write-debug "Set-Message command archive: $($execute)"
try {
Invoke-Expression $execute | Out-Null
Remove-Item -Path $_.FullName
}
catch {
Set-Message "WARNING" "Can't zip $($_.Fullname) log files"
}
}
}
}
Write-Debug "Loaded script from $PSScriptRoot"
# Temporary directory creation / clean
if ( Test-Path $tmp_path ) {
Write-Debug "Remove file in $tmp_path"
Remove-Item -Path $tmp_path\* -recurse -Force
}
else {
Write-Debug "Create directory $tmp_path"
New-Item -ItemType Directory -Force -Path $tmp_path
}
# Parse JSON
try {
$backup = Get-Content $(Get-ChildItem $conf -).FullName -Raw | ConvertFrom-Json
}
catch {
Set-Error "Error While Loading JSON : $conf"
exit
}
Write-Debug "configuration $conf loaded successfully"
$backup.actions | % {
$destination = ""
$source = ""
Set-Message "---"
Set-Message "Process action : $($_.name) | type: $($_.type)"
Set-Message "---"
# Process source
if ( $_.psobject.properties.match('source_eval').Count -and $_.source_eval -eq $true ) {
$_.source = eval_var $($_.source)
Write-Debug "Result $($_.source)"
}
if ( $_.source -eq "{{tmpdir}}" ) {
Write-Debug "source is the temp directory"
$source = $tmp_path
}
elseif ( -not (Test-Path $_.source) -and $_.source ) {
Set-Message "Source path $($_.source) not found `n`n"
continue
}
else {
Write-Debug "Source is a regular directory"
$source = $_.source
}
# Test output path
if ( $_.dest -match "^\\.*$"){
Write-Debug "Destination is a network path"
if ( -not $_.username -or -not $_.pass ) {
Set-Error "you must specify a username and a password"
return
}
#Mount Network Drive
$cred = New-Object System.Management.Automation.PSCredential($_.username, ($_.pass | ConvertTo-SecureString))
try {
# get-psdrive
# Use Securestring to secure Password
# get secured password :
# ("Passw00rd" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString)
New-PSDrive -Credential $cred -Name $net_default_letter -Root $($_.dest) -PSProvider FileSystem -Persist -Scope Script -ErrorAction Stop | Out-Null
$destination = "$($net_default_letter):"
}
catch {
Set-Error "Can't mount the network share"
Write-Debug $error[0].Exception
return
}
}
elseif ( $_.dest -eq "{{tmpdir}}" ){
Write-Debug "Destination is the temporary folder ($tmp_path)"
$destination = $tmp_path
}
else {
Write-Debug "$($_.dest) seems to le a local path"
if ( Test-Path $_.dest ) {
$destination = $_.dest
}
else {
Set-Error "Destination '$($_.dest)' doest not exit"
return
}
}
Write-Debug "Begin backup of $($_.name)"
if ( $_.psobject.Properties.Name -contains "options") {
$opt = $_.options | json_to_hash
}
else{
$opt = $false
}
try {
Write-Debug "Import module $($_.type)"
Import-Module -Name "$PSScriptRoot\lib\backupscript-$($_.type).psm1"
Backup-Create -source $source -dest $destination -name $_.name -opt $opt
if ( $_.psobject.properties.match('hook_postexec').Count -and $_.hook_postexec -ne "" ) {
Set-Message "Postexec hook : execute $($_.hook_postexec)"
Invoke-Expression $_.hook_postexec
}
}
catch {
Set-Error $Error[0].FullyQualifiedErrorId
}
finally{
# Properly remove net drive if mounted
if ( Test-Path "$($net_default_letter):" ){
Remove-PSDrive -Name $net_default_letter
}
# Remove Module
Get-Module -Name "backupscript-$($_.type)" | Remove-Module -Force
}
}
Set-Message "Backup operation done"