Looking for a Archive/Backup script that accepts arguments called from the command line

rated by 0 users
This post has 10 Replies | 2 Followers

Top 25 Contributor
Posts 40
janfreiburghaus79 Posted: 12-28-2011 6:51 AM

The aim is a PowerShell script solution. This script is triggered by various means configured in a third party application.

The script will also clear time-controlled files or archive (hereafter used only archiving), which directories should never be deleted.
 

The file formats should be considered as flexible are passed as parameters. With multiple file formats can be accepted.
 

Reference and archive directory should be freely chosen.


The depth of the directories that should be considered to be freely chosen.

3.1 Time Control
An additional parameter is passed a value in the format <integer> with the unit [days]. "Hay-te" +} {DAY returns the date to be archived for up to date modified files.


The depth of the directories that should be considered to be freely chosen.

3.2 File format (s)
An additional parameter is a value in the fromat <string> = [*.* | *. txt, * log | | *. log | *. txt, etc.] passed to the script that determines which file formats to consider.

Several file formats Comma Separated passed. The case sensitivity of file extensions may not play a role. I.e. a file with the extension *. log is treated as a file with the extension *. log or *. log.

Thus fell in the choice of the value to pass to the upper and lower case.

3.3 recursivity
An additional parameter is a value in the format defined <integer> = [0 | 1 s | | ...], to consider how far into the directory structure of the script files.

With the value "0" only files from the directory reference is taken into account.

I.e. 0th = Reference level directory

3.4 Deletion / Archiving
An additional parameter is a value in the format given without units = <integer> the script [0 | 2 | 1].

Here, the values ​​should be interpreted as follows:
0: Delete the files
1: Archiving files without compression
2: Archiving files with compression

Principle must be created if no archive to archive any files.

3.4.1 0: Deleting the files
All relevant files are deleted from the reference list, and recursively definitely in the specified depth.

3.4.3 1: Archiving files without compression
All relevant files are copied along with the directory structure to an archive directory and deleted the reference list.

Here is the list of reference be extended to the archive directory with the prefix "ARCHIVE_" and then in date format "_yyyymmdd-hhmm".


example:
Reference directory ... = \ Logs \
Archive directory ... = \ Archive directory
Recursive = 1

The result:
- Lists of the second Level have been excluded
- Reference list was supplemented with prefix and date

3.4.4 1: Archiving files with compression
In contrast to the archive without compression should be in this case, the directory containing their files archived. What type of compression is used, is optional.

3.5 Reference Guide
An additional parameter is passed a value <string> fromat in the script. This string contains a complete blank signless path to the directory to be archived.
The directory must be both local (C: \ ...) and network paths (\ \ ...) are supported.


3.6 archive directory
An additional parameter is passed a value <string> fromat in the script. This string contains a complete blank signless path to the destination directory into which the archive should be created.
The directory must be both local (C: \ ...) and network paths (\ \ ...) are supported.


4th
Structure of the call

1 2 3 4 5 6 7
ArchiveScript.sc 2 -30 9 *. log, *. txt, *. xml C: \ BelVis \ Logs \ \ srv1 \ Archive

1: Name of script
2: Function
3: Time Control
4: recursivity
5: File format (s)
6: Reference Guide
7: Archive directory

Top 10 Contributor
Posts 421
Microsoft MVP
Top Contributor

Wow, that's a lot of information. Unfortunately, this isn't really a forum for analyzing business requirements and recommending a solution. Did you have a question about using PowerShell?

Top 25 Contributor
Posts 40

Thank you i understand.i come here with a example

This far i have a script like this:

 

This archive script  crabs all .log Files out of c:\Logs recursively. takes its path and replaces the drive's letter with "E".

And the end of the script it moves the .log files with the same directoryname to drive "E".

Get-ChildItem c:\Logs\A\B\*.log -recurse | Where-Object {!$_.PsISContainer} |
foreach{
$Ordner = Split-Path ($_.Fullname -replace '^.','E')
$Pfad = New-Item -Type Container -Path $Ordner -Force
$_ | Move-Item -Destination $Pfad -Force
}

My task is now to modify this script that it allows to be started from the command line passing arguments.

The user can decide weather or not it has to be recursevely or not an i should be able to pass the following arguments:

 

$age  (age of files in days "-30" to be moved)

$sourcedirectory

$destinationdirectory

Do I have to use this in order to pas args?

 

##### Test.ps1 #####
Param($User,
 $Path)
"User: $user"
"Path: $path"

at the end i have to zip the moved directory and files

 

 

 

 

Top 10 Contributor
Posts 421
Microsoft MVP
Top Contributor

Yes, a parameter block is the correct way to define parameters that you want passed in.

param([string]$path,[string]$targetPath,[switch]$recurse,[int]$age)

Something like that. As much as possible, try to use parameter names similar to those used by other PowerShell commands, for consistency.

Top 25 Contributor
Posts 40

thank you so much for your help Don i will give it a try ...

Top 25 Contributor
Posts 40

This ArchiveScript allows a user to specify age of Files ($Retentiondays), formats ($formats), he can specify the sourcepath ($ReferenDirectory) and the targetpath ($targetpath) and he can decide whether to delete, archive or archive and crompress (Write-Zip cmdlet Module) the selected ($found) files.

I get files recursevely to preserve subdirectories/path depth.


Now i have troubles to do a if(statement)

I want that the script  moves the entire path / files to a temporary directory only if the desired function is not 1

i want to shorten the script by using the if statement so that the fileselection  "$found = Get-ChildItem -path $ReferenceDirectory -include $formats -recurse | Where-Object {!$_.PsISContainer -and $_.LastWriteTime -lt $cutoffdate }" has only to be executed once.
But somehow it won't work.
The Files are moved even everytime even thoug it is not necessary for function 1 deletion.

Function = 1 #Delete
Function = 2 #Archive
Function = 3 #Archive and Compress


And if no files older than x-day are found there should be a warning "No files older than $RetentionDays day found!" and the script stops.

Furthermore i don't know how to terminate a session. Because i can only write to logs once.

Can somebody give me a hint?


--------------------------------------------------------------------------------------------------


#[int]$RetentionDays = $Null
#[string]$ReferenceDirectory =  $Null
#[string]$targetPath = $Null
#[array]$formats =$Null
#[single]$Function = $Null


param(
 [Parameter(Mandatory=$True,Position=1)]
[string]$ReferenceDirectory,
  [Parameter(Mandatory=$True,Position=2)]
 [int]$RetentionDays,
  [Parameter(Mandatory=$True,Position=3)]
[array]$formats,
  [Parameter(Mandatory=$True,Position=4)]
[ValidateRange(1,3)]
[single]$Function,
 [Parameter(Mandatory=$True,Position=5)]
  [string]$targetpath
)

#ErrorAction
#$ErrorActionPreference = "SilentlyContinue"

#Set Time
Set-Date -Date (Get-Date)
 
#FIXE Variables
$ArchivePrefix = "Archive_" #Präfix ArchiveDirectoryName
$date = Get-Date -format yyyyMMdd_HHmm  #Datumsformat für Zeitstempel ArchiveDirectoryName
$Level = 1 #Compression Level des ZIP-Files (je höher der Level desto grösser die Kompression/Je höher desto länger die Verarbeitungszeit)
$date2 = Get-Date -format yyyyMMdd_HHmmss #Datumsformat für temporärer Ordner
$cutoffdate = (Get-Date).AddDays(-$RetentionDays) #Cutoff Datum = Files mit Datum kleiner als Cutoff-Datum werden berücksichtigt

#Pfad auseinander nehmen => $ArchiveDirectoryName
$ArchiveFolder = Split-Path $ReferenceDirectory -Leaf  #Wird fürs Builden des ArchiveDirectoryName benötigt
$ArchiveDirectoryName =  $ArchivePrefix + $ArchiveFolder + "_" + $date
#zu kopierenedes ArchiveDirectory
$completeArchivePath = ($targetpath + $ArchiveDirectoryName)
#Temporärer Ordner mit Zeitstempel
$temp = Join-Path $targetpath -ChildPath ("temp" + "_" + $date2)

 

#Get files recursevely to preserve subdirectories/path depth
$found = Get-ChildItem -path $ReferenceDirectory -include $formats -recurse | Where-Object {!$_.PsISContainer -and $_.LastWriteTime -lt $cutoffdate }|
foreach{
$Folder = Split-Path ($_.Fullname -replace '^.:',$temp)
$Pfad = New-Item -Type Container -Path $Folder -Force
$_| Copy-Item -Container -Destination $Pfad -Recurse -Force

 

}

if ($function -gt 1 )

  {move-item $Folder -destination $completeArchivePath -force}

else
  {Remove-Item $_. -Recurse -force}
  
  
# Ordnergrösse für Berechnung freigegebener Speicherplatz (Vor Löschen/Archivieren) 
$before = (Get-ChildItem $ReferenceDirectory -recurse| Measure-Object Length -Sum).Sum

 switch ($Function) {
 
 1  {
  Get-ChildItem -Path $ReferenceDirectory -include $formats -Recurse |
     Where-Object {-not $_.PsIsContainer -and $_.LastWriteTime -lt $cutoffdate } |
     Remove-Item -Recurse -verbose -force
  #Log
  $Del_log = Dir -Recurse $completeArchivePath | out-File -Filepath  "$targetpath\del_log.log" -Encoding utf8  -Append -Force
  #$Del_log.close()
  Remove-Item -Recurse $temp -Verbose -force
  #Remove-Item  $completeArchivePath -Recurse -Verbose -Force
  #Calculate freed disc space
  Start-Sleep 5
  $after = (Get-ChildItem $ReferenceDirectory -recurse | Measure-Object Length -Sum).Sum
  'Freed {0:0.00} MB disk space' -f (($before-$after)/1MB)
  #Outputmessage if no files found
  if (($before-$after) -eq 0)
   {
   "No files older than $RetentionDays day found!"
   }
  }  

 2 {
  Copy-Item $found -Destination $targetpath -Force
  Remove-Item -Recurse $temp -Verbose -Force
  Get-ChildItem -Path $ReferenceDirectory -Include $formats -Recurse |
     Where-Object {-not $_.PsIsContainer -and $_.LastWriteTime -lt $cutoffdate } |
  Remove-item -recurse
  #Log der Archivierten Files
  $Archive_log = Dir  $completeArchivePath -Recurse  | out-File -Filepath "$targetpath\archive_log.log" -Encoding utf8 -Append  -Force 
  #Calculate freed disc space
  Start-Sleep 5
  $after = (Get-ChildItem $ReferenceDirectory -recurse | Measure-Object Length -Sum).Sum
  'Freed {0:0.00} MB disk space' -f (($before-$after)/1MB)
  #Outputmessage if no files found
  if (($before-$after) -eq 0)
   {
   "No files older than $RetentionDays day found!"

   }
  
  }

 3 {
  Import-Module pscx
  Write-Zip -Path $completeArchivePath -outputpath ("$completeArchivePath" + ".zip") -level $Level -Quiet
  #Log der Archivierten Files
  $Archive_comp_log = Dir -Recurse  $completeArchivePath | out-File -Filepath "$targetpath\archive_comp_log.log" -Encoding utf8  -Append -Force
  Remove-Item -Recurse $temp -Verbose -force
  Remove-Item -Recurse $completeArchivePath -Verbose -Force
  Get-ChildItem -path $ReferenceDirectory -include $formats -recurse |
  Where-Object {!$_.PsISContainer -and $_.LastWriteTime -lt $cutoffdate } |
  Remove-item -recurse
  #Calculate freed disc space
  Start-Sleep 5
  $after = (Get-ChildItem $ReferenceDirectory | Measure-Object Length -Sum).Sum
  'Freed {0:0.00} MB disk space' -f (($before-$after)/1MB)
  #Outputmessage if no files found
  if (($before-$after) -eq 0)
   {
   "No files older than $RetentionDays day found!"

   }
  }
  
 } 
 
$Error | Out-File $targetPath\error.log

 

Top 10 Contributor
Posts 421
Microsoft MVP
Top Contributor

That is a *lot* of code for me to go through, and I'm unfortunately working on an iPad for a couple of weeks so it's difficult. Can you narrow this down for me? Which specific bit isn't working, and what about it isn't working?

Top 25 Contributor
Posts 40

This if statement doesn't seem to work i have tried to put dem into brackets but none works

$function

 

 

= 2

#Get Files recurse an move them if Function equals 2 oder 3

[array]$found = Get-ChildItem -path d:\logs -include *.txt, *.log -recurse | 

    Where-Object {-not $_.PsISContainer -and $_.LastWriteTime -lt "11/24/2011" }

Get-ChildItem -path d:\logs -include *.txt, *.log  -recurse | 
    Where-Object {-not $_.PsISContainer -and $_.LastWriteTime -lt "11/24/2011" } |

    foreach {

        $Folder = Split-Path($_.Fullname -replace '^.:',$temp) 

        $Path = New-Item -Type Container -Path $Folder -Force $_ | Copy-Item -Container -Destination $Path-Force -Recurse

    }

#If Function is 1 do not move but remove the found files

if ($function -eq "2" -or $function -eq "3" ){

    move-item $Folder -destination d:\backup -force

} else {

    Remove-Item $_. -Recurse -force

}

Top 25 Contributor
Posts 40

move $folder doesn't work ether

Top 10 Contributor
Posts 421
Microsoft MVP
Top Contributor

So, $function doesn't equal "2," it equals 2. You've put an integer into it. if ($function -eq 2) should work. If that's not working, then it's because the content of $function is getting changed someplace. Try setting $DebugPreference='Continue' at the very top of your script, and then use Write-Debug to output the content of $function prior to testing it:

Write-Debug "function is $function"

As for the Move command not working, I'm not entirely sure I follow what your code is doing. It looks to me like $folder is being continually overwritten in your ForEach. Add some code to output $folder just prior to moving it - it's possible $folder doesn't contain what you think it does at that point, which is why the command is failing.

Write-Debug "Attempting to move $folder"

Note that Write-Debug will normally not produce output - setting $DebugPreference='Continue' activates it. You can also run your script with the -Debug parameter if you declare your parameter block with [CmdletBinding()], rather than setting $DebugPreference.

Unfortunately, the script is too complicated and too specific to your environment for me to run it on my system and debug it for you. But, the general approach to debugging is to get a handle on what's actually inside those variables. When something simple - like your If block - seems to not be working, the only real possibility is the variable not containing what you thought it did. It's a little difficult to walk you through an interactive process like debugging in a forum like this, but hopefully these tips can get you started.

Top 25 Contributor
Posts 40

Thank you for the tip. I will give it a try with the debugprefence variable.

 

Page 1 of 1 (11 items) | RSS
Concentrated Tech NSoftware Dell Compellent Sponsored by Idera and Concentrated Tech and NSoftware and Dell Compellent
Copyright 2011 PowerShell.com. All rights reserved.