PowerShell Import Text
Hallo,
ich habe mal eine Frage an die Profis. Ich erstelle gerade ein Script, welches den Arbeitsablauf beschleunigen und standardisieren soll. Dabei geht es um das Anlegen von Benutzer im AD inkl. Gruppenzuweisung und das Anlegen von Portgruppen im vCenter. Wenn ich das einzeln machen würde, hätte ich mir für jede dieser Aufgaben eine CSV Datei erstellt und diese entsprechend eingelesen. Damit es aber für die Kollegen handle bar ist, frage ich mich, ob diese Information nicht in einer Datei stehen können. Aus meiner Sicht besteht das Problem darin, dass die Anzahl der Benutzer oder eben der Portgruppen variable ist, so dass das selektieren der einzelnen Bereiche schwer fällt.
Die Datei hätte ich mir in etwa so vorgestellt:
Wie würdet Ihr solch eine Datensammlung und Verarbeitung lösen? Ist eine CSV vielleicht nicht das richtige oder gibt es bessere Möglichkeiten?
Gruß
derhoeppi
ich habe mal eine Frage an die Profis. Ich erstelle gerade ein Script, welches den Arbeitsablauf beschleunigen und standardisieren soll. Dabei geht es um das Anlegen von Benutzer im AD inkl. Gruppenzuweisung und das Anlegen von Portgruppen im vCenter. Wenn ich das einzeln machen würde, hätte ich mir für jede dieser Aufgaben eine CSV Datei erstellt und diese entsprechend eingelesen. Damit es aber für die Kollegen handle bar ist, frage ich mich, ob diese Information nicht in einer Datei stehen können. Aus meiner Sicht besteht das Problem darin, dass die Anzahl der Benutzer oder eben der Portgruppen variable ist, so dass das selektieren der einzelnen Bereiche schwer fällt.
Die Datei hätte ich mir in etwa so vorgestellt:
#ActiveDirectory
#Vorname, Nachname, Login
Max,Mustermann,MustermannMax
Karl,August,AugustKarl
#vCenter
#Bezeichnung,VlanID,PrivatVLANTag
LAN1,50,
Lan2,60,Promiscouse
Lan3,70,Isolated
Wie würdet Ihr solch eine Datensammlung und Verarbeitung lösen? Ist eine CSV vielleicht nicht das richtige oder gibt es bessere Möglichkeiten?
Gruß
derhoeppi
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 284092
Url: https://administrator.de/forum/powershell-import-text-284092.html
Ausgedruckt am: 15.05.2025 um 09:05 Uhr
8 Kommentare
Neuester Kommentar
Guten Abend @derhoeppi,
also ich persönlich würde das schon in zwei separate Files trennen, da das eine mit dem anderen hier ja eigentlich nicht viel gemeinsam hat.
Realisieren lässt sich sowas aber, wenn es unbedingt sein muss, problemlos mit Regular Expressions.
Z.b. lässt sich der folgende leicht abgewandelte Inhalt deiner Datei
mit diesem Code in zwei separate Objekte einlesen:
Der Code extrahiert via Regex deine zwei durch die speziellen Markierungen gesetzten Blöcke und schickt sie an Convertfrom-CSV um sie zu handelbaren Objekten zu konvertieren. Das ganze lässt sich natürlich nach Belieben erweitern.
Trotzdem wären mit zwei CSV wahrscheinlich lieber, da die Leute hier hinterher kein Copy n' Paste in das zusammenfassende File machen müssen. Aber das bleibt deinem Gusto überlassen
Grüße Uwe
also ich persönlich würde das schon in zwei separate Files trennen, da das eine mit dem anderen hier ja eigentlich nicht viel gemeinsam hat.
Realisieren lässt sich sowas aber, wenn es unbedingt sein muss, problemlos mit Regular Expressions.
Z.b. lässt sich der folgende leicht abgewandelte Inhalt deiner Datei
#ActiveDirectory-Start
Vorname,Nachname,Login
Max,Mustermann,MustermannMax
Karl,August,AugustKarl
#ActiveDirectory-End
#vCenter-Start
Bezeichnung,VlanID,PrivatVLANTag
LAN1,50,
Lan2,60,Promiscouse
Lan3,70,Isolated
#vCenter-End
$settings = gc 'c:\settings.txt' | out-string
$users = [regex]::match($settings,'(?ism)^#ActiveDirectory-Start\s*(.*?)#ActiveDirectory-End').Groups[1].Value | ConvertFrom-CSV -delimiter ","
$vCenter = [regex]::match($settings,'(?ism)^#vCenter-Start\s*(.*?)#vCenter-End').Groups[1].Value | ConvertFrom-CSV -delimiter ","
Trotzdem wären mit zwei CSV wahrscheinlich lieber, da die Leute hier hinterher kein Copy n' Paste in das zusammenfassende File machen müssen. Aber das bleibt deinem Gusto überlassen
Grüße Uwe
Zitat von @derhoeppi:
finde aber mehrere Dateien auch nicht schön, weil das editieren einer Datei schnell vergessen wird und dann werden Kommandos ausgeführt, die bereits ausgeführt wurden. Das wird natürlich abgefangen, aber glücklich wäre ich darüber nicht.
Dann mach dir halt eine simple GUI in der du deine User die CSV-Files aus dem Dateisystem auswählen lässt, welche du dann mit deinem Skript auf Gültigkeit prüfst und dann importierst.finde aber mehrere Dateien auch nicht schön, weil das editieren einer Datei schnell vergessen wird und dann werden Kommandos ausgeführt, die bereits ausgeführt wurden. Das wird natürlich abgefangen, aber glücklich wäre ich darüber nicht.
Da bist du als Programmierer gefragt das alles abzufangen.
Ebenso sollte man natürlich vor dem AD Import checken ob es einen User mit dem gleichen Namen schon gibt etc., das alles musst du bedenken, erst dann wird es absolut Wasser- und DAU-Fest.
Zum AD Import und Check habe ich hier ja schon diverse Skripte gepostet ... Einfach mal die Suche anschmeißen, dann findest du dazu diversen Input von mir.
Grüße Uwe
Ein veraltetes ListView verwenden ? Wir haben doch mit Powershell so schöne Controls wie das DataGridView 
#Form Function
function GenerateForm {
#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
#endregion
#region Form Objects
$form1 = New-Object System.Windows.Forms.Form
$btnOK = New-Object System.Windows.Forms.Button
$dgv = New-Object System.Windows.Forms.DataGridView
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects
#----------------------------------------------
# Event Script Blocks
#----------------------------------------------
$handler_btnOK_Click=
{
$dgv.Rows | ?{!$_.IsNewRow} | %{
$vorname = $_.Cells.Value
$nachname = $_.Cells[1].Value
$loginname = $_.Cells[2].Value
[System.Windows.Forms.MessageBox]::Show($vorname + " # " + $nachname + " # " + $loginname)
}
}
$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 = 214
$System_Drawing_Size.Width = 359
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$form1.Name = "form1"
$form1.Text = "Demo"
$btnOK.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 272
$System_Drawing_Point.Y = 180
$btnOK.Location = $System_Drawing_Point
$btnOK.Name = "btnOK"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 75
$btnOK.Size = $System_Drawing_Size
$btnOK.TabIndex = 1
$btnOK.Text = "OK"
$btnOK.Anchor = 10
$btnOK.UseVisualStyleBackColor = $True
$btnOK.add_Click($handler_btnOK_Click)
$form1.Controls.Add($btnOK)
$dgv.Anchor = 15
$System_Windows_Forms_DataGridViewTextBoxColumn_4 = New-Object System.Windows.Forms.DataGridViewTextBoxColumn
$System_Windows_Forms_DataGridViewTextBoxColumn_4.AutoSizeMode = 16
$System_Windows_Forms_DataGridViewTextBoxColumn_4.HeaderText = "Vorname"
$System_Windows_Forms_DataGridViewTextBoxColumn_4.Name = ""
$System_Windows_Forms_DataGridViewTextBoxColumn_4.Width = 97
$dgv.Columns.Add($System_Windows_Forms_DataGridViewTextBoxColumn_4)|Out-Null
$System_Windows_Forms_DataGridViewTextBoxColumn_5 = New-Object System.Windows.Forms.DataGridViewTextBoxColumn
$System_Windows_Forms_DataGridViewTextBoxColumn_5.AutoSizeMode = 16
$System_Windows_Forms_DataGridViewTextBoxColumn_5.HeaderText = "Nachname"
$System_Windows_Forms_DataGridViewTextBoxColumn_5.Name = ""
$System_Windows_Forms_DataGridViewTextBoxColumn_5.Width = 98
$dgv.Columns.Add($System_Windows_Forms_DataGridViewTextBoxColumn_5)|Out-Null
$System_Windows_Forms_DataGridViewTextBoxColumn_6 = New-Object System.Windows.Forms.DataGridViewTextBoxColumn
$System_Windows_Forms_DataGridViewTextBoxColumn_6.AutoSizeMode = 16
$System_Windows_Forms_DataGridViewTextBoxColumn_6.HeaderText = "Loginname"
$System_Windows_Forms_DataGridViewTextBoxColumn_6.Name = ""
$System_Windows_Forms_DataGridViewTextBoxColumn_6.Width = 97
$dgv.Columns.Add($System_Windows_Forms_DataGridViewTextBoxColumn_6)|Out-Null
$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 = 162
$System_Drawing_Size.Width = 335
$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
#Call the Function
GenerateForm
Falls du es doch mit einem ListView machen willst hier beide Varianten in einer Form:
Dann hast du die Qual der Wahl
Zur Info und deiner Frage: Zum Hinzufügen eines ListView-Items mit dessen Subitems kannst du eine verkürzte Variante nehmen:
Dann hast du die Qual der Wahl
Zur Info und deiner Frage: Zum Hinzufügen eines ListView-Items mit dessen Subitems kannst du eine verkürzte Variante nehmen:
$deinListView.Items.Add("Max").SubItems.AddRange(@("Muster","mmuster"))
#Generated Form Function
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
$btnAddItem = New-Object System.Windows.Forms.Button
$lv = New-Object System.Windows.Forms.ListView
$btnOK = New-Object System.Windows.Forms.Button
$dgv = New-Object System.Windows.Forms.DataGridView
$columnHeader1 = New-Object System.Windows.Forms.ColumnHeader
$columnHeader2 = New-Object System.Windows.Forms.ColumnHeader
$columnHeader3 = New-Object System.Windows.Forms.ColumnHeader
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects
#----------------------------------------------
#Generated Event Script Blocks
#----------------------------------------------
$handler_btnOK_Click=
{
$dgv.Rows | ?{!$_.IsNewRow} | %{
$vorname = $_.Cells.Value
$nachname = $_.Cells[1].Value
$loginname = $_.Cells[2].Value
[System.Windows.Forms.MessageBox]::Show($vorname + " # " + $nachname + " # " + $loginname)
}
}
$handler_btnAddItem_Click=
{
$lv.Items.Add("Max").SubItems.AddRange(@("Muster","mmuster"))
}
$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 = 356
$System_Drawing_Size.Width = 435
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$form1.FormBorderStyle = 3
$form1.MaximizeBox = $False
$form1.Name = "form1"
$form1.SizeGripStyle = 2
$form1.Text = "Demo"
$btnAddItem.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 292
$System_Drawing_Point.Y = 321
$btnAddItem.Location = $System_Drawing_Point
$btnAddItem.Name = "btnAddItem"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 131
$btnAddItem.Size = $System_Drawing_Size
$btnAddItem.TabIndex = 3
$btnAddItem.Text = "Item hinzufügen"
$btnAddItem.UseVisualStyleBackColor = $True
$btnAddItem.add_Click($handler_btnAddItem_Click)
$form1.Controls.Add($btnAddItem)
$lv.Columns.Add($columnHeader1)|Out-Null
$lv.Columns.Add($columnHeader2)|Out-Null
$lv.Columns.Add($columnHeader3)|Out-Null
$lv.DataBindings.DefaultDataSourceUpdateMode = 0
$lv.FullRowSelect = $True
$lv.HideSelection = $False
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 198
$lv.Location = $System_Drawing_Point
$lv.Name = "lv"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 117
$System_Drawing_Size.Width = 411
$lv.Size = $System_Drawing_Size
$lv.TabIndex = 2
$lv.UseCompatibleStateImageBehavior = $False
$lv.View = 1
$form1.Controls.Add($lv)
$btnOK.Anchor = 10
$btnOK.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 292
$System_Drawing_Point.Y = 165
$btnOK.Location = $System_Drawing_Point
$btnOK.Name = "btnOK"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 131
$btnOK.Size = $System_Drawing_Size
$btnOK.TabIndex = 1
$btnOK.Text = "Collection auflisten"
$btnOK.UseVisualStyleBackColor = $True
$btnOK.add_Click($handler_btnOK_Click)
$form1.Controls.Add($btnOK)
$System_Windows_Forms_DataGridViewTextBoxColumn_19 = New-Object System.Windows.Forms.DataGridViewTextBoxColumn
$System_Windows_Forms_DataGridViewTextBoxColumn_19.AutoSizeMode = 16
$System_Windows_Forms_DataGridViewTextBoxColumn_19.HeaderText = "Vorname"
$System_Windows_Forms_DataGridViewTextBoxColumn_19.Name = ""
$System_Windows_Forms_DataGridViewTextBoxColumn_19.Width = 123
$dgv.Columns.Add($System_Windows_Forms_DataGridViewTextBoxColumn_19)|Out-Null
$System_Windows_Forms_DataGridViewTextBoxColumn_20 = New-Object System.Windows.Forms.DataGridViewTextBoxColumn
$System_Windows_Forms_DataGridViewTextBoxColumn_20.AutoSizeMode = 16
$System_Windows_Forms_DataGridViewTextBoxColumn_20.HeaderText = "Nachname"
$System_Windows_Forms_DataGridViewTextBoxColumn_20.Name = ""
$System_Windows_Forms_DataGridViewTextBoxColumn_20.Width = 122
$dgv.Columns.Add($System_Windows_Forms_DataGridViewTextBoxColumn_20)|Out-Null
$System_Windows_Forms_DataGridViewTextBoxColumn_21 = New-Object System.Windows.Forms.DataGridViewTextBoxColumn
$System_Windows_Forms_DataGridViewTextBoxColumn_21.AutoSizeMode = 16
$System_Windows_Forms_DataGridViewTextBoxColumn_21.HeaderText = "Loginname"
$System_Windows_Forms_DataGridViewTextBoxColumn_21.Name = ""
$System_Windows_Forms_DataGridViewTextBoxColumn_21.Width = 123
$dgv.Columns.Add($System_Windows_Forms_DataGridViewTextBoxColumn_21)|Out-Null
$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 = 147
$System_Drawing_Size.Width = 411
$dgv.Size = $System_Drawing_Size
$dgv.TabIndex = 0
$form1.Controls.Add($dgv)
$columnHeader1.Text = "Vorname"
$columnHeader1.Width = 108
$columnHeader2.Text = "Nachname"
$columnHeader2.Width = 99
$columnHeader3.Text = "Loginname"
$columnHeader3.Width = 112
#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
#Call the Function
GenerateForm
WPF ist kein Windows Forms deswegen geht das obige von mir dort so nicht. Zu WPF und Powershell habe ich hier schon etwas gepostet:
WPF Oberflächen mit Powershell
Bei WPF gibt es nur das DataGrid und das ist kein DataGridView, das sollte nur über eine Datenquelle gesteuert werden. Manuell kommt es zu deinem beobachteten Crash.
Hier ein Beispiel:
Aber das ist ja nun ein ganz anderes Thema als der Ursprungsthreads. Bitte eine neue Frage dazu erstellen. Danke.
Grüße Uwe
WPF Oberflächen mit Powershell
Bei WPF gibt es nur das DataGrid und das ist kein DataGridView, das sollte nur über eine Datenquelle gesteuert werden. Manuell kommt es zu deinem beobachteten Crash.
Hier ein Beispiel:
Add-Type -AssemblyName Presentationframework
[string]$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Window" Title="Mein Fenster" WindowStartupLocation = "CenterScreen" ResizeMode="NoResize" SizeToContent = "WidthAndHeight" ShowInTaskbar = "True" Background = "lightgray">
<StackPanel>
<DataGrid x:Name="LV_User" HorizontalAlignment="Left" Height="195.723" Margin="10,10,0,0" VerticalAlignment="Top" Width="253.566" Grid.ColumnSpan="2" AutoGenerateColumns="True">
</DataGrid>
</StackPanel>
</Window>
"@
# Markup laden
$window=[Windows.Markup.XamlReader]::Parse($xaml)
# DataGrid
$dgv = $window.FindName('LV_User')
# DataTable erstellen
$dt = new-Object System.Data.DataTable
[void]$dt.Columns.Add("Vorname")
[void]$dt.Columns.Add("Nachname")
[void]$dt.Columns.Add("Loginname")
# Row zur DataTable hinzufügen
$dt.Rows.Add(@("Max","Muster","mmustermann"))
# DataTable dem DataGrid als Quelle zuweisen
$dgv.ItemsSource = $dt.DefaultView
$async = $window.Dispatcher.InvokeAsync({$window.ShowDialog() | Out-Null})
$async.Wait() | Out-Null
Aber das ist ja nun ein ganz anderes Thema als der Ursprungsthreads. Bitte eine neue Frage dazu erstellen. Danke.
Grüße Uwe