Zum Inhalt wechseln


Foto

Codebeispiele + Erklärungen für foreach


  • Bitte melde dich an um zu Antworten
27 Antworten in diesem Thema

#16 Dukel

Dukel

    Board Veteran

  • 9.313 Beiträge

 

Geschrieben 15. März 2012 - 14:32

Dir fehlt ein "{" hinter dem if.

if(!(Test-Path $dstfile))[COLOR="Red"]{[/COLOR]


#17 schreckinger

schreckinger

    Junior Member

  • 73 Beiträge

 

Geschrieben 16. März 2012 - 08:12

Hallo danke für den Hinweiß mit {

das was ich jetzt noch habe ist ...

das Script läuft durch macht aber nix ?

#Quelle
$src = "C:\filetyp"
#Ziel
$dst = "\\fileserver01\filetyp"

#Schleife über Dateisystem.
foreach($file in (Get-ChildItem $src -Recurse -include *.txt,*.doc,*.ppt)){

	#Dateiname im Ziel
	$dstfile = $file.FullName.replace("$src","$dst")

	#Ordner im Ziel
	$dstfolder = $dstfile.split('\')[0..($dstfile.split('\').length-2)] -join '\'

	#Testen ob diese Datei NICHT existiert
	if(!(test-path $dstfile)){

		#Testen ob ein Ordner existiert
		if(!(test-path $dstfolder)){

			#Wenn er nicht existiert, dann an anlegen
			new-item $dstfolder -type directory -recurse

		}

		#Wenn die Datei nicht existiert von der Quelle kopieren
		copy-item $file.FullName $dstfolder
				
	}
}

Weiters möchte ich eine Abfrage einbauen die das Script mit protokoliert, was genau passiert ? Wie kann ich das am besten lösen.

Und nochmals ich kann mich nur bei euch bedanken das ihr euch Zeit nehmst.
Echt ein klasse Forum. ( Kennt man eigentlich nicht so aus der Windows Welt)

Na dann im diesem Sinne wünsche ich euch allen einen wünderschönen Guten Morgen :)

#18 schreckinger

schreckinger

    Junior Member

  • 73 Beiträge

 

Geschrieben 16. März 2012 - 08:21

So das Script läuft jetzt wunderbar :)

hab mich verguckt ...

so daher es noch weiter geht lasse ich den Thread noch offen :)

ich soll nun in das Vorhande Script eine Abfrage einbauen die folgendes kann:

Also wenn auf den Quell Laufwerk eine Datei Gleich ist am Ziel Laufwerk soll er abbrechen.
Sofrot raus.

Und dann soll ich noch in der Varaiable eine String definieren wo die Daten hinkopiert worden sind, wenn er nicht abbricht.

Wie gesagt daher mir das ganze noch neu ist bitte ich um Anregungen sowie Hilfe

Danke

Bearbeitet von schreckinger, 16. März 2012 - 08:55.


#19 Dukel

Dukel

    Board Veteran

  • 9.313 Beiträge

 

Geschrieben 16. März 2012 - 09:16

Soll er nicht alles was auf dem Share fehlt kopieren?

#20 schreckinger

schreckinger

    Junior Member

  • 73 Beiträge

 

Geschrieben 16. März 2012 - 09:35

Ja des schon, aber wenn eine Datei gleich ( besser gesagt wenn der Dateiname schon vorhanden ist) ist soll er abbrechen.
aber dann komplett raus.

Dass soll ich in einem Log mitschreiben wenn er abbricht.

Wenn aber keine Datei gleich sind soll das Script einfach alle Dateien Kopieren und dann in eine Variable in einem String speichern.
Im String soll der Pfad der kopierenden Datei stehen.

Die File brauche ich nur auf den Namen checken, der Inhalt ist nicht wichtig.

Danke nochmals

#21 schreckinger

schreckinger

    Junior Member

  • 73 Beiträge

 

Geschrieben 16. März 2012 - 09:37

Zusatz:

Das Programm wird dann nicht für *.txt genommen sondern für Datenbank-files.

#22 blub

blub

    Moderator

  • 7.605 Beiträge

 

Geschrieben 16. März 2012 - 09:42

Ja des schon, aber wenn eine Datei gleich ( besser gesagt wenn der Dateiname schon vorhanden ist) ist soll er abbrechen.
aber dann komplett raus.

Dass soll ich in einem Log mitschreiben wenn er abbricht.

