feuervogt
Goto Top

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. face-wink

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()

screenshot_1
screenshot_2
screenshot_3
screenshot_4

Danke für etwaige Hilfe.

Jens

Content-ID: 8210454994

Url: https://administrator.de/contentid/8210454994

Ausgedruckt am: 22.11.2024 um 00:11 Uhr

CamelCase
CamelCase 22.05.2024 aktualisiert um 08:58:55 Uhr
Goto Top
Moin,

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 face-smile
Jugg3r
Jugg3r 22.05.2024 um 08:41:41 Uhr
Goto Top
öhm ...
Ich überflieg nur mal schnell und bin jetzt auch nicht der Crack, aber
ggf. die Klammern in 110 + 112 schließen?
Und es sieht aus, als wäre das array $global:userInfo Teil des Event handlers.

Viel Erfolg
feuervogt
feuervogt 22.05.2024 um 12:24:31 Uhr
Goto Top
Zitat von @CamelCase:

Moin,

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)



Danke für den Hinweis, die beiden Ausgaben habe ich tatsächlich übersehen, das lag wohl daran, dass ich das eine Skript in das andere kopiert habe, ohne vom ersten die Ausgabe zu entfernen.
feuervogt
feuervogt 22.05.2024 um 12:35:20 Uhr
Goto Top
Zitat von @Jugg3r:

öhm ...
Ich überflieg nur mal schnell und bin jetzt auch nicht der Crack, aber
ggf. die Klammern in 110 + 112 schließen?
Und es sieht aus, als wäre das array $global:userInfo Teil des Event handlers.

Viel Erfolg

Die beiden Klammern schließen jeweils in Zeile 163 (if Block) und 164 (die aus Zeile 110)

Das array muss ich noch schauen. Aber danke schonmal für den Tipp.
13034433319
Lösung 13034433319 23.05.2024 aktualisiert um 07:40:09 Uhr
Goto Top
Sorry, kleiner Copy n Paste Fehler passiert ...
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ß
feuervogt
feuervogt 24.05.2024 um 12:48:01 Uhr
Goto Top
Vielen Dank für Dein Script, der Ansatz geht ja in eine andere Richtung. Ich hatte meine Idee auch noch einmal geändert und den Eventhandler "getrennt".

Leider brachte weder das, noch Dein Skript die Lösung. In beiden Fällen bleibt es bei den fälschlicherweise ausgegeben Zahlen 0 bis 542 vor der "eigentlichen" Ausgabe. Hat vielleicht noch jemand eine Idee, woran es liegen könnte? Die Antwort:"An Deiner Blödheit.", akzeptiere ich auch, wenn mir erklärt wird, was so blöde ist. face-wink

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) {
            $global:userInfo = Get-UserInfo -samAccountName $selectedUser.Split('-')[-1].Trim()  
            $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 Get-UserInfo {
    param (
        [string]$samAccountName
    )

    $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"  
    }

    return @"  
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
"@  
}

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()
13034433319
13034433319 24.05.2024 aktualisiert um 15:30:02 Uhr
Goto Top
der Ansatz geht ja in eine andere Richtung.
Nö, nur gröbsten ineffizienten Shiet etwas optimiert umgesetzt face-wink.
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.
feuervogt
feuervogt 28.05.2024 um 08:33:26 Uhr
Goto Top
Ich habe Deinen Code per Copy and Paste übernommen, kann ihn also nicht verändert haben. Die Änderung in meinem Code, die Du ansprichst, hatte ich vorher schon vorgenommen. ich hatte natürlich Deinen Code nicht noch einmal hier gepostet, weil das ja redundant gewesen wäre. Und dass mein Code so miserabel ist, bitte ich zu entschuldigen, ich gelobe Besserung....

Gerade vor eben zehn Sekunden, habe ich Deinen Code noch einmal per copy and paste ausprobiert und bekomme trotzdem dieselbe vermasselte Ausgabe. Zu doof zum kopieren bin ich dann doch nicht. Wenn es bei Dir nicht bzu diesem Fehler kommt ist, scheint es wohl aus einem anderen Grund anders behandelt zu werden. Ich werde mal weitersuchen.

Ich habe gelesen, verstanden und ausprobiert! face-smile
13034433319
13034433319 28.05.2024 aktualisiert um 08:59:34 Uhr
Goto Top
Zitat von @feuervogt:

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)")  
Und genau das [void] ist hier nämlich der Knackpunkt damit keine Integer Indizes in den Ausgabe-Stream der Funktion geschrieben werden, das sind nämlich genau die "komischen" Zahlen die du im Dialog siehst, das sind einfach nur die Indizes der Funktion Items.Add die diese beim Hinzufügen aller deiner User (es sind wohl insgesamt 541) zurückgibt 😉! Jetzt verstanden?

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.
feuervogt
feuervogt 29.05.2024 um 07:40:53 Uhr
Goto Top
Hallo hempel,

natürlich unterscheidet sich der Code von Deinem. Wie ich ja schon angemerkt habe, hatte ich Deinen nicht noch einmal hier gepostet, weil ich das redundant fand. Ich hatte meinen Code schon geändert, BEVOR ich Deine Lösung sah und wollte das (meinen, zu dem Zeitpunkt, "neuen" Code) nur anmmerken, weil ich dachte, es würde nicht schaden. Aber wenn ich hier im Forum Deinen Code kopiere und unbearbeitet in meine Powershell einfüge, was ich getan habe und wovon Du logischerweise nichts mitbekommst (hoffe ich doch wenigstens....*smile*), dann ist die Ausgabe dennoch die gleiche. Und das irritiert mich eben. Ich danke Dir aber dennoch sehr für Deine Hilfe und dass Du Dir die Mühe machst, Dich mit mir auszutauschen, auch wenn Du vielleicht denkst, ich wäre lernresistent. Jedenfalls will ich unbedingt eine Lösung dafür finden, schon alleine, weil es anders gehen muss. Ich probiere nachher noch ein paar Ansätze aus, dummerweise muss ich zwischenzeitlich auch "normal" arbeiten. Wenn ich das Script "trenne", also die Abfrage ohne die Windows Form mit den Checkboxen laufen lasse, bekomme ich den Fehler nicht (jedenfalls war das so, ich muss das nachher noch einmal validieren). Verstanden, was Du mir sagen willst, habe ich schon, denke ich.
Aber wie gesagt, (ernsthaft) vielen Dank für Deine Hilfe!
feuervogt
feuervogt 29.05.2024 aktualisiert um 07:51:41 Uhr
Goto Top
Guten Morgen,

ich weiß, das klingt jetzt doof..... Ich habe das Ganze noch einmal versucht und jetzt geht es ohne Probleme. Ich habe aber tatsächlich nur Dein Script genauso in eine leere Powershell (in die ISE) kopiert, wie vorher.

Ich kann mir das eigentlich nicht vorstellen aber: ich habe ein normales MS Update auf dem DC gefahren. Daran wird es ja wohl nicht gelegen haben oder bin ich mittlerweile völlig verblödet?

Jedenfalls scheint es jetzt zu funktionieren und ich freue mich sehr, dass Deine Hilfe dazu beigetragen hat!!

Reicht es, wenn ich "Markiere als Lösung" auswähle oder muss ich hier noch schließen? Wenn ja, wie?
13034433319
13034433319 29.05.2024 aktualisiert um 07:55:23 Uhr
Goto Top
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.

✌️