
106543
03.05.2012, aktualisiert am 04.05.2012
Powershell - Textdatei auslesen und dynamische Variablen vergeben zur Erstellung einer Batch-Datei
Hallo Leute,
habe ein kleines Problem bezüglich Powershell. Das Script soll Server aus der Citrix XenApp Farm auslesen. Soweit kein Problem. Die Server werden richtig ausgelesen und in einer temporären Textdatei gespeichert. Danach wird das ganze so gekürzt, dass wirklich NUR die Server drinstehen. Als letztes (und hier liegt das Problem) soll die Datei ausgelesen werden und die Server in unterschiedliche Variablen verpackt werden.
Die .txt-Datei mit den Servern sieht wie folgt aus:
Servername1
Servername2
Servername3
...
Das habe ich bereits zustande gebracht:
#Server auslesen und kürzen
(Get-XAServer| Where-Object {$_.Folderpath -eq "Servers/Datacollector"} | Select-Object ServerName) > Temp\Datacollector.txt
$datei = Get-Content $loc\Temp\Datacollector.txt
$datei | select-object -last 2 > Temp\Datacollector.txt
#Server auslesen und in Batch schreiben
for ($j=0;$j -le 2;$j++) {Invoke-Expression "`$j"; `
Foreach ($i in $test1 = Get-Content $loc\Temp\Datacollector.txt) { `
$spalte1 = $i | %{ $_.Split(","); }; `
$spalte1 = ${Datacollector_$j}; `
write-host "$Datacollector_$j"; `
} `
}
wobei hier :
$loc= Get-Location
Hätte mir vorgestellt dass die Variable $Datacollector_$j dann zu $Datacollector_1, $Datacollector_2, usw. wird.
Danke für eure Hilfe
Dominik
habe ein kleines Problem bezüglich Powershell. Das Script soll Server aus der Citrix XenApp Farm auslesen. Soweit kein Problem. Die Server werden richtig ausgelesen und in einer temporären Textdatei gespeichert. Danach wird das ganze so gekürzt, dass wirklich NUR die Server drinstehen. Als letztes (und hier liegt das Problem) soll die Datei ausgelesen werden und die Server in unterschiedliche Variablen verpackt werden.
Die .txt-Datei mit den Servern sieht wie folgt aus:
Servername1
Servername2
Servername3
...
Das habe ich bereits zustande gebracht:
#Server auslesen und kürzen
(Get-XAServer| Where-Object {$_.Folderpath -eq "Servers/Datacollector"} | Select-Object ServerName) > Temp\Datacollector.txt
$datei = Get-Content $loc\Temp\Datacollector.txt
$datei | select-object -last 2 > Temp\Datacollector.txt
#Server auslesen und in Batch schreiben
for ($j=0;$j -le 2;$j++) {Invoke-Expression "`$j"; `
Foreach ($i in $test1 = Get-Content $loc\Temp\Datacollector.txt) { `
$spalte1 = $i | %{ $_.Split(","); }; `
$spalte1 = ${Datacollector_$j}; `
write-host "$Datacollector_$j"; `
} `
}
wobei hier :
$loc= Get-Location
Hätte mir vorgestellt dass die Variable $Datacollector_$j dann zu $Datacollector_1, $Datacollector_2, usw. wird.
Danke für eure Hilfe
Dominik
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 184394
Url: https://administrator.de/forum/powershell-textdatei-auslesen-und-dynamische-variablen-vergeben-zur-erstellung-einer-batch-datei-184394.html
Ausgedruckt am: 14.05.2025 um 17:05 Uhr
18 Kommentare
Neuester Kommentar
Moin Dominik,
Was steht jetzt in der Variable '$Spalte1'?
Und jetzt? (Oder: Warum überschreibst Du jetzt die obige Variable, ohne mit dem Inhalt erst etwas zu machen? Oder: Was steht zum Zeitpunkt in der/den Variable(n) '$Datacollector_$j')
Wolltest Du evtl. ein Array mit dem Inhalt von '$Spalte1' füllen?
Was will das besagen?
Warum füllst Du die Variablen nicht in der For-Each-Schleife?
Besser wären die Servernamen allerdings in einem Array aufgehoben, die Anzahl der vorhandenen (erkannten) Servernamen gibt dann ein '$Datacollector[-1]' aus. Das Array kannst Du ebenfalls (dann ohne Suffix) in der Schleife füllen.
Freundliche Grüße von der Insel - Mario
Zitat von @106543:
$spalte1 = $i | %{ $_.Split(","); }; `
$spalte1 = $i | %{ $_.Split(","); }; `
Was steht jetzt in der Variable '$Spalte1'?
$spalte1 = ${Datacollector_$j}; `
Und jetzt? (Oder: Warum überschreibst Du jetzt die obige Variable, ohne mit dem Inhalt erst etwas zu machen? Oder: Was steht zum Zeitpunkt in der/den Variable(n) '$Datacollector_$j')
write-host "$Datacollector_$j"; `
Wolltest Du evtl. ein Array mit dem Inhalt von '$Spalte1' füllen?
wobei hier :
$loc= Get-Location
$loc= Get-Location
Was will das besagen?
Hätte mir vorgestellt dass die Variable $Datacollector_$j dann zu $Datacollector_1, $Datacollector_2, usw. wird.
Warum füllst Du die Variablen nicht in der For-Each-Schleife?
Foreach ($i in $test1 = Get-Content $loc\Temp\Datacollector.txt) {
$Datacollector_$j = $i | %{ $_.Split(","); }; 'liefert Servername(n)?
}
Besser wären die Servernamen allerdings in einem Array aufgehoben, die Anzahl der vorhandenen (erkannten) Servernamen gibt dann ein '$Datacollector[-1]' aus. Das Array kannst Du ebenfalls (dann ohne Suffix) in der Schleife füllen.
Freundliche Grüße von der Insel - Mario
Moin Dominik,
Was Du willst, ist schon klar - dann musst Du das aber auch tun!
Links steht immer der, der bekommt, rechts der, der gibt ... (Ist nicht politisch gemeint!
)
Und weil das Doppelmoppelei ist, machst Du es evtl. gleich so, wie oben gepostet (jedes gefilterte 'Split'-Ergebnis in eine Variable '$Datacollector_$j').
Hat dann also erstmal nichts mit dem Problem zu tun ... Puuhh ...
Musst Du auch nicht verwenden, aber: Wenn Du in einer Schleife Variablen 'füllst' (also etwa $Datacollector_1, $Datacollector_2 ... $Datacollector_n), dann weißt Du erstmal nicht, wieviele es/gefüllt geworden sind (Ergo - wieviele Server in Deinem konkreten Fall gefunden wurden). Zu diesem Zweck (Du willst schließlich alle Variablen weiterverwenden) musst Du Dir die Zählvariable aus der Schleife retten (merken) oder mühsam (evtl. noch per Stringzerlegung) existierende Variablen abfragen ...
Ein Array (hier entspr. Lektüre) hat hier den Vorteil, dass es, wie oben erwähnt, seine eigenen Grenzwerte quasi mit sich herumträgt.
Es funktioniert aber auch mit einzelnen Variablen, umstellen auf Arrays kannst Du immer noch - es ist so einfach ...
Wenn Du diesen Gedanken nun folgst, stellst Du gewiss fest, das einer sofortigen Verwendung der gefundenen Servernamen innerhalb der Schleife auch nichts wesentliches entgegensteht ...
Freundliche Grüße von der Insel - Mario
Zitat von @106543:
> > $spalte1 = ${Datacollector_$j}; `
>
> Und jetzt? (Oder: Warum überschreibst Du jetzt die obige Variable, ohne mit dem Inhalt erst etwas zu machen? Oder: Was
> steht zum Zeitpunkt in der/den Variable(n) '$Datacollector_$j')
Ich schreibe die Variable einfach in die andere, damit sie mir über die Schleife hinaus erhalten bleibt, will heißen
dass ich den Wert von $Datacollector_$j gerne behalten würde, deswegen auch $j am Ende, weil $j eine fortlaufende Zahl sein
soll wie oben in der For-Schleife ausgeführt.
> > $spalte1 = ${Datacollector_$j}; `
>
> Und jetzt? (Oder: Warum überschreibst Du jetzt die obige Variable, ohne mit dem Inhalt erst etwas zu machen? Oder: Was
> steht zum Zeitpunkt in der/den Variable(n) '$Datacollector_$j')
Ich schreibe die Variable einfach in die andere, damit sie mir über die Schleife hinaus erhalten bleibt, will heißen
dass ich den Wert von $Datacollector_$j gerne behalten würde, deswegen auch $j am Ende, weil $j eine fortlaufende Zahl sein
soll wie oben in der For-Schleife ausgeführt.
Was Du willst, ist schon klar - dann musst Du das aber auch tun!
$Datacollector_$j = $Spalte1;
Und weil das Doppelmoppelei ist, machst Du es evtl. gleich so, wie oben gepostet (jedes gefilterte 'Split'-Ergebnis in eine Variable '$Datacollector_$j').
Der Befehl get-location gibt den aktuellen Pfad zurück, den ich so in eine Variable speichere und für später aufheben kann.
Hat dann also erstmal nichts mit dem Problem zu tun ... Puuhh ...
Array hab ich leider wenig bis gar keine Erfahrung von daher würde ich das gerne vermeiden...
Musst Du auch nicht verwenden, aber: Wenn Du in einer Schleife Variablen 'füllst' (also etwa $Datacollector_1, $Datacollector_2 ... $Datacollector_n), dann weißt Du erstmal nicht, wieviele es/gefüllt geworden sind (Ergo - wieviele Server in Deinem konkreten Fall gefunden wurden). Zu diesem Zweck (Du willst schließlich alle Variablen weiterverwenden) musst Du Dir die Zählvariable aus der Schleife retten (merken) oder mühsam (evtl. noch per Stringzerlegung) existierende Variablen abfragen ...
Ein Array (hier entspr. Lektüre) hat hier den Vorteil, dass es, wie oben erwähnt, seine eigenen Grenzwerte quasi mit sich herumträgt.
Es funktioniert aber auch mit einzelnen Variablen, umstellen auf Arrays kannst Du immer noch - es ist so einfach ...
Wenn Du diesen Gedanken nun folgst, stellst Du gewiss fest, das einer sofortigen Verwendung der gefundenen Servernamen innerhalb der Schleife auch nichts wesentliches entgegensteht ...
Freundliche Grüße von der Insel - Mario
Moin Dominik,
Erhofft hattest Du (indirekt), man könne in dem Schleifendurchlauf gleich noch (soviele) Variablen erstellen, wie gebraucht werden - und dabei den Namen aus einem Basisteil und einer Zählvariablen zusammensetzen. Und vielleicht noch ein wenig mehr ...
Warum tust Du Dir diese Variablengeschichte an? Nutze den herausgelösten Servernamen in der Schleife (und beachte den verbleibenden Nutzen der Äußeren), also etwa so:
Das Auslesen aller Variablen (mit den genannten Problemen) oder eines Arrays müsste auch wieder in einer Schleife erfolgen - das kannst Du besser gleich erledigen.
Freundliche Grüße von der Insel - Mario
Zitat von @106543:
hmm hat nicht ganz so geklappt wie erhofft jetzt hab ich folgenden Befehl:
hmm hat nicht ganz so geklappt wie erhofft jetzt hab ich folgenden Befehl:
Erhofft hattest Du (indirekt), man könne in dem Schleifendurchlauf gleich noch (soviele) Variablen erstellen, wie gebraucht werden - und dabei den Namen aus einem Basisteil und einer Zählvariablen zusammensetzen. Und vielleicht noch ein wenig mehr ...
... aber jetzt hab ich das Problem dass da die Schleifen ja doppelt durchlaufen also beide dann hab ich in der Variablen IMMER den selben Server ...
Warum tust Du Dir diese Variablengeschichte an? Nutze den herausgelösten Servernamen in der Schleife (und beachte den verbleibenden Nutzen der Äußeren), also etwa so:
Write-host Datacollector
(Get-XAServer| Where-Object {$_.Folderpath -eq "Servers/Datacollector"} | Select-Object ServerName) > Temp\Datacollector.txt
$datei = Get-Content $loc\Temp\Datacollector.txt
$datei | select-object -last 2 > Temp\Datacollector.txt
for ($j=1;$j -le 2;$j++) {
Foreach ($i in $test1 = Get-Content Temp\Datacollector.txt) {
$SrvName = $i | %{ $_.Split(","); };
Write-Host $SrvName; # Ausgabe bzw. Weiterverarbeitung
}
}
Das Auslesen aller Variablen (mit den genannten Problemen) oder eines Arrays müsste auch wieder in einer Schleife erfolgen - das kannst Du besser gleich erledigen.
Freundliche Grüße von der Insel - Mario
Moin Dominik,
mein Kommentar
Freundliche Grüße von der Insel - Mario
mein Kommentar
... (und beachte den verbleibenden Nutzen der Äußeren) ...
sollte Dich auf das Problem hinweisen - die äußere Schleife ist zur einmaligen Gewinnung der Servernamen kontraproduktiv. Da ich aber nicht sicher sein kann, ob sie noch zu etwas anderem dient ... Kurzer Test: Zeile 5+10 (Dein letzter Post) auskommentieren.Freundliche Grüße von der Insel - Mario
Moin Dominik,
Also das wesentliche ... Ja - ich hatte geschrieben ...'der Äußeren ...' - das bezog sich nur auf die selbige Schleife. Jetzt läuft es wie gewünscht?
Freundliche Grüße von der Insel - Mario
Zitat von @106543:
Der Nutzen des Äußeren hält sich in Grenzen, da hier nur die Server ausgelesen werden (get-XAServer), dann nach ...
Der Nutzen des Äußeren hält sich in Grenzen, da hier nur die Server ausgelesen werden (get-XAServer), dann nach ...
Also das wesentliche ... Ja - ich hatte geschrieben ...'der Äußeren ...' - das bezog sich nur auf die selbige Schleife. Jetzt läuft es wie gewünscht?
Freundliche Grüße von der Insel - Mario
Moin Dominik,
wenn Du in eine Datei schreibst, nimm die
Im konkreten Fall kommt hinzu, das in einer Batch-Datei ein
Das ist wichtig, um den String definiert abzuschließen (keine sog. 'Trailing Blanks').
Da zusätzlich die Variablen vor dem Schreiben durch Ihren Inhalt ersetzt werden müssen, sieht das Konstrukt in der PS so aus:
Die dreifachen Literale stehen für:
- äußeres Paar bildet Gesamtstring für
- inneres Paar bewirkt Variablenauflösung
- mittleres Paar wird unverändert in Datei geschrieben
BTW: Beim Schreiben der Strings dürfte Dir spätestens der Nachteil der Variablenlösung aufgehen - was passiert, wenn mehr oder weniger als zwei Servernamen erkannt werden?
Verwende bitte für Deine Posts - auch nachträglich - die -Formatierung!
Freundliche Grüße von der Insel - Mario
wenn Du in eine Datei schreibst, nimm die
'Add-Content'
oder 'Set-Content'
-Methoden, dort wird die Kodierung anhand der Ausgabedatei (meistens richtig) vorgenommen.Im konkreten Fall kommt hinzu, das in einer Batch-Datei ein
'set'
-Befehl stets mit Literalen notiert und ausgeführt werden sollte, also so:set "Variable=Wert"
Das ist wichtig, um den String definiert abzuschließen (keine sog. 'Trailing Blanks').
Da zusätzlich die Variablen vor dem Schreiben durch Ihren Inhalt ersetzt werden müssen, sieht das Konstrukt in der PS so aus:
Set-Content "server.bat" "set ""Datacollector=$Datacollector2,$Datacollector2"""
Die dreifachen Literale stehen für:
- äußeres Paar bildet Gesamtstring für
'Set-Content'
-Befehl- inneres Paar bewirkt Variablenauflösung
- mittleres Paar wird unverändert in Datei geschrieben
BTW: Beim Schreiben der Strings dürfte Dir spätestens der Nachteil der Variablenlösung aufgehen - was passiert, wenn mehr oder weniger als zwei Servernamen erkannt werden?
Verwende bitte für Deine Posts - auch nachträglich - die -Formatierung!
Freundliche Grüße von der Insel - Mario