Wenn aber keine Datei gleich sind soll das Script einfach alle Dateien Kopieren und dann in eine Variable in einem String speichern.
Im String soll der Pfad der kopierenden Datei stehen.

Die File brauche ich nur auf den Namen checken, der Inhalt ist nicht wichtig.


Dann zeig doch mal deinen Ansatz für diese Aufgabe. Wo genau hakt es?
blub

Ein Kluger bemerkt alles, Ein Dummer macht über alles eine Bemerkung. (Heinrich Heine)


#23 schreckinger

schreckinger

    Junior Member

  • 73 Beiträge

 

Geschrieben 16. März 2012 - 10:31

Hallo Blubb...

okay wo es hackt ;) leider zur Zeit noch an mehren Stellen.

#Quelle
$src = "C:\filetyp"
#Ziel
$dst = "\\fileserver01\filetyp"

#Schleife über Dateisystem.
$abc = foreach($file in (Get-ChildItem $src -Recurse -include *.txt,*.doc,*.ppt)){

	#Dateiname im Ziel
	$dstfile = $file.FullName.replace("$src","$dst")

	#Ordner im Ziel
	$dstfolder = $dstfile.split('\')[0..($dstfile.split('\').length-2)] -join '\'

	#Testen ob diese Datei NICHT existiert
	if(!(test-path $dstfile)){

		#Testen ob ein Ordner existiert
		if(!(test-path $dstfolder)){

			#Wenn er nicht existiert, dann an anlegen
			new-item $dstfolder -type directory -recurse

		}s

		#Wenn die Datei nicht existiert von der Quelle kopieren
		copy-item $file.FullName $dstfolder
				
	}
}

Start-Transaction -path "C:\Benutzer\lrzlboh\Desktop\transcript1.txt" -noclobber

#$abc | Select-String -path

Habe den Ansatz das ich mit Transaction vorgänge in einer Log Datei sichere, und mit die ganze Foreach Schleife in einer Variablen definiere damit ich dann $abc mit "Select-String" den Pfad auslesen kann ...
bin mir aber noch nicht im Klaren wie das genau Funktioniert..

Habe mir gerade das Buch PowerShell in Action zu gelegt also sollte es bald aufhörn mit der Fragerei, aber wie gesagt bin ich sehr dankbar für Hilfe oder einen Denk Anstoß.

#24 PowerShellAdmin

PowerShellAdmin

    Board Veteran

  • 1.136 Beiträge

 

Geschrieben 16. März 2012 - 11:06

für was willst du Transaktionen sichern ?

Wäre es nicht besser die wichtigen Ereignis einfach in das Log zu schreiben. Die Daten werden einfach angefügt (append)
z.B.

$event = "hier steht dein Fehler oder deine Info"

#Setzt das Datum (zum String formatiert) -kann man bei Bedarf auch in anderen Format ausgeben- und den String in das angegebene Log. 
(get-date).toString() + $event >> c:\log.log

Das was du beschreibst ist ja kein Log mehr :), eher ein Transaktionsprotokoll...

Bzgl. Zeitstempel kann ich eine Funktion empfehlen. Einfach oben im Skript einfügen und darunter ausführen. Der Zeitstempel ist ein valider SQLTimestamp (Powershell bietet die Formatierung leider nicht mit Boardmitteln an)
Ausgabe sieht so aus: 20120316 12:14:06
YYYYMMDD HH:MM:SS

Function timestamp
{
	$now=get-Date
	$yr=$now.Year.ToString()
	$mo=$now.Month.ToString()
	$dy=$now.Day.ToString()
	$hr=$now.Hour.ToString()
	$mi=$now.Minute.ToString()
	$se=$now.Second.ToString()
	if ($mo.length -lt 2) 
	{
		$mo="0"+$mo #pad single digit months with leading zero
	}
	if ($dy.length -lt 2) 
	{
		$dy="0"+$dy #pad single digit day with leading zero
	}
	if ($hr.length -lt 2) 
	{
		$hr="0"+$hr #pad single digit hour with leading zero
	}
	if ($mi.length -lt 2) 	
	{
		$mi="0"+$mi #pad single digit minute with leading zero
	}
	if ($se.length -lt 2)
	{
		$se="0"+$se #pad single digit minute with leading zero
	}
	write-output $yr$mo$dy" "$hr":"$mi":"$se
}

Wichtig: Der Funktionsaufruf im Skript muss immer unterhalb der Funktion folgen, dann könnte das Ganze auch wie folgt aussehen:

