Verbindung von mehreren Hash-Tabellen
Hallo community,
ich habe ein Problem mit meinem Powershell Skript. Dieses soll es möglich machen Daten aus einer Internetseite herraus zu lesen und als CSV Datei abzuspeichern. Dies funktioniert auch soweit, aber da das Script so dynamisch wie möglich sein soll, frage ich in einer Schleife ab, welche Spaltennahmen den später die CSV Datei haben soll.
(Kurz zur erklärung die Abfrage geschied über eine URL in dem man mit ?columns=name,address,... die ausgabe filtern kann. Diese Ausgabe erfolg in JSON.)
Jetzt ist nicht das Problem die richtige URL zu erzeugen, sondern das die Spalten auch manchmal ein Array sein können (z.b. services). Um dieses Problem zu beheben, wandle ich das Array mit hilfer dieses Befehls in einen String um:
@{Name='$services';Expression={[string]::join(",",($_.$services))}}.
Auch das klapt noch ohne Probleme, nur wie gesagt das Skript soll Dynamsich sein und am Ende meiner Ausgabe soll es nicht so wie es jetzt ist stehen
$ausgabe | select name, address,@{Name='services';Expression={[string]::join(",",($_.services))}} | export-csv $path
sondern in einer Art wie dies:
$ausgabe | select $anordnung | export-csv $pfad
So, versucht zu lösen hab ich es momentag in einer schleife die den User immer wieder fragt ob er weitere "Spaltennahmen" eingeben will. Diese eingabe wird in der Variablen $temp gespeichert und zusammen mit den folgenden 2 Befehlen inder der Schleife laufen gelassen.
$anordnungtemp = @{Name='$temp';Expression={[string]::join(",",($_.$temp))}}
$anordnung = $anordnung + "," + $anordnungtemp
(das "," benötige ich um die eingaben beim select Befehl zu trennen)
Und da ist das Problem, solange ich nur ein "Spaltennamen" eingebe funktioniert alles einwandfrei aber wenn ich einen zweiten eingebe kommt immer die Fehlermeldung:
"Das Element wurde bereits hinzugefügt. Schlüssel im Wörterbuch: "Expression". Hinzuzufügender Schlüssel: "Expression""
Ich habe auch schon versucht, die Werte in den Variablen in Anführungszeichen zu setzten, dass die Typumwandlungsbefehele nicht sofort ausgeführt werden, sonder erst in der letzten Zeile, also in der ausgabe. Dann bekomme ich zwar keine Fehlermeldung mehr, aber meine CSV Datei enthält keine Werte.
Ich hoffe ich habe mir halbwegs verständlich ausgedrück im Grunde geht es mir darum in der Zeile:
$ausgabe | select $anordnung | export-csv $pfad
anstelle von $anordnung so etwas zu bekommen
@{Name='name';Expression={[string]::join(",",($_.name))}}, @{Name='address';Expression={[string]::join(",",($_.address))}}, @{Name='services';Expression={[string]::join(",",($_.services))}}
wie, spielt dabei keine rolle, nur es muss halt dynamisch sein.
Mit freundlichen Grüßen
Tobias
ich habe ein Problem mit meinem Powershell Skript. Dieses soll es möglich machen Daten aus einer Internetseite herraus zu lesen und als CSV Datei abzuspeichern. Dies funktioniert auch soweit, aber da das Script so dynamisch wie möglich sein soll, frage ich in einer Schleife ab, welche Spaltennahmen den später die CSV Datei haben soll.
(Kurz zur erklärung die Abfrage geschied über eine URL in dem man mit ?columns=name,address,... die ausgabe filtern kann. Diese Ausgabe erfolg in JSON.)
Jetzt ist nicht das Problem die richtige URL zu erzeugen, sondern das die Spalten auch manchmal ein Array sein können (z.b. services). Um dieses Problem zu beheben, wandle ich das Array mit hilfer dieses Befehls in einen String um:
@{Name='$services';Expression={[string]::join(",",($_.$services))}}.
Auch das klapt noch ohne Probleme, nur wie gesagt das Skript soll Dynamsich sein und am Ende meiner Ausgabe soll es nicht so wie es jetzt ist stehen
$ausgabe | select name, address,@{Name='services';Expression={[string]::join(",",($_.services))}} | export-csv $path
sondern in einer Art wie dies:
$ausgabe | select $anordnung | export-csv $pfad
So, versucht zu lösen hab ich es momentag in einer schleife die den User immer wieder fragt ob er weitere "Spaltennahmen" eingeben will. Diese eingabe wird in der Variablen $temp gespeichert und zusammen mit den folgenden 2 Befehlen inder der Schleife laufen gelassen.
$anordnungtemp = @{Name='$temp';Expression={[string]::join(",",($_.$temp))}}
$anordnung = $anordnung + "," + $anordnungtemp
(das "," benötige ich um die eingaben beim select Befehl zu trennen)
Und da ist das Problem, solange ich nur ein "Spaltennamen" eingebe funktioniert alles einwandfrei aber wenn ich einen zweiten eingebe kommt immer die Fehlermeldung:
"Das Element wurde bereits hinzugefügt. Schlüssel im Wörterbuch: "Expression". Hinzuzufügender Schlüssel: "Expression""
Ich habe auch schon versucht, die Werte in den Variablen in Anführungszeichen zu setzten, dass die Typumwandlungsbefehele nicht sofort ausgeführt werden, sonder erst in der letzten Zeile, also in der ausgabe. Dann bekomme ich zwar keine Fehlermeldung mehr, aber meine CSV Datei enthält keine Werte.
Ich hoffe ich habe mir halbwegs verständlich ausgedrück im Grunde geht es mir darum in der Zeile:
$ausgabe | select $anordnung | export-csv $pfad
anstelle von $anordnung so etwas zu bekommen
@{Name='name';Expression={[string]::join(",",($_.name))}}, @{Name='address';Expression={[string]::join(",",($_.address))}}, @{Name='services';Expression={[string]::join(",",($_.services))}}
wie, spielt dabei keine rolle, nur es muss halt dynamisch sein.
Mit freundlichen Grüßen
Tobias
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 263198
Url: https://administrator.de/forum/verbindung-von-mehreren-hash-tabellen-263198.html
Ausgedruckt am: 21.02.2025 um 12:02 Uhr
4 Kommentare
Neuester Kommentar
Hallo Tobias, Willlkommen auf Administrator.de!
Ich würde das anders angehen und die Daten vorher schon korrekt in die Spalten des Objects $ausgabe schreiben oder korrigieren, dann musst du nicht mit einer Expression in einem Select "nachkorrigieren".
Also alle Spalten von $ausgabe durchlaufen und die Arrays in Strings umwandeln.
Zum Schluss lässt du den Anwender dann die gewünschten Spalten eingeben und machst mit dieser Variable einen select auf dein Ausgabe-Objekt.
Hier ein einfaches Beispiel:
Grüße Uwe
Ich würde das anders angehen und die Daten vorher schon korrekt in die Spalten des Objects $ausgabe schreiben oder korrigieren, dann musst du nicht mit einer Expression in einem Select "nachkorrigieren".
Also alle Spalten von $ausgabe durchlaufen und die Arrays in Strings umwandeln.
Zum Schluss lässt du den Anwender dann die gewünschten Spalten eingeben und machst mit dieser Variable einen select auf dein Ausgabe-Objekt.
Hier ein einfaches Beispiel:
# Nur für einen Test Demodaten erzeugen
$ausgabe = new-object PSObject -Property @{"Name"="Testzeile";"Wert1"=@("Test1","Test2","Test3");"Wert2"=@("BlaA","BlaB","BlaC")}
# Alle Spaltenname des Objekts extrahieren
$spalten = $ausgabe | gm -MemberType NoteProperty | select -ExpandProperty Name
# Alle Daten in den Spalten des Objects in Strings wandeln
foreach($line in $ausgabe){
$spalten | %{$line.$_ = $line.$_ -join ','}
}
# User die Spalten eingeben lassen (im Format Spalte1,Spalte2,Spalte3,SpalteN)
$auswahl = (Read-host "Geben sie die Spaltennamen an mit Komma getrennt an").Split(",")
# CSV Ausgabe
$ausgabe | select $auswahl | export-csv "C:\temp\test.csv" -Delimiter ";" -NoType
Grüße Uwe
Hier einmal mein komplettes Skript, vielleicht habe ich auch nur einen Fehler gemacht, bei der Implementierung deines Skriptes:
Das hast du leider nicht richtig in dein Script implementiert, alles etwas an der falschen Stelle plaziert, deswegen auch keine Änderung deiner Ausgabe Bitte nutze in Zukunft Code-Tags für deinen Quellcode:
<code> Quellcode </code>
. Merci.#Abfrage der benötigten Informationen
$Username = Read-Host "Bitte geben Sie den Nutzernamen an"
$Password = Read-Host "Bitte geben Sie das Passwort an"
$url = read-host "Bitte geben Sie die gewüncht URL ein, ohne die Einträge '?columns=...'"
$auswahl = Read-host "Geben sie die Spaltennamen an mit Komma getrennt an"
$url = $url + "?columns=" + $auswahl
$path = Read-Host "Bitte geben Sie den Zeilpfad der Output Datei an"
#Umwandlung der Zugangsdaten für die Internetseite
$Zugangsdaten = $Username + ":" + $Password
$bytes = [System.Text.Encoding]::ASCII.GetBytes($zugangsdaten)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
$headers = @{ Authorization = $basicAuthValue }
#Funktion zum Ignorieren der Wahrnung des fehlenden Sicherheitszertifikat
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
#Einlesen der Daten sowie deren Ausgabe als CSV Datei
$Daten = Invoke-WebRequest -uri "$url" -Headers $headers
$ausgabe = $Daten | ConvertFrom-Json
# Bearbeiten der extrahierten Daten (Umwandlung der Arrays)
$spalten = $ausgabe | gm -MemberType NoteProperty | select -ExpandProperty Name
foreach($line in $ausgabe){
$spalten | %{$line.$_ = $line.$_ -join ','}
}
$ausgabe | select $auswahl.Split(",") | export-csv $path -Delimiter ";" -NoType -Encoding UTF8
PS: Ich würde mich auch freuen, wenn mir jemand den Trick verraten würde, wie ich den Code als Tabelle ausgeben kann ;P
Was meinst du damit, meinst du format-table oder was meinst du sonst mit Tabelle ? Spezifiziere mal genau wie und in welchem Format was wohin soll.Etwa sowas ?:
$ausgabe | select $auswahl.Split(",") | format-table -AutoSize -Wrap | out-file 'C:\test.txt'
$ausgabe | select $auswahl.Split(",") | Convertto-HTML | out-file 'C:\test.html'
Bestimmte Werte aus CSV Datei automatisch in HTML Datei einfügen
Grüße Uwe