Powershell Datenimport
Hallo,
ich bin gerade bei einem Gedankenspiel, welches ich auch schon kurz getestet habe. Ich habe eine CSV Datei, deren Inhalt ich importiere. Den Inhalt lasse ich durch eine Foreach Schleife laufen, so dass ich an die einzelnen Einträge herankomme. Die Einträge werden wiederum zu globalen Variablen gemacht. Nun habe ich das Problem, dass es in der CSV Datei ebenfalls Einträge gibt, die als Array angelegt werden sollen. Habt ihr einen Hinweis, wie ich das machen könnte. Der Delimeter für die CSV ist ";" und als Trenner für das Array möchte ich "," verwenden. Bisher bekomme ich über GetType immer einen String zurück.
Mein globales Ziel ist eine zentrale Datei, die mit sämtlichen Variablen und Arrays bestückt ist, die ich für alle meine Skripte nutzen kann. Dies soll der Vermeidung von Variablenüberschneidungen dienen.
Gruß
derhoeppi
ich bin gerade bei einem Gedankenspiel, welches ich auch schon kurz getestet habe. Ich habe eine CSV Datei, deren Inhalt ich importiere. Den Inhalt lasse ich durch eine Foreach Schleife laufen, so dass ich an die einzelnen Einträge herankomme. Die Einträge werden wiederum zu globalen Variablen gemacht. Nun habe ich das Problem, dass es in der CSV Datei ebenfalls Einträge gibt, die als Array angelegt werden sollen. Habt ihr einen Hinweis, wie ich das machen könnte. Der Delimeter für die CSV ist ";" und als Trenner für das Array möchte ich "," verwenden. Bisher bekomme ich über GetType immer einen String zurück.
Mein globales Ziel ist eine zentrale Datei, die mit sämtlichen Variablen und Arrays bestückt ist, die ich für alle meine Skripte nutzen kann. Dies soll der Vermeidung von Variablenüberschneidungen dienen.
Gruß
derhoeppi
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 308474
Url: https://administrator.de/contentid/308474
Ausgedruckt am: 24.11.2024 um 02:11 Uhr
16 Kommentare
Neuester Kommentar
Hallo derhoeppi,
für sowas habe ich hier schon mal einen Beitrag geschrieben, um Variablen, Einstellungen, Werte in einer XML-Datei zu speichern, zurückzuschreiben und wieder auszulesen:
Powershell: Werte aus einer XML-Datei auslesen und wieder darin speichern
Ansonsten wie @H41mSh1C0R schreibt, per Schleife deine Werte einer Hashtable zuweisen. Das ist wesentlich zielgerichteter als "extra Variablen" zu erzeugen. Auf die Werte in der Hashtable kannst du ja dann so zugreifen:
oder auch
Hier ein simples Beispiel:
Ein Array kannst du für einen String ganz einfach erzeugen
oder
Grüße Uwe
für sowas habe ich hier schon mal einen Beitrag geschrieben, um Variablen, Einstellungen, Werte in einer XML-Datei zu speichern, zurückzuschreiben und wieder auszulesen:
Powershell: Werte aus einer XML-Datei auslesen und wieder darin speichern
Ansonsten wie @H41mSh1C0R schreibt, per Schleife deine Werte einer Hashtable zuweisen. Das ist wesentlich zielgerichteter als "extra Variablen" zu erzeugen. Auf die Werte in der Hashtable kannst du ja dann so zugreifen:
$hashtable['Einstellung1']
$hashtable['Einstellung2']
$hashtable.'Einstellung1'
Hier ein simples Beispiel:
$csv = @"
Variable;Typ;Wert
var1;string;Max Muster
var2;array;2001,2002,2003,2003
var3;int;100
"@ | convertfrom-CSV -Delimiter ";"
# Hashtable hält unsere Daten
$data = @{}
# CSV durchlaufen und Werte der Hashtable zuweisen
foreach($line in $csv){
switch($line.Typ){
'int' {$data[$line.Variable] = [int]$line.Wert}
'array' {$data[$line.Variable] = [array]$line.Wert.Split(',')}
default {$data[$line.Variable] = [string]$line.Wert}
}
}
$data
"Bla,Blub" -split ','
$array = $variable.Split(',')
Grüße Uwe
$content = @{}
$content = Import-Csv -Path $varibales_filename -Delimiter ";"
Falsch, du erstellst eine Hashtable und weist der Hashtable per Import-CSV ein Objekt zu, das geht nicht. Import-CSV erstellt ein Custom-Object keine Hashtable.$content = Import-Csv -Path $varibales_filename -Delimiter ";"
Mein einziges Problem mit der Hashtabelle ist das direkte Adressieren der einzelnen Variablen.
Wieso? Auf die Variablen einer Hashtable kannst du ganz bequem mit deren Namen ansprechen und auch Werte zuweisen:Wie in meinem Beispiel oben:
$data['NameDerVariablen']
$data.'Name Der Variablen'
Als Fortgeschrittener kann man es auch über XML-Object-Serialization und einer Klassendefinition machen , dann werden die Typen der Variablen automatisch wieder korrekt zugewiesen:
Einmal ein bißchen in der c# Doku gelesen und du hast auf einmal hunderte mehr Möglichkeiten
http://www.blackwasp.co.uk/xmlarrays.aspx
Powershell = .NET = C# = VB.Net (Lässt sich alles auch in Powershell abbilden)
$pathSettings = 'A:\meine_app_settings.xml'
# Klassendefinition
Add-Type -TypeDefinition @"
public class myAppSettings {
public string var1;
public int var2;
public double var3;
public string var4;
}
"@ -EA Ignore
# Objekt von Klasse erzeugen
$settings = new-object myAppSettings
$settings.var1 = "teststring"
$settings.var2 = 333
$settings.var3 = 999383828
$settings.var4 = @("1","2","3","4")
# XML-Serialization
$serializer = New-Object System.Xml.Serialization.XmlSerializer ([myAppSettings])
$writer = New-Object System.IO.StreamWriter($pathSettings)
$serializer.Serialize($writer,$settings)
$writer.Close()
# Settings-Objekt für die Demo zerstören
$settings = $null
# XML-Deserialization wieder aus XML-Datei laden
$serializer = New-Object System.Xml.Serialization.XmlSerializer([myAppSettings])
$settings = $serializer.Deserialize((New-Object System.IO.StreamReader($pathSettings)))
# geladene Daten wieder anzeigen
$settings
# Der Zugriff auf die einzelnen Eigenschaften(Variablen) erfolgt wie bei jedem anderen Custom-Objekt
$settings.var4
http://www.blackwasp.co.uk/xmlarrays.aspx
Powershell = .NET = C# = VB.Net (Lässt sich alles auch in Powershell abbilden)
Du hast ja jetzt die Wahl Die Entscheidung können wir dir nicht abnehmen, nur mögliche Umsetzungen liefern.
@H41mSh1C0R hat das in dem Zusammenhang auch schon mal gefragt. Da habe ich Ihm hier auch zu einer XML und einer Datatable geraten, da es einfach über die GUI einem DataGridView zuweisbar und in die XML zurück zu schreiben ist: Powershell Datagridview und XML Datenhaltung
@H41mSh1C0R hat das in dem Zusammenhang auch schon mal gefragt. Da habe ich Ihm hier auch zu einer XML und einer Datatable geraten, da es einfach über die GUI einem DataGridView zuweisbar und in die XML zurück zu schreiben ist: Powershell Datagridview und XML Datenhaltung
Das Speichern jedoch nicht.
Aha, und du meinst die Info "funktioniert nicht" reicht jetzt aus oder was ??? Fehlermeldung?Glaskugel rauskam ... Du hast wahrscheinlich dem DataGridView die Datatable nicht als Source Datenobjekt zugewiesen und schreibst deshalb die unveränderte Version zurück.
Aber alles nur Spekulation bei dem Informationsüberfluss
Hier ein simples Beispiel für den Im- und Export der Daten in/aus einer XML-Datei in ein DataGridView-Steuerelement:
$scriptpath = Split-Path $MyInvocation.MyCommand.Definition -Parent
$xmlpath = "$scriptpath\data.xml"
function GenerateForm {
#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
#endregion
#region Generated Form Objects
$form1 = New-Object System.Windows.Forms.Form
$btnExport = New-Object System.Windows.Forms.Button
$btnImport = New-Object System.Windows.Forms.Button
$dgv = New-Object System.Windows.Forms.DataGridView
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
$dt = New-Object System.Data.DataTable
#endregion Generated Form Objects
#----------------------------------------------
# Event Script Blocks
#----------------------------------------------
$handler_form1_Load=
{
$dt.TableName = "Daten"
$dt.Columns.Add('Vorname')
$dt.Columns.Add('Nachname')
$dt.Rows.Add(@('Max','Muster'))
$dt.Rows.Add(@('Anna','Musterfrau'))
$dgv.DataSource = $dt
}
$handler_btnExport_Click=
{
$dt.WriteXml($xmlpath)
[System.Windows.Forms.MessageBox]::Show("Daten wurden exportiert nach '$xmlpath' !")
}
$handler_btnImport_Click=
{
if ((Test-Path $xmlpath)){
$dt.Clear()
$dt.ReadXml($xmlpath)
[System.Windows.Forms.MessageBox]::Show("Daten wurden importiert von '$xmlpath'!")
}else{
[System.Windows.Forms.MessageBox]::Show("Führen sie erst einen Export durch!")
}
}
$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
#----------------------------------------------
#region Generated Form Code
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 183
$System_Drawing_Size.Width = 340
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$form1.Name = "form1"
$form1.Text = "DataGridView Load&Export"
$form1.add_Load($handler_form1_Load)
$btnExport.Anchor = 10
$btnExport.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 253
$System_Drawing_Point.Y = 157
$btnExport.Location = $System_Drawing_Point
$btnExport.Name = "btnExport"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 75
$btnExport.Size = $System_Drawing_Size
$btnExport.TabIndex = 2
$btnExport.Text = "Exportieren"
$btnExport.UseVisualStyleBackColor = $True
$btnExport.add_Click($handler_btnExport_Click)
$form1.Controls.Add($btnExport)
$btnImport.Anchor = 10
$btnImport.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 172
$System_Drawing_Point.Y = 157
$btnImport.Location = $System_Drawing_Point
$btnImport.Name = "btnImport"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 75
$btnImport.Size = $System_Drawing_Size
$btnImport.TabIndex = 1
$btnImport.Text = "Importieren"
$btnImport.UseVisualStyleBackColor = $True
$btnImport.add_Click($handler_btnImport_Click)
$form1.Controls.Add($btnImport)
$dgv.Anchor = 15
$dgv.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$dgv.Location = $System_Drawing_Point
$dgv.Name = "dgv"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 139
$System_Drawing_Size.Width = 316
$dgv.Size = $System_Drawing_Size
$dgv.TabIndex = 0
$form1.Controls.Add($dgv)
#endregion Generated Form Code
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$form1.ShowDialog()| Out-Null
} #End Function
GenerateForm
Warum muss ich eine Copy anlegen.
Musst du definitiv nicht. Siehe mein funktionsfähiges Beispiel oben.Ich bin also davon ausgegangen, dass wenn ich eine Änderung im DataGridView durchführe - diese dann ebenfalls in der DataTable $dt geändert wird.
Das ist auch absolut richtig. Bei meiner Variante oben benötigst du keine Kopie, weil das DataGridView ja direkt mit der DataSource verbunden ist! Probiere mein Beispiel oben aus dann wirst du sehen das du Änderungen vornehmen kannst und diese direkt per WriteXML wegschreiben kannst ohne extra eine Kopie dieser zu erstellen. Ging schon immer einwandfrei.Ich vermute du machst in deinem Code einfach eine fehlerhafte Variablendeklaration und änderst die Quelle aus einem anderen Scope, deswegen geht es bei dir vermutlich nur per Kopie. Wenn man die Variablen im richtigen Scope deklariert und verwendet geht das auch ohne Kopie problemlos.
about_Scopes
Iteriere einfach über alle Rows deiner Datatable mit einer Schleife und weise deiner Hashtable die Werte wie oben zu, feddich ...
Beispiel:
Beispiel:
$data = @{}
$dt = New-Object System.Data.DataTable
$dt.TableName = "Daten"
[void]$dt.Columns.Add('Variable')
[void]$dt.Columns.Add('Typ')
[void]$dt.Columns.Add('Wert')
[void]$dt.Rows.Add(@('var01','string','Das ist ein String'))
[void]$dt.Rows.Add(@('var02','array','400,500,600'))
foreach ($r in $dt.Rows){
switch($r.Typ){
'int' {$data[$r.Variable] = [int]$r.Wert}
'array' {$data[$r.Variable] = [array]$r.Wert.Split(',')}
default {$data[$r.Variable] = [string]$r.Wert}
}
}
$data