Fragensteller
Powershell Dateien zu einem Ziparchiv zufügen

Allgemeine Diskussion
-
Hallo liebe Technetgemeinschaft, habe mein Problem bereits in einem anderen Forum gepostet, hier mal die Problematik:
Mein Script(erstellt eine Zip von Dateien, die in einem gewissen Intervall liegen) läuft noch nicht so richtig rund. Erstmaliges Durchlaufen des Scriptes erzeugt eine Zip und benennt diese um. Jetzt mein Problem: Verändere ich jetzt den Ausgangspfad(füge Dateien mit passendem Änderungsdatum hinzu), wird nochmal ein komplettes Zip-Archiv erstellt, welches dann in das bestehende Archiv integriert wird. Ohne Veränderung des Ausgangs, kann das Script beliebig oft durchlaufen werden, ohne das dem Archiv etwas zugefügt wird. Bei einem einmalig verändertem Ausgangspfad und mehrfachem Durchlaufen des Scriptes wird so oft wie das Script durchlaufen wird , die Suche mit in das Archiv integriert, obwohl keine neuen Dateien mit entsprechendem Datumsintervall zugefügt wurden.Wie lässt sich das jetzt beheben? Also, wie füge ich nur die neu dazu kommenden Dateien hinzu, ohne das die komplette Anfrage erneut gezipped und zugefügt wird? Und wieso wird wie oben beschrieben nach nur einmaliger Veränderung und mehrfachem Durchlaufen auch das nicht geupdatete gezipped und zugefügt?
Hier mal mein Ansatz:
#Powershell Community Extensions einlesen
Import-Module Pscx
#Variablen, die später als Parameter übergeben werden
$pfad = "c:\test"
$pfadausgabe ="c:\test\test.zip"
$datum1 = "08/01/2015"
$datum2 = "10/22/2015"
#Abbruch bei Fehler
$ErrorActionPreference = "stop"
#filtern nach gesuchten Dateien
$zwischenSpei = ls $pfad | Where-Object {$_.LastWriteTime -gt $datum1} | Where-Object {$_.LastWriteTime -lt $datum2}
#Zippen der gesuchten Dateien
Write-Zip $zwischenSpei -outputpath $pfadausgabe
#Namensgebung
$split = $datum1.Split("/")
$datum_name1 = $split[2] + "_" + $split[0] + "_" + $split[1]
$split = $datum2.Split("/")
[string]$datum_name2 = $split[2] + "_" + $split[0] + "_" + $split[1]
$newname = "c:\test\" + $datum_name1 + "-" + $datum_name2 + ".zip"
#existiert gesuchte Datei nicht
#gib der Zipdatei den Namen $newname
if(!(Test-Path -Path $newname))
{
Rename-Item $pfadausgabe $newname
}
#andernfalls Datei existiert
#prüfe nach Gleichheit
else
{
if(((Get-FileHash $pfadausgabe).hash) -eq ((Get-FileHash $newname).hash))
{
#bei Gleichheit lösche
rm $pfadausgabe
}
else
#bei Ungleichheit
{
# Asemblies laden (benötigt mindestens .NET 4.5 und Powershell 3.0)
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
#Dateien spezifizieren welche hinzugefügt werden sollen
$files = gci $pfadausgabe
$zip = [System.IO.Compression.ZipFile]::Open($newname,[System.IO.Compression.ZipArchiveMode]::Update)
$files | %{[void][System.IO.Compression.ZipfileExtensions]::CreateEntryFromFile($zip,$_.FullName,$_.Name)}
$zip.Dispose()
#an dieser Stelle die gezippten Daten löschen???
#rm $zwischenSpei
}
}
return 0- Typ geändert Teodora MilushevaModerator Montag, 16. November 2015 06:40 Die Threads die keine Aktivität haben, werden als Diskussion geändert. Das machen wir, um die Suche in dem Forum zu verbessern. Sie können den Typ jede Zeit ändern.
Alle Antworten
-
Hallo Ronny,
ich bin nicht so kompetent im PowerShell Scripting, aber vielleicht wirft den Artikel ein bisschen Licht auf die Sache:
Use PowerShell to Create ZIP Archive of Folder
Gruß,
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.
-
Viele Dank für die Antwort.
Hab in beschrieben Artikel leider nicht ganz die erhoffte Antwort gefunden. Es läuft ja, nur nicht so ganz wie es soll. Hab jetzt aber Dank des Links mal direkt Ed Wilson angeschrieben, wenn eine Antwort folgt, werde ich dies hier updaten.
mfg
-
Hallo Ronny,
schon weiter gekommen?
Gruß,
Teodora
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.
-
Hallo Ronny,
dein Skript ist recht umfangreich, deshalb fange ich einfach mal vorne an. Eventuell auch ohne eine insgesamt laufende Lösung zu haben.
Erstens: Dein Datum wird als String verglichen und nicht als Datumsobject. $_.LastWriteTime ist vom Typ Datetime, deine Datumswerte sind einfache Strings. Du musst sie mit
$datum1 = Get-Date "08/01/2015"
in Datumswerte umwandeln. Dann kannst du deine Dateinamen anstelle des Splits auch mit der ToString()-Methode bilden, etwa so:
$Datum1.ToString("dd.MM.yyyy")
Zweitens: Assemblys lädt man nicht in Schleifen! Das erzeugt zwar keine Fehler, schluckt aber unnötige Performance und ist schlechter lesbar. Alles mit Add-Type kommt ganz nach oben.
Drittens: In Skripten schreibt man am besten ganze Cmdlet-Namen und keine Aliase. Das kann keiner ordentlich lesen.
Viele Grüße
Christoph
- Bearbeitet hpotsirhc Freitag, 6. November 2015 12:42
-
Hallo Ronny,
Christoph hat Recht, das mit Datum hat so keine Aussicht auf Erfolg. Da Du das Datum als [String] und später als [DateTime] brauchst habe ich Dir die entsprechenden Variablen deklariert. Dann habe ich Dir noch die Datumsbegrenzung in eine Abfrage zusammengefasst. Zu Thema ZIP kann ich leider nicht wirklich etwas zielführendes beitragen.
Viel Erfolg
Uwe#Abbruch bei Fehler $ErrorActionPreference = "stop" $pfad = "c:\test" $Datum1Str = "2015_08_01" # Datum als String $Datum2Str = "2015_11_22" $Datum1DT = [DateTime]::ParseExact($Datum1Str, "yyyy_MM_dd", $null) # Datum als DateTime für Get-ChildItem $Datum2DT = [DateTime]::ParseExact($Datum2Str, "yyyy_MM_dd", $null) $pfadausgabe = "c:\test\test.zip" $newname = Join-Path -Path (Split-Path -Path $pfadausgabe -Parent) -ChildPath ("{0}-{1}.zip" -f $Datum1Str, $Datum2Str) #filtern nach gesuchten Dateien # $zwischenSpei = ls $pfad | Where-Object {$_.LastWriteTime -gt $datum1} | Where-Object {$_.LastWriteTime -lt $datum2} $zwischenSpei = Get-ChildItem -Path $pfad | Where-Object { ( ($_.LastWriteTime -gt $Datum1DT) -and ($_.LastWriteTime -le $Datum2DT) ) } # Oder doch rekursive Suche # $zwischenSpei = Get-ChildItem -Path $pfad -Recurse | Where-Object { ( ($_.LastWriteTime -gt $Datum1DT) -and ($_.LastWriteTime -le $Datum2DT) ) } #Zippen der gesuchten Dateien Write-Zip $zwischenSpei -outputpath $pfadausgabe #existiert gesuchte Datei nicht #gib der Zipdatei den Namen $newname if(!(Test-Path -Path $newname)) { Rename-Item -Path $pfadausgabe -NewName $newname -Force } else { #andernfalls Datei existiert #prüfe nach Gleichheit if(((Get-FileHash $pfadausgabe).hash) -eq ((Get-FileHash $newname).hash)) { #bei Gleichheit lösche Remove-Item -Path $pfadausgabe -Force } else { #bei Ungleichheit # Asemblies laden (benötigt mindestens .NET 4.5 und Powershell 3.0) Add-Type -AssemblyName System.IO.Compression Add-Type -AssemblyName System.IO.Compression.FileSystem #Dateien spezifizieren welche hinzugefügt werden sollen $files = Get-ChildItem $pfadausgabe $zip = [System.IO.Compression.ZipFile]::Open($newname,[System.IO.Compression.ZipArchiveMode]::Update) $files | %{[void][System.IO.Compression.ZipfileExtensions]::CreateEntryFromFile($zip,$_.FullName,$_.Name)} $zip.Dispose() #an dieser Stelle die gezippten Daten löschen??? #rm $zwischenSpei } } return 0
-
Erstmal vielen Dank für die zahlreichen Antworten. Die Problematik des ungleichen Datentypes ist meinem Kollegen auch schon aufgefallen, sprich wurde auch schon bemängelt. Werde mich gleich mal an die Umsetzung machen. Ed Wilson hat leider noch nicht geantwortet, sobald dort Nachricht kommt, wird sie hie hoch geladen.
mfg
Ronny
-
Nochmals danke an Teodora, Uwe und Christoph. Habe jetzt das Datum im DateTime Fomat übernommen, obwohl auch die String Variante in meinem Fall funktioniert hätte ( da das Ganze aber universell einsetztbar sein soll ist somit eine korrekte Datentyp-Angabe erforderlich). Habe jetzt die Lösung für mein eingangs gestelltes Problem. Es ist nicht die schönste Lösung, doch mit einer Löschfunktion am Ende ist das Updaten als solches möglich. Es wird nun kein zusätzlicher Zipcontainer erstellt der dann in den alten zugefügt wird.
Hier mal das Ergebnis:
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
$ErrorActionPreference = "stop"
$pfad = "c:\test\"
$Datum1Str = "2015_08_01" # Datum als String
$Datum2Str = "2015_10_23"
$filter = "*.txt"
$Datum1DT = [DateTime]::ParseExact($Datum1Str, "yyyy_MM_dd", $null) # Datum als DateTime für Get-ChildItem
$Datum2DT = [DateTime]::ParseExact($Datum2Str, "yyyy_MM_dd", $null)
Test-Path $newname
$pfadausgabe = "c:\test\test"
$newname = Join-Path -Path (Split-Path -Path $pfadausgabe -Parent) -ChildPath ("{0}-{1}.zip" -f $Datum1Str, $Datum2Str)
$zwischenSpei = Get-ChildItem -Path $pfad -Filter $filter | Where-Object { ( ($_.LastWriteTime -gt $Datum1DT) -and ($_.LastWriteTime -le $Datum2DT) ) }
Write-Host $zwischenSpei
Write-Host $newname
if (!(Test-Path $newname))
{
write-zip $zwischenSpei -outputpath $newname
}
if (Test-Path $newname)
{
$files = gci $pfadausgabe
$zip = [System.IO.Compression.ZipFile]::Open($newname,[System.IO.Compression.ZipArchiveMode]::Update)
$files | %{[void][System.IO.Compression.ZipfileExtensions]::CreateEntryFromFile($zip,$_.FullName,$_.Name)}
$zip.Dispose()
}
ls $pfad -Filter $filter | Where-Object {$_.LastWriteTime -gt $datum1} | Where-Object {$_.LastWriteTime -lt $datum2} | rm- Bearbeitet Ronny Schröter Montag, 9. November 2015 10:29
-
Kommando zurück!!!
War gerade am Testen und so ganz rund läuft es immer noch nicht!!! In das erstellte Ziparchiv wird jetzt kein neues Archiv geschrieben, was an sich schon ganz schön ist, allerdings werden jetzt, obwohl sich keine .txt Dateien im durchsuchten Verzeichnis befinden, bei jedem Scriptdurchlauf .txt-Dateien aus der Suchanfrage zugeschrieben, obwohl sie sich schon im Archiv befinden (nicht mehr im zu durchsuchenden Ordner). Ich dachte, dass dort ein Zusatz wie -unique für die zu zippenden Dateien sinnvoll wäre, weiß aber nicht an welcher Stelle der eingebaut werden müsste.
mfg
Ronny
P.s.
Oh Graus!!! Muss an irgendeiner Stelle der Speicher gelöscht werden? Hab das ganze mit .png Dateien getestet und trotz Neustart von ISE wurden auch vorher gefilterte .txt Dateien mit in die Zipdatei geschrieben. Hab in dem Script also "*.txt" gegen "*.png" ausgetauscht in der Hoffnung das nur .png files auftauchen, doch Fehlanzeige. Was mache ich falsch???
mfg
Ronny
- Bearbeitet Ronny Schröter Montag, 9. November 2015 14:49