简体   繁体   中英

How do I display this output in a label?

I'm trying to display the output of a script that searches domain controllers for accounts which have been locked into a label in a GUI I've created and running in to problems. I've been able to do this without problems with other scripts I've utilized, but this one is a little different and I am a complete novice and have been pulling my hair out trying to figure it out. When running the script by itself in Powershell, it outputs the information in a beautiful, easy to ready format but I can't get it to put that information into my label.

#LOCKOUT TRACE BUTTON
$Button16                         = New-Object system.Windows.Forms.Button
$Button16.text                    = "Lockout Trace"
$Button16.width                   = 85
$Button16.height                  = 30
$Button16.location                = New-Object 
System.Drawing.Point(105,113)
$ErrorActionPreference = 'SilentlyContinue'
$Button16.Add_Click(
{
$Label2.Text = ""
Import-Module ActiveDirectory
$UserName = $($TextBox1.Text)
#Get DCs
$PDC = (Get-ADDomainController -Discover -Service PrimaryDC).Name
$DCs = (Get-ADDomainController -Filter *).Name
#Get user info
$UserInfo = Get-ADUser -Identity $UserName
#Search PDC for lockout events with ID 4740
$LockedOutEvents = foreach ($DC in $DCs) { Get-WinEvent -ComputerName $DC 
-FilterHashtable @{LogName='Security';Id=4740} -ErrorAction Stop | Sort- 
Object -Property TimeCreated -Descending }
#Parse and filter out lockout events
Foreach($Event in $LockedOutEvents)
{
If($Event | Where {$_.Properties[2].value -match $UserInfo.SID.Value})
{

$Event | Select-Object -Property @( 
    @{Label = 'User'; Expression = {$_.Properties[0].Value}}
    @{Label = 'DomainController'; Expression = {$_.MachineName}}
    @{Label = 'EventId'; Expression = {$_.Id}}
    @{Label = 'LockoutTimeStamp'; Expression = {$_.TimeCreated}}
    @{Label = 'Message'; Expression = {$_.Message -split "`r" | Select - 
    First 1}}
    @{Label = 'LockoutSource'; Expression = {$_.Properties[1].Value}}
  )

}}
$Label2.Text = ("User = $($_.Properties[0].Value)
DomainController = $($_.MachineName)
EventID = $($_.ID)
LockoutTimeStamp = $($_.TimeCreated)
Message = $($_.Message -split "`r" | Select -First 1)
LockoutSource = $($_.Properties[1].Value)")
}
)
$main_form.Controls.Add($Button16)

In the code provided, it returns "User =" "DomainController =" "Event ID =" etc. on their own lines as expected, just without the data following. If I place "$Label2.Text =" before "Foreach($Event in $LockedOutEvents)", all the data is returned in the Label however it's all on one continuous line. I'd like it to output the data points on their own individual lines in the created label so I'm turning to the geniuses for help. This site has answered more than one of my questions on this journey and I'm hoping for another. Thanks in advance.

The code you show sometimes breaks at arbitrary places with newlines. I hope that is just from trying to format it in the question.

As for what I think you want, probably the best thing is to not use a Label object to show the results in the form, but instead use a multiline TextBox with scrollbars so you know the returned value wil always fit the form.

For now, I've left the $Label2 as is, but remodelled your $Button16.Add_Click() to this:

$Button16.Add_Click({
    $Label2.Text = ""
    $UserName = $TextBox1.Text
    # Try and get the user object from the name entered in the textbox
    $UserInfo = Get-ADUser -Identity $UserName
    if (!$UserInfo) {
        $Label2.Text = "$UserName not found!"
        return
    }

    # Get DCs
    ## $PDC = (Get-ADDomainController -Discover -Service PrimaryDC).Name
    $DCs = (Get-ADDomainController -Filter *).Name
    # Search DC's for lockout events with ID 4740
    $LockedOutEvents = foreach ($DC in $DCs) { 
        Get-WinEvent -ComputerName $DC -FilterHashtable @{LogName='Security';Id=4740} -ErrorAction SilentlyContinue | 
        Where {$_.Properties[2].value -match $UserInfo.SID} |
        Sort-Object -Property TimeCreated -Descending 
    }
    if ($LockedOutEvents) {
        # Parse and filter out lockout events. Collect the outputted string(s) in a variable
        # use 'Format-List | Out-String' to collect nicely formatted text
        $events = $LockedOutEvents | ForEach-Object {
            ($_ | Select-Object -Property @( 
                @{Name = 'User'; Expression = {$_.Properties[0].Value}}
                @{Name = 'DomainController'; Expression = {$_.MachineName}}
                @{Name = 'EventId'; Expression = {$_.Id}}
                @{Name = 'LockoutTimeStamp'; Expression = {$_.TimeCreated}}
                @{Name = 'Message'; Expression = {$_.Message -split '\r?\n' | Select-Object -First 1}}
                @{Name = 'LockoutSource'; Expression = {$_.Properties[1].Value}}
              ) | Format-List | Out-String).Trim()
        }
        # join the collected output and insert that into the label
        $Label2.Text = $events -join ([Environment]::NewLine * 2)
    }
    else {
        $Label2.Text = "No Lockout events found for user $UserName"
    }
})

The Import-Module ActiveDirectory line can be moved up to the top line in your script.

Hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM