Unerwartete Ausgabe einer PowerShell-Form
Hallo zusammen,
das ist mein erster Beitrag hier und ich hoffe, mich nicht allzu dämlich anzustellen. Im Ernstfall einfach draufhauen, ich brech dann weinend zusammen.
Ich möchte eine "Sammlung" nützlicher Powershellskripte für die tägliche Arbeit unter einer "Oberfläche" zusammenfassen. Es gib sicher schon einige Sammlungen, ich möchte es aber gerne selbst hinbekommen und gleichzeitig meine Kenntnisse in der Powershell vertiefen. So richtig warm bin ich mit der Powershell nämlich manchmal noch nicht.
Das Formular habe ich bereits erstellt und das erste Skript ebenfalls. Grundsätzlich machen beide auch, was sie sollen, allerdings bekomme ich in der Ausgabe des ersten (Unter)Skripts zusätzlich zu den gewünschten Ausgaben noch unnützes Zeugs. Es sieht für mich so aus, als würde irgendwo eine Zählschleife mit ausgegeben, ich bin aber zu blöd, sie zu erkennen. Im unten angefügten Beispiel ist es übrigens so, dass ich bei der Umleitung der Ausgabe in eine Datei alle Daten, auch die nicht gewollten Zahlen und bei der reinen Bildschirmausgabe erst die richtige Ausgabe und dann die vermasselte gleich hinterher bekomme. Ich würde mich freuen, wenn Ihr mir einen Schubs in die richtige Richtung geben könntet.
Anbei einmal das eigentliche Skript und die Ausgabe, die ich so nicht haben möchte. Ich denke, Ihr seht direkt, was ich meine.
Danke für etwaige Hilfe.
Jens
das ist mein erster Beitrag hier und ich hoffe, mich nicht allzu dämlich anzustellen. Im Ernstfall einfach draufhauen, ich brech dann weinend zusammen.
Ich möchte eine "Sammlung" nützlicher Powershellskripte für die tägliche Arbeit unter einer "Oberfläche" zusammenfassen. Es gib sicher schon einige Sammlungen, ich möchte es aber gerne selbst hinbekommen und gleichzeitig meine Kenntnisse in der Powershell vertiefen. So richtig warm bin ich mit der Powershell nämlich manchmal noch nicht.
Das Formular habe ich bereits erstellt und das erste Skript ebenfalls. Grundsätzlich machen beide auch, was sie sollen, allerdings bekomme ich in der Ausgabe des ersten (Unter)Skripts zusätzlich zu den gewünschten Ausgaben noch unnützes Zeugs. Es sieht für mich so aus, als würde irgendwo eine Zählschleife mit ausgegeben, ich bin aber zu blöd, sie zu erkennen. Im unten angefügten Beispiel ist es übrigens so, dass ich bei der Umleitung der Ausgabe in eine Datei alle Daten, auch die nicht gewollten Zahlen und bei der reinen Bildschirmausgabe erst die richtige Ausgabe und dann die vermasselte gleich hinterher bekomme. Ich würde mich freuen, wenn Ihr mir einen Schubs in die richtige Richtung geben könntet.
Anbei einmal das eigentliche Skript und die Ausgabe, die ich so nicht haben möchte. Ich denke, Ihr seht direkt, was ich meine.
Add-Type -AssemblyName System.Windows.Forms
# Form erstellen
$form = New-Object System.Windows.Forms.Form
$form.Text = "Script-Auswahl"
$form.Size = New-Object System.Drawing.Size(300, 450)
$form.StartPosition = "CenterScreen"
# Radiobuttons erstellen
$scripts = @(
"Skript 1: Benutzerinformationen abrufen",
"Skript 2: leer",
"Skript 3: leer",
"Skript 4: leer",
"Skript 5: leer",
"Skript 6: leer",
"Skript 7: leer",
"Skript 8: leer",
"Skript 9: leer",
"Skript 10: leer"
)
$yPos = 20
$radioButtons = @()
for ($i = 0; $i -lt $scripts.Count; $i++) {
$radioButton = New-Object System.Windows.Forms.RadioButton
$radioButton.Text = $scripts[$i]
$radioButton.Location = New-Object System.Drawing.Point(10, $yPos)
$radioButton.Size = New-Object System.Drawing.Size(250, 20)
$form.Controls.Add($radioButton)
$radioButtons += $radioButton
$yPos += 30
}
# Checkbox erstellen für Ausgabe in Datei speichern
$checkBoxSaveToFile = New-Object System.Windows.Forms.CheckBox
$checkBoxSaveToFile.Text = "Ausgabe in Datei speichern"
$checkBoxSaveToFile.Location = New-Object System.Drawing.Point(10, 320)
$checkBoxSaveToFile.Size = New-Object System.Drawing.Size(250, 20)
$form.Controls.Add($checkBoxSaveToFile)
# "Ausführen" Button erstellen
$buttonExecute = New-Object System.Windows.Forms.Button
$buttonExecute.Text = "Ausführen"
$buttonExecute.Location = New-Object System.Drawing.Point(10, 350)
$buttonExecute.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonExecute)
# "Abbrechen" Button erstellen
$buttonCancel = New-Object System.Windows.Forms.Button
$buttonCancel.Text = "Abbrechen"
$buttonCancel.Location = New-Object System.Drawing.Point(100, 350)
$buttonCancel.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonCancel)
# SaveFileDialog erstellen
$saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$saveFileDialog.Filter = "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*"
$saveFileDialog.Title = "Speicherort auswählen"
# Funktionen für die Skripte
function Execute-Script1 {
Import-Module ActiveDirectory
# GUI für die Benutzerauswahl mit Suchfeld
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Benutzer auswählen"
$form.Size = New-Object System.Drawing.Size(300, 400)
$form.StartPosition = "CenterScreen"
$searchBox = New-Object System.Windows.Forms.TextBox
$searchBox.Size = New-Object System.Drawing.Size(260, 20)
$searchBox.Location = New-Object System.Drawing.Point(10, 10)
$form.Controls.Add($searchBox)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Size = New-Object System.Drawing.Size(260, 270)
$listBox.Location = New-Object System.Drawing.Point(10, 40)
$form.Controls.Add($listBox)
$buttonOK = New-Object System.Windows.Forms.Button
$buttonOK.Text = "OK"
$buttonOK.Location = New-Object System.Drawing.Point(10, 320)
$buttonOK.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonOK)
$buttonCancelInner = New-Object System.Windows.Forms.Button
$buttonCancelInner.Text = "Abbrechen"
$buttonCancelInner.Location = New-Object System.Drawing.Point(195, 320)
$buttonCancelInner.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonCancelInner)
# ListBox mit Benutzern füllen
$users = Get-ADUser -Filter * -Property DisplayName, SamAccountName | Sort-Object DisplayName
foreach ($user in $users) {
if ($user.DisplayName) {
$listBox.Items.Add("$($user.DisplayName) - $($user.SamAccountName)")
}
}
# Variable für userInfo
$global:userInfo = ""
# Event handlers
$buttonOK.Add_Click({
$selectedUser = $listBox.SelectedItem
if ($selectedUser) {
$samAccountName = $selectedUser.Split('-')[-1].Trim()
$user = Get-ADUser -Identity $samAccountName -Properties DisplayName, GivenName, Surname, EmailAddress, TelephoneNumber, Department, LastLogonDate, LastLogoff, LogonCount, PasswordLastSet, PasswordExpired, msDS-UserPasswordExpiryTimeComputed, badPasswordTime
$passwordExpiryDate = $user."msDS-UserPasswordExpiryTimeComputed"
if ($passwordExpiryDate) {
try {
$passwordExpiryDate = [datetime]::FromFileTime($passwordExpiryDate)
} catch {
$passwordExpiryDate = "Unbekannt"
}
} else {
$passwordExpiryDate = "Unbekannt"
}
# Überprüfung der Anmeldeanzahl
$logonCount = $user.LogonCount
if ($logonCount -eq 65535) {
$logonCount = "Unbekannt oder nicht initialisiert"
}
# Letzter fehlerhafter Anmeldeversuch
$lastBadPasswordAttempt = $user.badPasswordTime
if ($lastBadPasswordAttempt) {
try {
$lastBadPasswordAttempt = [datetime]::FromFileTime($lastBadPasswordAttempt)
} catch {
$lastBadPasswordAttempt = "Unbekannt"
}
} else {
$lastBadPasswordAttempt = "Unbekannt"
}
$global:userInfo = @"
Name: $($user.Surname)
Vorname: $($user.GivenName)
E-Mail-Adresse: $($user.EmailAddress)
Telefonnummer: $($user.TelephoneNumber)
Abteilung: $($user.Department)
Letzte Anmeldezeit: $($user.LastLogonDate)
Letzte Abmeldezeit: $($user.LastLogoff)
Anmeldeanzahl: $logonCount
Passwort zuletzt geändert: $($user.PasswordLastSet)
Passwort gültig bis: $passwordExpiryDate
Letzter fehlerhafter Anmeldeversuch: $lastBadPasswordAttempt
"@
[System.Windows.Forms.MessageBox]::Show($global:userInfo, "Benutzerinformationen")
$form.Close()
} else {
[System.Windows.Forms.MessageBox]::Show("Bitte wählen Sie einen Benutzer aus.", "Fehler")
}
})
$buttonCancelInner.Add_Click({
$form.Close()
})
# Filterung der Nutzer anhand des Suchfelds
$searchBox.Add_TextChanged({
$listBox.Items.Clear()
$filter = $searchBox.Text
$filteredUsers = $users | Where-Object { $_.DisplayName -like "*$filter*" }
foreach ($user in $filteredUsers) {
$listBox.Items.Add("$($user.DisplayName) - $($user.SamAccountName)")
}
})
$form.Add_Shown({ $form.Activate() })
[void]$form.ShowDialog()
return $global:userInfo
}
function Execute-Script2 {
"Ausgabe von Skript 2"
}
function Execute-Script3 {
"Ausgabe von Skript 3"
}
function Execute-Script4 {
"Ausgabe von Skript 4"
}
function Execute-Script5 {
"Ausgabe von Skript 5"
}
function Execute-Script6 {
"Ausgabe von Skript 6"
}
function Execute-Script7 {
"Ausgabe von Skript 7"
}
function Execute-Script8 {
"Ausgabe von Skript 8"
}
function Execute-Script9 {
"Ausgabe von Skript 9"
}
function Execute-Script10 {
"Ausgabe von Skript 10"
}
# Button-Klick-Ereignis
$buttonExecute.Add_Click({
$output = $null # Initialisiere die Variable als Null
if ($radioButtons[0].Checked) {
$output = Execute-Script1
}
elseif ($radioButtons[1].Checked) {
$output = Execute-Script2
}
elseif ($radioButtons[2].Checked) {
$output = Execute-Script3
}
elseif ($radioButtons[3].Checked) {
$output = Execute-Script4
}
elseif ($radioButtons[4].Checked) {
$output = Execute-Script5
}
elseif ($radioButtons[5].Checked) {
$output = Execute-Script6
}
elseif ($radioButtons[6].Checked) {
$output = Execute-Script7
}
elseif ($radioButtons[7].Checked) {
$output = Execute-Script8
}
elseif ($radioButtons[8].Checked) {
$output = Execute-Script9
}
elseif ($radioButtons[9].Checked) {
$output = Execute-Script10
}
if ($checkBoxSaveToFile.Checked) {
if ($saveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
# Stelle sicher, dass nur die richtige Ausgabe in die Datei geschrieben wird
$output | Out-File -FilePath $saveFileDialog.FileName
[System.Windows.Forms.MessageBox]::Show("Ausgabe wurde in Datei gespeichert: " + $saveFileDialog.FileName)
}
} else {
[System.Windows.Forms.MessageBox]::Show($output)
}
})
# Abbrechen-Klick-Ereignis
$buttonCancel.Add_Click({
$form.Close()
})
# Form anzeigen
$form.Add_Shown({$form.Activate()})
[void] $form.ShowDialog()
Danke für etwaige Hilfe.
Jens
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 8210454994
Url: https://administrator.de/contentid/8210454994
Ausgedruckt am: 22.11.2024 um 00:11 Uhr
12 Kommentare
Neuester Kommentar
Moin,
die doppelten Messageboxen, wenn du nicht in ne Datei speicherst, kommen davon dass du zwei Messageboxen aufrufst,
einmal in Zeile 159:
Und dann nochmal nach Ende der Execute-Script1 Funktion in Zeile 263:
Bei den Nummern bin ich mir nicht sicher... hab gerade nicht die Zeit so ins Detail zu gehen
die doppelten Messageboxen, wenn du nicht in ne Datei speicherst, kommen davon dass du zwei Messageboxen aufrufst,
einmal in Zeile 159:
[System.Windows.Forms.MessageBox]::Show($global:userInfo, "Benutzerinformationen")
Und dann nochmal nach Ende der Execute-Script1 Funktion in Zeile 263:
[System.Windows.Forms.MessageBox]::Show($output)
Bei den Nummern bin ich mir nicht sicher... hab gerade nicht die Zeit so ins Detail zu gehen
Sorry, kleiner Copy n Paste Fehler passiert ...
Gruß
Add-Type -AssemblyName System.Windows.Forms
# Form erstellen
$form = New-Object System.Windows.Forms.Form
$form.Text = "Script-Auswahl"
$form.Size = New-Object System.Drawing.Size(300, 450)
$form.StartPosition = "CenterScreen"
# Radiobuttons mit zugewiesenen Script-Funktionen
$scripts = [ordered]@{
"Skript 1: Benutzerinformationen abrufen" = "Execute-Script1"
"Skript 2: leer" = "Execute-Script2"
"Skript 3: leer" = "Execute-Script3"
"Skript 4: leer" = "Execute-Script4"
"Skript 5: leer" = "Execute-Script5"
"Skript 6: leer" = "Execute-Script6"
"Skript 7: leer" = "Execute-Script7"
"Skript 8: leer" = "Execute-Script8"
"Skript 9: leer" = "Execute-Script9"
"Skript 10: leer" = "Execute-Script10"
}
$yPos = 20
$radioButtons = for ($i = 0; $i -lt $scripts.Count; $i++) {
$radioButton = New-Object System.Windows.Forms.RadioButton
$radioButton.Text = ([string[]]$scripts.Keys)[$i]
$radioButton.Location = New-Object System.Drawing.Point(10, $yPos)
$radioButton.Size = New-Object System.Drawing.Size(250, 20)
$form.Controls.Add($radioButton)
$yPos += 30
$radioButton
}
# Checkbox erstellen für Ausgabe in Datei speichern
$checkBoxSaveToFile = New-Object System.Windows.Forms.CheckBox
$checkBoxSaveToFile.Text = "Ausgabe in Datei speichern"
$checkBoxSaveToFile.Location = New-Object System.Drawing.Point(10, 320)
$checkBoxSaveToFile.Size = New-Object System.Drawing.Size(250, 20)
$form.Controls.Add($checkBoxSaveToFile)
# "Ausführen" Button erstellen
$buttonExecute = New-Object System.Windows.Forms.Button
$buttonExecute.Text = "Ausführen"
$buttonExecute.Location = New-Object System.Drawing.Point(10, 350)
$buttonExecute.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonExecute)
# "Abbrechen" Button erstellen
$buttonCancel = New-Object System.Windows.Forms.Button
$buttonCancel.Text = "Abbrechen"
$buttonCancel.Location = New-Object System.Drawing.Point(100, 350)
$buttonCancel.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonCancel)
# SaveFileDialog erstellen
$saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$saveFileDialog.Filter = "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*"
$saveFileDialog.Title = "Speicherort auswählen"
# Funktionen für die Skripte
function Execute-Script1 {
Import-Module ActiveDirectory
# GUI für die Benutzerauswahl mit Suchfeld
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Benutzer auswählen"
$form.Size = New-Object System.Drawing.Size(300, 400)
$form.StartPosition = "CenterScreen"
$form | Add-Member -Membertype Noteproperty -Name UserInfo -Value ""
$searchBox = New-Object System.Windows.Forms.TextBox
$searchBox.Size = New-Object System.Drawing.Size(260, 20)
$searchBox.Location = New-Object System.Drawing.Point(10, 10)
$form.Controls.Add($searchBox)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Size = New-Object System.Drawing.Size(260, 270)
$listBox.Location = New-Object System.Drawing.Point(10, 40)
$form.Controls.Add($listBox)
$buttonOK = New-Object System.Windows.Forms.Button
$buttonOK.Text = "OK"
$buttonOK.Location = New-Object System.Drawing.Point(10, 320)
$buttonOK.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonOK)
$buttonCancelInner = New-Object System.Windows.Forms.Button
$buttonCancelInner.Text = "Abbrechen"
$buttonCancelInner.Location = New-Object System.Drawing.Point(195, 320)
$buttonCancelInner.Size = New-Object System.Drawing.Size(75, 23)
$form.Controls.Add($buttonCancelInner)
# ListBox mit Benutzern füllen
$users = Get-ADUser -Filter * -Property DisplayName, SamAccountName | Sort-Object DisplayName
foreach ($user in $users) {
if ($user.DisplayName) {
[void]$listBox.Items.Add("$($user.DisplayName) - $($user.SamAccountName)")
}
}
# Event handlers
$buttonOK.Add_Click({
$selectedUser = $listBox.SelectedItem
if ($selectedUser) {
$samAccountName = $selectedUser.Split('-')[-1].Trim()
$user = Get-ADUser -Identity $samAccountName -Properties DisplayName, GivenName, Surname, EmailAddress, TelephoneNumber, Department, LastLogonDate, LastLogoff, LogonCount, PasswordLastSet, PasswordExpired, msDS-UserPasswordExpiryTimeComputed, badPasswordTime
$passwordExpiryDate = $user."msDS-UserPasswordExpiryTimeComputed"
if ($passwordExpiryDate) {
try {
$passwordExpiryDate = [datetime]::FromFileTime($passwordExpiryDate)
} catch {
$passwordExpiryDate = "Unbekannt"
}
} else {
$passwordExpiryDate = "Unbekannt"
}
# Überprüfung der Anmeldeanzahl
$logonCount = $user.LogonCount
if ($logonCount -eq 65535) {
$logonCount = "Unbekannt oder nicht initialisiert"
}
# Letzter fehlerhafter Anmeldeversuch
$lastBadPasswordAttempt = $user.badPasswordTime
if ($lastBadPasswordAttempt) {
try {
$lastBadPasswordAttempt = [datetime]::FromFileTime($lastBadPasswordAttempt)
} catch {
$lastBadPasswordAttempt = "Unbekannt"
}
} else {
$lastBadPasswordAttempt = "Unbekannt"
}
$form.userInfo = @"
Name: $($user.Surname)
Vorname: $($user.GivenName)
E-Mail-Adresse: $($user.EmailAddress)
Telefonnummer: $($user.TelephoneNumber)
Abteilung: $($user.Department)
Letzte Anmeldezeit: $($user.LastLogonDate)
Letzte Abmeldezeit: $($user.LastLogoff)
Anmeldeanzahl: $logonCount
Passwort zuletzt geändert: $($user.PasswordLastSet)
Passwort gültig bis: $passwordExpiryDate
Letzter fehlerhafter Anmeldeversuch: $lastBadPasswordAttempt
"@
$form.Close()
} else {
[void][System.Windows.Forms.MessageBox]::Show("Bitte wählen Sie einen Benutzer aus.", "Fehler")
}
})
$buttonCancelInner.Add_Click({
$form.Close()
})
# Filterung der Nutzer anhand des Suchfelds
$searchBox.Add_TextChanged({
$listBox.Items.Clear()
$filter = $searchBox.Text
$filteredUsers = $users | Where-Object { $_.DisplayName -like "*$filter*" }
foreach ($user in $filteredUsers) {
$listBox.Items.Add("$($user.DisplayName) - $($user.SamAccountName)")
}
})
$form.Add_Shown({ $form.Activate() })
[void]$form.ShowDialog()
return $form.userInfo
}
function Execute-Script2 {
"Ausgabe von Skript 2"
}
function Execute-Script3 {
"Ausgabe von Skript 3"
}
function Execute-Script4 {
"Ausgabe von Skript 4"
}
function Execute-Script5 {
"Ausgabe von Skript 5"
}
function Execute-Script6 {
"Ausgabe von Skript 6"
}
function Execute-Script7 {
"Ausgabe von Skript 7"
}
function Execute-Script8 {
"Ausgabe von Skript 8"
}
function Execute-Script9 {
"Ausgabe von Skript 9"
}
function Execute-Script10 {
"Ausgabe von Skript 10"
}
# Button-Klick-Ereignis
$buttonExecute.Add_Click({
$checked = $radioButtons | ? Checked
if (!$checked){
[System.Windows.Forms.MessageBox]::Show("Bitte eine Auswahl treffen","Keine Auswahl",0,48)
return
}
$output = $checked | %{
Invoke-Expression -command $scripts[$_.Text]
}
if ($checkBoxSaveToFile.Checked) {
if ($saveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
# Stelle sicher, dass nur die richtige Ausgabe in die Datei geschrieben wird
$output | Out-File -FilePath $saveFileDialog.FileName
[System.Windows.Forms.MessageBox]::Show("Ausgabe wurde in Datei gespeichert: " + $saveFileDialog.FileName)
}
} else {
[System.Windows.Forms.MessageBox]::Show($output)
}
})
# Abbrechen-Klick-Ereignis
$buttonCancel.Add_Click({
$form.Close()
})
# Form anzeigen
$form.Add_Shown({$form.Activate()})
[void] $form.ShowDialog()
Gruß
der Ansatz geht ja in eine andere Richtung.
Nö, nur gröbsten ineffizienten Shiet etwas optimiert umgesetzt .Leider brachte weder das, noch Dein Skript die Lösung.
Mein angepasstes Skript klappt hier einwandfrei ohne überflüssige Ausgaben! Hast du wohl falsch übernommen was man an deinem Skript sehen kann.Dein Problem sind vor allem die globalen Variablen, die sind böse und very bad practice und führen oft zu solchen Problemen die man sich damit einhandelt wie du, und vor allem wie du an meiner Anpassung sehen kannst, sind sie vollkommen überflüssig!!
Read, understand, then start practicing.
Zitat von @feuervogt:
Ich habe Deinen Code per Copy and Paste übernommen, kann ihn also nicht verändert haben.
Ich habe Deinen Code per Copy and Paste übernommen, kann ihn also nicht verändert haben.
Komisch ist aber das diese Zeile hier in deinem Code oben, sich von meiner unterscheidet:
$listBox.Items.Add("$($user.DisplayName) - $($user.SamAccountName)")
Da fehlt nämlich was, meine sieht oben nämlich so aus[void]$listBox.Items.Add("$($user.DisplayName) - $($user.SamAccountName)")
Liest du hier :
ListBox.ObjectCollection.Add(Object) Methode
Gibt zurück
Int32
Der nullbasierte Index des Elements in der Auflistung oder -1, wenn BeginUpdate() aufgerufen wurde.
Int32
Der nullbasierte Index des Elements in der Auflistung oder -1, wenn BeginUpdate() aufgerufen wurde.
Dein Script genauso in eine leere Powershell (in die ISE) kopiert, wie vorher.
Die ISE macht oft so einigen Schabernack den man nicht erwartet.Besser Vstudio-Code, notepad++ etc. benutzen, die ISE hat einige Bugs und Glitches die einem leicht auf die Füße fallen können, vor allem PS Neulingen.
✌️