Benutzer mit den meisten Antworten
pssession und computernamen aus txt oder CSV importieren geht überhaupt nicht...

Frage
-
Hallo, ich versuche ein Script zu schreiben, dass mehrere Remote Server bearbeiten soll, aber irgendwie geht das nicht, wie in der Dokumentation beschrieben.
Inhalt der Text.csv oder auch Text.txt, hab beides Versucht:
computer1.domain.local,computer1.domain.local
oder Computer1.domain.local;computer2.domain.localhier die Codezeile
$s = New-PSSession -computername (import-csv ./text.csv) -ConfigurationName thisname
Das ist in ähnlicher Weise hier beschrieben, Beispiel Nummer 9:
$cred = get-credential $s = New-PSSession -computername (import-csv ./text.csv) -ConfigurationName thisname -credential $cred
Das hab ich auch schon versucht, geht aber auch nicht. Wenn ich ./text.csv durch text.csv ersetze, hilft es nicht.
Hier sagt er mir (in beiden Fällen, immer Das Argument für den Parameter "Computername" kann nicht überprüft werden. Das Argument ist NULL oder leer. Geben Sie ein Argument an, das nicht NULL oder leer ist, und führen Sie dann den Befehl erneut aus.
:-P
Das klappt aber auch nicht.
Das habe ich auch versucht:
$bleche = import-csv ./text.csv foreach ($rechner in $bleche) { $mySession = New-PSSession -Computername $rechner -ConfigurationName PSHHREMOTE if ($mySession) { Enter-PSSession $mySession.Id $zielpfade= gci "C:\Program Files (x86)\Blob\dateien\" | where {$_.attributes -match "Directory"} | select-Object Fullname $quellpfade = gci \\Server\freigabe\Blob\dateien\ | where {$_.attributes -match "Directory"} | select-Object Fullname for($i=0; $i -le $quellpfade.length; $i++) { $quelle = $quellpfade[$i] + "\\*" $ziel = $zielpfade[$i] + "\\*" Copy-Item $quelle $ziel -force } Exit-PSSession Remove-PSSession $mySession.Id } else { "Fehler bei pssession aufbau" }
Da passiert allerdings überhaupt nichts mehr (!), weder tut er irgendwas, noch gibt es eine Fehlermeldung, das Script endend einfach sang- und klanglos.
Wenn ich mich ohne Script also über normale Konsolenbefehle Remoteeinwähle, dann läuft alles wunderbar.
Kann mir einer von euch sagen, was ich falsch mache???
Antworten
-
Beim Lernen und beim Debuggen sollte man sich den Abschnitt heraussuchen der nicht Funktioniert. Zerlege das große Problem in viele kleine, löse die Kleinen Probleme und das große Problem löst sich von selbst (Teile und herrsche).
Wenn du eine .txt nutz dann muss in jeder Zeile nur ein Computername stehen. PowerShell behandelt dann beim Einlesen mit Get-Content jede Zeile einzeln.
Mach folgendes:1. Erstelle eine Textdatei mit jeweils einem Computernamen in einer Zeile (nichts anderes)
$File = "D:\Temp\Computer.txt" "Computer1.domain.local" | Out-File $File "Computer2.domain.local" | Out-File $File -Append "Computer3.domain.local" | Out-File $File -Append
2. Nun nimm diese Textdatei und lese sie mit Get-Content ein:
Get-Content "D:\Temp\Computer.txt" | ForEach { "Ich verarbeite nun den Computer: $_"}
Du siehst jeder Computername wird einzeln verarbeitet.
Es gibt in der PowerShell 2 Verschieden ForEach !
Da musst du aufpassen!
Einmal das ForEach-Object { ... } Cmdlet und die ForEach ($File in Files) { ... } Schleife !
Gemeinerweise hat das ForEach-Object { ... } Cmdlet einen Alias der ForEach { ... } heisst!
Da kommt man schnell durcheinander!
Der Unterschied ist, das ForEach-Object { ... } Cmdlet wird in der Pipeline eingesetzt und die ForEach ($Computer in $Computers) { ... } Schleife nicht!
Die ForEach Schleife ist schneller als das ForEach-Object Cmdlet.
Bei dem ForEach Cmdlet wird jedes Objekt einzeln in der Pipeline weitergegeben so wird kein Array benötigt.
Die ForEach( X in Y){ … } Schleife benötigt ein Array das alle Objekte enthält enthält.
Ein Array für eine ForEach Schleife kann bei sehr vielen Dateien sehr viel Speicher verbrauchen, das ist ungünstig.
Bei einer geringen Anzahl an Objekten (kleine Datenmenge) ist es egal wann man das Cmdlet und wann die Schleife nimmt.Dein Code würde dann so aussehen:
# So mit ForEach-Object Cmdlet und Pipeline Get-Content "D:\Temp\Computer.txt" | ForEach-Object { # $_ ist das aktuelle Objekt das in der Pipeline gerade verarbeitet wird $mySession = New-PSSession -Computername $_ -ConfigurationName PSHHREMOTE if ($mySession) { Enter-PSSession $mySession.Id $zielpfade= gci "C:\Program Files (x86)\Blob\dateien\" | where {$_.attributes -match "Directory"} | select-Object Fullname $quellpfade = gci \\Server\freigabe\Blob\dateien\ | where {$_.attributes -match "Directory"} | select-Object Fullname for($i=0; $i -le $quellpfade.length; $i++) { $quelle = $quellpfade[$i] + "\\*" $ziel = $zielpfade[$i] + "\\*" Copy-Item $quelle $ziel -force } # ende for Exit-PSSession Remove-PSSession $mySession.Id } # ende if ($mySession) else { "Fehler bei pssession aufbau" } # ende else } # ende ForEach-Object #### ODER SO #### # mit ForEach Schleife ohne Pipeline $Computers = Get-Content "D:\Temp\Computer.txt" ForEach ($Computer in $Computers) { $mySession = New-PSSession -Computername $Computer -ConfigurationName PSHHREMOTE if ($mySession) { Enter-PSSession $mySession.Id $zielpfade= gci "C:\Program Files (x86)\Blob\dateien\" | where {$_.attributes -match "Directory"} | select-Object Fullname $quellpfade = gci \\Server\freigabe\Blob\dateien\ | where {$_.attributes -match "Directory"} | select-Object Fullname for($i=0; $i -le $quellpfade.length; $i++) { $quelle = $quellpfade[$i] + "\\*" $ziel = $zielpfade[$i] + "\\*" Copy-Item $quelle $ziel -force } # ende for Exit-PSSession Remove-PSSession $mySession.Id } # ende if ($mySession) else { "Fehler bei pssession aufbau" } # ende else } # ende ForEach Schleife
Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
German ? Come to German PowerShell Forum!
- Bearbeitet Peter Kriegel Freitag, 11. Januar 2013 06:40
- Als Antwort markiert Jeffrey Goines Samstag, 12. Januar 2013 10:26
Alle Antworten
-
Hi, wie ist denn deine .csv aufgebaut? Also welche Headerzeile?
Ansonsten nimm eine einfache Textdatei zum Test, schreib in jede Zeile einen Computernamen und les diese mit get-content ein. Damit dürfte auf jeden Fall das öffnen der Session klappen.
Gruss
Bastian
P.S. der Parameter -Computername akzeptiert nur Strings (in der Hilfe zu sehen -> durch die beiden eckigen Klammern [] auch zu erkennen, dass ein String Array akzeptiert wird). Mit Import-csv bekommst du eigentlich ein PSCustomObject zurück. In deinem Skriptbeispiel würde es klappen, wenn du im Foreach auf das Property referenzierst, welches bei dem Objekt den Computernamen darstellt.Also in deinem Skript müsste das klappen, wenn der Header für den Computernamen "Computernamen" lautet:
$bleche = import-csv ./text.csv foreach ($rechner in $bleche) { $mySession = New-PSSession -Computername $rechner.computername -ConfigurationName PSHHREMOTE
Wenn du nur $rechner angibst, gibst du das ganze Objekt vom Typ PsCustomObject an, aber der Parameter akzeptiert ja nur Strings.
Wenn du dir die Textdatei also eh nur mit Computernamen füllst, folge meinem Vorschlag oben. Mit get-content bekommst du so einen String, der mit den Klammern dann direkt als Parameter für -Computername benutzt werden kann
- Bearbeitet baschuel Donnerstag, 10. Januar 2013 16:48
-
Hi, wie ist denn deine .csv aufgebaut? Also welche Headerzeile?
Ansonsten nimm eine einfache Textdatei zum Test, schreib in jede Zeile einen Computernamen und les diese mit get-content ein. Damit dürfte auf jeden Fall das öffnen der Session klappen.
Aufgebaut, wie oben beschrieben.
Computername1.domain.local,Computername2.domain.local
oder
Computername1.domain.local;Computername2.domain.local
aber gut, hab jetzt in die Ausgabe geguckt, da nimmt er die mit "import-csv" importierten sachen als Header... :-P
Im Technet-Beispiel war davon nie die Rede, finde es sowieso extrem nervig, dass man da extra in die Doku schaut, und das was deren Beispiel "importiert" kann grundsätzlich nicht klappen..grmpf... naja, anderes Thema.
Das was du sagst, also Textdatei, ein name pro Zeile dann get-Content, war das erste was ich versucht habe.
Die Fehlermeldungen (von wegen Rechner-Name ist ungültig, ja, deswegen klappt es ja, wenn ich Ihn direkt eingebe) sind da so irre, dass ich das gar nicht mehr mit erwähnt habe.
-
Beim Lernen und beim Debuggen sollte man sich den Abschnitt heraussuchen der nicht Funktioniert. Zerlege das große Problem in viele kleine, löse die Kleinen Probleme und das große Problem löst sich von selbst (Teile und herrsche).
Wenn du eine .txt nutz dann muss in jeder Zeile nur ein Computername stehen. PowerShell behandelt dann beim Einlesen mit Get-Content jede Zeile einzeln.
Mach folgendes:1. Erstelle eine Textdatei mit jeweils einem Computernamen in einer Zeile (nichts anderes)
$File = "D:\Temp\Computer.txt" "Computer1.domain.local" | Out-File $File "Computer2.domain.local" | Out-File $File -Append "Computer3.domain.local" | Out-File $File -Append
2. Nun nimm diese Textdatei und lese sie mit Get-Content ein:
Get-Content "D:\Temp\Computer.txt" | ForEach { "Ich verarbeite nun den Computer: $_"}
Du siehst jeder Computername wird einzeln verarbeitet.
Es gibt in der PowerShell 2 Verschieden ForEach !
Da musst du aufpassen!
Einmal das ForEach-Object { ... } Cmdlet und die ForEach ($File in Files) { ... } Schleife !
Gemeinerweise hat das ForEach-Object { ... } Cmdlet einen Alias der ForEach { ... } heisst!
Da kommt man schnell durcheinander!
Der Unterschied ist, das ForEach-Object { ... } Cmdlet wird in der Pipeline eingesetzt und die ForEach ($Computer in $Computers) { ... } Schleife nicht!
Die ForEach Schleife ist schneller als das ForEach-Object Cmdlet.
Bei dem ForEach Cmdlet wird jedes Objekt einzeln in der Pipeline weitergegeben so wird kein Array benötigt.
Die ForEach( X in Y){ … } Schleife benötigt ein Array das alle Objekte enthält enthält.
Ein Array für eine ForEach Schleife kann bei sehr vielen Dateien sehr viel Speicher verbrauchen, das ist ungünstig.
Bei einer geringen Anzahl an Objekten (kleine Datenmenge) ist es egal wann man das Cmdlet und wann die Schleife nimmt.Dein Code würde dann so aussehen:
# So mit ForEach-Object Cmdlet und Pipeline Get-Content "D:\Temp\Computer.txt" | ForEach-Object { # $_ ist das aktuelle Objekt das in der Pipeline gerade verarbeitet wird $mySession = New-PSSession -Computername $_ -ConfigurationName PSHHREMOTE if ($mySession) { Enter-PSSession $mySession.Id $zielpfade= gci "C:\Program Files (x86)\Blob\dateien\" | where {$_.attributes -match "Directory"} | select-Object Fullname $quellpfade = gci \\Server\freigabe\Blob\dateien\ | where {$_.attributes -match "Directory"} | select-Object Fullname for($i=0; $i -le $quellpfade.length; $i++) { $quelle = $quellpfade[$i] + "\\*" $ziel = $zielpfade[$i] + "\\*" Copy-Item $quelle $ziel -force } # ende for Exit-PSSession Remove-PSSession $mySession.Id } # ende if ($mySession) else { "Fehler bei pssession aufbau" } # ende else } # ende ForEach-Object #### ODER SO #### # mit ForEach Schleife ohne Pipeline $Computers = Get-Content "D:\Temp\Computer.txt" ForEach ($Computer in $Computers) { $mySession = New-PSSession -Computername $Computer -ConfigurationName PSHHREMOTE if ($mySession) { Enter-PSSession $mySession.Id $zielpfade= gci "C:\Program Files (x86)\Blob\dateien\" | where {$_.attributes -match "Directory"} | select-Object Fullname $quellpfade = gci \\Server\freigabe\Blob\dateien\ | where {$_.attributes -match "Directory"} | select-Object Fullname for($i=0; $i -le $quellpfade.length; $i++) { $quelle = $quellpfade[$i] + "\\*" $ziel = $zielpfade[$i] + "\\*" Copy-Item $quelle $ziel -force } # ende for Exit-PSSession Remove-PSSession $mySession.Id } # ende if ($mySession) else { "Fehler bei pssession aufbau" } # ende else } # ende ForEach Schleife
Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
German ? Come to German PowerShell Forum!
- Bearbeitet Peter Kriegel Freitag, 11. Januar 2013 06:40
- Als Antwort markiert Jeffrey Goines Samstag, 12. Januar 2013 10:26
-
Moin, das mit in kleine Abschnitte zerlegen und die Teilprobleme lösen mach ich auch so. ;-)
Allerding muss ich zugeben, das Foreach-Object kannte ich nicht (ähem.. ja.. Basics und so..ähem... :-S ), war genau das was ich gesucht hatte. Vielen Dank für die Info, dass hat mir gleich mehrere Probleme gelöst. THANX!! :-D
-
Hi, Thread ist zwar schon solved, aber ich würd den gern nochmal aufgreifen.
Das mit Foreach-Object ist zwar richtig und auch eine Möglichkeit, aber meiner Meinung nach sollte das vom Threadersteller bzw. mir beschriebene Vorgehen trotzdem funktionieren. (also mit import-csv auch, aber nur gepipet nach select und expandproperty, da ja computername ein String sein muss)
Also das Ausführen von Kommandos in Klammern vor dem eigentlichen Befehl als Input für Parameter ist ja ein sehr nützliches Werkzeug und sollte funktionieren.
Bsp.:
get-service -computername (get-content .\Server.txt) # Voraussetzung in jeder Zeile ein String mit dem Computernamen
get-service -computername (import-csv .\Server.csv | select-object -expand compname) # Voraussetzung Header für Computernamen heißt hier "Compname"
DAchte ich zumindest bisher. Nu hab ich seit meinem Post meinen Rechner neu installiert und mit Windows 8. Und probier eben nochmal und ich bekomm die gleiche Fehlermeldung wie der Threadersteller?!
Fahr ich meine Testmaschine Windows Server 2008R2 hoch und probier es, klappt alles wie erwartet!
Ich probiers mit Server 2012 und geht wieder nicht mit gleichem Fehler.
Kannst du dir das erklären Peter? Raff das nich :/
Danke und Gruss
Bastian
-
Hi Bastian!
Deine Frage hat nur sehr indirekt mit der ursprünglichen Frage etwas zu tun, außerdem werden Grün abgehakte Fragen hier kaum noch beachtet. Deshalb bitte in Zukunft einen neue Frage öffnen!
Ich habe deinen Code jetzt auch 2 Windows 7 Systemen getestet. Einmal mit PS 2.0 und einmal mit PS 3.0 . Beide Codes liefen sauber durch. Ich werde das heute Abend mal mit meinem Win8 und Server 2012 Probieren und berichten.
Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
German ? Come to German PowerShell Forum! -
Hi Bastian!
Deine Frage hat nur sehr indirekt mit der ursprünglichen Frage etwas zu tun, außerdem werden Grün abgehakte Fragen hier kaum noch beachtet. Deshalb bitte in Zukunft einen neue Frage öffnen!
Ich habe deinen Code jetzt auch 2 Windows 7 Systemen getestet. Einmal mit PS 2.0 und einmal mit PS 3.0 . Beide Codes liefen sauber durch. Ich werde das heute Abend mal mit meinem Win8 und Server 2012 Probieren und berichten.
Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
My PowerShell Blog http://www.admin-source.info
[string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
German ? Come to German PowerShell Forum!Hallo Peter,
passt schon, mach dir keine Mühe mehr. Ich bekomm es nu wieder nicht mehr reproduziert. Auf 10 Testmaschinen grad probiert von 2008R2 bis 2012 über Windows 8 in englisch und deutsch und überall klappt es. Keine Ahnung wie ich das hinbekommen habe. Tippe momentan darauf, dass das Problem vor der Tastatur saß und ich irgendnen platten Fehler gemacht hab. Keine Ahnung, aber da nicht mehr reproduzierbar für mich, auch nichts wo man noch Mühe reinstecken sollte :)
Danke und sry für die "Unruhe"
Gruss
Bastian