2017-10-03 4 views
0

Ich versuche, ein Powershell-Skript zu entwickeln, mit dem ich alle Dateien archivieren kann, die älter als 2 Jahre sind und über ihre übergeordneten Verzeichnisse in einen neuen Stammordner kopieren. Ich möchte auch die ursprüngliche Datei und alle leeren Verzeichnisse löschen, nachdem die Archivierung abgeschlossen wurde.Copy-Item fehlgeschlagen mit -Destination Parameter definiert durch Skriptblock

Ich habe die unten Funktion, die mir erlauben sollte, den ersten Teil (Verschieben der Dateien und übergeordnete Verzeichnisse) zu tun im Moment von einem Testskript aufgerufen wird, und es wird mit dem Fehler Fehler:

Copy-Item : Der Parameter 'Destination' kann nicht ausgewertet werden, da sein Argument als Skriptblock angegeben ist und keine Eingabe erfolgt. Ein Skriptblock kann nicht ohne Eingabe ausgewertet werden. Bei C: \ Benutzer \ cfisher \ Dokumente \ WindowsPowerShell \ Module \ ShareMigration \ ShareMigration.psm1: 99 Zeichen: 43 + Kopieren-Item -Force -Destination { + ~ + CategoryInfo: MetadataError: (:) [Kopieren- Artikel], ParameterBindingException + FullyQualifiedErrorId: ScriptBlockArgumentNoInput, Microsoft.PowerShell.Commands.CopyItemCommand

Hier ist die Funktion:

Funktion ArchiveFiles { [CmdletBinding()]

Param (
    [Parameter(Mandatory=$True)][string]$SourceDirectory, 
    [Parameter(Mandatory=$True)][string]$DestinationDirectory, 
    [Parameter(Mandatory=$True)][ValidateSet('AddMinutes','AddHours','AddDays','AddMonths','AddYears')][string]$TimeUnit, 
    [Parameter(Mandatory=$True)][int]$TimeLength 
) 
Begin { 
    Write-Host "Archiving files..." -ForegroundColor Yellow -BackgroundColor DarkGreen 
} 
Process { 
    $Now = Get-Date 
    $LastWrite = $Now.$TimeUnit(-$TimeLength) 

    $Items = Get-ChildItem -Path $SourceDirectory -Recurse | where { $_.LastWriteTime -lt "$LastWrite" } 

    ForEach($Item in $Items) { 
     Copy-Item -Force -Destination { 
      If ($_.PSIsContainer) { 
       If (!(Test-Path -Path $_.Parent.FullName)) { 
        New-Item -Force -ItemType Directory -Path 
        (
         Join-Path $DestinationDirectory $_.Parent.FullName.Substring($SourceDirectory.length) 
        ) 
       } 
       Else { 
        Join-Path $DestinationDirectory $_.Parent.FullName.Substring($SourceDirectory.length) 
       } 
      } 
      Else { 
       Join-Path $DestinationDirectory $_.FullName.Substring($SourceDirectory.length) 
      } 
     } 
    } 
} 
End { 
    Write-Host "Archiving has finished." -ForegroundColor Yellow -BackgroundColor DarkGreen 
} 

}

Ich dachte, dass die Ergebnisse Passieren von Join-Path als Eingabe für den -Destination Parameter würde den Trick tun, aber es scheint nicht zusammen spielen werden. Muss ich neue Objekte für jeden Pfad oder etwas erstellen? Irgendwie neu zu Powershell, tut mir leid, wenn das schlampig aussieht. Ich schätze jede konstruktive Kritik und Lösung.

Danke!

+0

ich nie mit einem Skript Kopie Artikel tat. Warum verwenden Sie das Kopierelement nicht vor dem Join-Pfad-Befehl? – guiwhatsthat

+0

Das ist eine gute Idee. Lass es mich versuchen. –

+0

warum nicht einfach Robocopy verwenden? – ArcSet

Antwort

1

Sie könnten Robocopy verwenden, um zu erreichen, was Sie suchen.

Source : What to copy

Destination : Where to put copy

Days : How old should the last access time for file be before copy

RemoveOldFiles : Delete Files and folders from source that were copied over.

Robocopy eine Menge von verschiedenen Optionen, die Ihnen helfen könnte dies viel einfacher

In diesem Fall nehmen wir machen verwenden

/MINLAD : Get files older then Last Access Date

/e : Copy sub directories even empty ones

/mov : Move files instead of copying them

Function ArchiveFileSystem([string]$Source, [string]$Destination, [int]$Days, [switch]$RemoveOldFiles){ 
    $LastWrite = Get-date (Get-Date).AddDays(-$Days) -Format yyyyMMdd 
    robocopy $Source $Destination /MINLAD:$LastWrite /e (&{if($RemoveOldFiles -eq $true){'/mov'}}) 
} 
ArchiveFileSystem -Source C:\TestSource -Destination C:\TestDestination -Days 1 -RemoveOldFiles 
+0

Vielen Dank. Das ist ein viel einfacherer Ansatz als das, was ich versucht habe. Diese Lösung scheint gut für meine zu funktionieren Zweck, danke nochmal! –

Verwandte Themen