$event = "hier steht dein Fehler oder deine Info"

#Setzt das Datum (zum String formatiert) und den String in das angegebene Log. 
(timestamp)+ $event >> c:\log.log


#25 schreckinger

schreckinger

    Junior Member

  • 73 Beiträge

 

Geschrieben 16. März 2012 - 12:08

hallo

danke erstmal für die Erklärung.

Aber mir ist unklar wofür ich einen Zeitstempel funktion benötigte ?

Überprüft diese Function die Zeitstempel von Datein damit diese nicht daruüber kopiert werden ?

Kann ich das nicht lösen mit dem Operator -match in der schleife ?

Das mit log werde ich verwenden. Die Transaktionen brauche ich nicht zu sichern dachte mir nur das wird alles mit Protokliert was passiert.

Frage zum

$event = "hier steht dein Fehler oder deine Info"

#Setzt das Datum (zum String formatiert) -kann man bei Bedarf auch in anderen Format ausgeben- und den String in das angegebene Log. 
(get-date).toString() + $event >> c:\log.log

Brauche ja den Pfad der Datei die Kopiert wird, deswegen bin ich leicht verunsichert wegen den Zeitangaben im Code ( Get-date) und wegen dem Zeitstempel.

Ich freue mich auf eine Antwort :)

#26 PowerShellAdmin

PowerShellAdmin

    Board Veteran

  • 1.136 Beiträge

 

Geschrieben 16. März 2012 - 12:15

Ich weiß nicht was du kopieren willst, aber generell gehört zu einem Log ein Zeitstempel.
Mit deinem Dateivergleich hat das nichts zu tun, ein Log speichert Ereignisse und führt nix aus. Das war nur ein allgemeiner Hinweis wie man eine Logdatei erstellen kann.

edit: Du konntest aber z.B Übereinstimmungen loggen oder Aktionen, das ist von deiner Skriptlogik abhängig.

PS: Vielleicht solltest du erstmal ein DV Konzept erstellen, darin kann man dann auch definieren was erfordert ist udn wie was gelöst wird. Im Anschluss kann man dann den passenden Skript erstellen.

Bearbeitet von PowerShellAdmin, 16. März 2012 - 12:31.


#27 schreckinger

schreckinger

    Junior Member

  • 73 Beiträge

 

Geschrieben 16. März 2012 - 12:36

Also

Ich habe einen Lokalen Ordner am PC.

Dieser beinhaltet 3 File Typen.

Dann möchte ich die Daten vom Lokalen PC auf den Fileserver speichern.

Dort soll er abgleichen ob es die Dateien dort schon gibt. Sprich auf den Namen matchen.

Wenn er alles Kopiert ohne eine Doppelte Datei zu finden dann soll es normal beendet werden und die Daten die kopiert worden sind sollen in einen String stehen ( mit der Pfad angabe)

Wenn aber eine Datei doppelt ist, soll das Script abbrechen und die Message ins Error log schreiben.

Das soll ich machen.

#28 PowerShellAdmin

PowerShellAdmin

    Board Veteran

  • 1.136 Beiträge

 

Geschrieben 16. März 2012 - 13:31

ok ist doch nicht schwer, du baust in deinem Skript eine Überprüfung - z.B. per IF ein, in der du deine Prüfung durchführst.

Das Ganze wird in einer Foreachschleife laufen, ich gehe davon aus dass das $object eine Datei ist und die Property Name den Dateinamen bzw Pfad enthält
#erstellt eine Variable (Typ String) und initialisiert diese mit der Fehlermeldung
[string]$error="Datei"+$object.name+"ist bereits vorhanden"
if (Bedingung)
{

#Setzt das Datum (zum String formatiert) -kann man bei Bedarf auch in anderen Format ausgeben- und den String in das angegebene Log. 
(get-date).toString() + $error>> c:\log.log
# Bricht den Skript ab
exit
}

Das sollte dir eigentlich ausreichend helfen, ich bin der Meinung das Skripten kriegst du selbst hin. Die Herausforderung ist ja für ein Anfänger durchaus machbar und du solltest wissen wo du ansetzt.
Bin im Bereich PowerShell auch noch nicht fortgeschritten, die Einarbeitung macht viel Spaß und Google ist dein Freund :) Habs und machs noch genauso, hänge auch grade am Multithreading/Jobs und suche eine Lösung die beste Fehlerabarbeitung.

Bearbeitet von PowerShellAdmin, 16. März 2012 - 13:48.