Helpdesk AD Search Form

Hi,
I have this form i copied from another users code and doctored to our own helpdesk’s needs.

Powershell.exe -WindowStyle Hidden {


# Load the Winforms assembly
[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms")
 
# Create the form
$form = New-Object Windows.Forms.Form
$form_selectgroup = New-Object Windows.Forms.Form
 
# Create the tabcontrol
$tabcontrol = New-Object windows.Forms.TabControl
$tabpage_ad = New-Object windows.Forms.TabPage
$tabcontrol.width = 1150
$tabcontrol.Height = 540
 
#Set TabPages
$tabpage_ad.Text = "Active Directory Users"
 
#Set the dialog title
$form.text = "Active Directory Query tool"
$form.Width = 1150
$form.Height = 600
$form.FormBorderStyle = "FixedSingle"
$form.ControlBox = $false
 
# Create the label control and set text, size and location
$label_lastname_ad = New-Object Windows.Forms.Label
$label_lastname_ad.Location = New-Object Drawing.Point 10,50
$label_lastname_ad.Size = New-Object Drawing.Point 100,15
$label_lastname_ad.text = "Search lastname"
 
# Create TextBox and set text, size and location
$textfield_lastname_ad = New-Object Windows.Forms.TextBox
$textfield_lastname_ad.Location = New-Object Drawing.Point 110,45
$textfield_lastname_ad.Size = New-Object Drawing.Point 160,15
 
# create grids
$ad_grid = New-Object Windows.Forms.DataGridview
$ad_grid.DataBindings.DefaultDataSourceUpdateMode = 0
$ad_grid.Name = "grouplist"
$ad_grid.DataMember = ""
$ad_grid.TabIndex = 1
$ad_grid.Location = New-Object Drawing.Point 300,40
$ad_grid.Size = New-Object Drawing.Point 800,440
$ad_grid.readonly = $true
$ad_grid.AutoSizeColumnsMode = 'AllCells'
$ad_grid.SelectionMode = 'FullRowSelect'
$ad_grid.MultiSelect = $false
$ad_grid.RowHeadersVisible = $false
$ad_grid.allowusertoordercolumns = $true
 
# Create Button and set text and location
$button_exit = New-Object Windows.Forms.Button
$button_exit.text = "Exit"
$button_exit.Location = New-Object Drawing.Point 15,545
 
$button_searchad = New-Object Windows.Forms.Button
$button_searchad.Location = New-Object Drawing.Point 10,70
$button_searchad.Size = New-Object Drawing.Point 100,23
$button_searchad.text = "Query AD"
 
# Set up event handler to extarct text from TextBox and display it on the Label.
$button_searchad.add_click({
$grid = $ad_grid
$lnquery = "*"+$textfield_lastname_ad.Text.ToString()+"*"
search_contact_ad($lnquery)
})
 
$textfield_lastname_ad.add_KeyPress({
If ($_.KeyChar -eq 13) {
$grid = $ad_grid
$lnquery = "*"+$textfield_lastname_ad.Text.ToString()+"*"
search_contact_ad($lnquery)
}
})
 
$button_exit.add_click({
$form.Close()
})
 
# Add the controls to the Form
$form.Controls.Add($tabcontrol)
$form.controls.add($button_exit)
 
$tabcontrol.tabpages.add($tabpage_ad)
# $tabcontrol.tabpages.add($tabpage_sql)
 
$tabpage_ad.controls.add($label_lastname_ad)
$tabpage_ad.controls.add($textfield_lastname_ad)
$tabpage_ad.controls.add($button_searchad)
$tabpage_ad.controls.add($ad_grid)
 
$form.add_Load($OnLoadForm_UpdateGrid)
 
function search_contact_ad([string]$lastname_str){
if ($lastname_str) {
$array_ad = New-Object System.Collections.ArrayList
$Script:procInfo = @(Get-ADUser -Filter {sn -like $lastname_str} -Properties sn,givenname,mail,displayname,Telephonenumber,comment -SearchBase "DC=Test,DC=com" |sort-object -property sn |Select-Object @{Name="First Name";Expression={$_.givenname}},@{Name="Surname";Expression={$_.sn}},@{Name="Display Name";Expression={$_.displayname}},@{Name="Email";Expression={$_.mail}},@{Name="Extension";Expression={$_.Telephonenumber}},@{Name="PC Name";Expression={$_.comment}})
$array_ad.AddRange($procInfo)
$grid.DataSource = $array_ad
$form.refresh()
}
else {
[windows.forms.messagebox]::show('Please enter a lastname to search before clicking the button','Warning','OK',[Windows.Forms.MessageBoxIcon]::Warning)
}
}

# Display the dialog
$form.ShowDialog()
}

It basically returns the technician a couple of bits from a user’s AD properties. We have populated the ADUsers comment field with their most used PC.

What i want to do is to utilize the ‘Get-LoggedOnUser’ function (code below) to create another column telling the technician who is logged onto the computer in the AD user’s Comment field.
Get-LoggedOnUser Code

Function Get-LoggedOnUser{
param(
    [Parameter(Mandatory=$true, 
               ValueFromPipeline=$true,
               ValueFromPipelineByPropertyName=$true,  
               Position=0)]
    [Alias('ComputerName')]
    [string[]]$Name,
    [Parameter(Mandatory=$false, 
               Position=1)]
    [System.Management.Automation.PSCredential]$Credential
)
    BEGIN{
    }

    PROCESS{
    $wmi = @{
        'Class'        = 'Win32_Process';
        'Filter'       = 'Name = ''explorer.exe''';
        'ComputerName' = $Name
    }
    if($Credential){
        $wmi.Add('Credential',$Credential)
    }

        Get-WmiObject @wmi | %{
            [string]$user = $_.GetOwner().User
            $obj = New-Object -TypeName PSObject
            $obj | Add-Member -MemberType NoteProperty -Name User -Value $user

            Write-Output $obj
        }
    }

    END{
    }
}

In the midst of your function at the bottom of the script you posted, search_contact_ad, and before you define the variable $script, you should run the function to get the logged on user of the remote machine. Store the output in $loggedonUser

Then in the next line, at the end of the very long line of calculated properties, simply add your new column using the same syntax you see in all of the other properties, @(Name=ColumnHeading;Expression=$LoggedOnUser)

I’m mobile so this is a bit abbreviated but this is how to do it.

Merry Christmas!

Hi,

Thanks for getting back to me.

It doesn’t seem to work.

I see no errors and the form searches AD but doesn’t return me any logged on users.

Please help.

Regards

Joe

By editing the end of the $script line to:

{
@{Name="Logged On User";Expression={Get-LoggedOnUser -Name $_.comment}}
}

This works but the returned data isn’t formatted ideally. It comes out as: @{User=jbloggs}

Any ideas?

Thanks

Joe

First, you have to indent bro! Try this:

function search_contact_ad([string]$lastname_str){
    if ($lastname_str){
        $array_ad = New-Object System.Collections.ArrayList

        Get-ADUser -Filter {sn -like $lastname_str } -SearchBase "DC=Test,DC=com"  -Properties sn,givenname,mail,displayname,telephonenumber,comment | Sort-Object sn | ForEach-Object {
            $obj = New-Object PSObject -Property @{
                "FirstName" = $_.givenname
                "LastName" = $_.sn
                "DisplayName" = $_.displayname
                "Email" = $_.mail
                "Extension" = $_.telephonenumber
                "PCName" = $_.comment
                "PCUser" = (Get-LoggedOnUser $_.comment)
            } | Select-Object Lastname,FirstName,DisplayName,Email,PCName,PCUser
            $array_ad.Add($obj)
        }
        $grid.DataSource = $array_ad
        $form.Refresh()
    }
    else {
        [windows.forms.messagebox]::show('Please enter a lastname to search before clicking the button','Warning','OK',[Windows.Forms.MessageBoxIcon]::Warning)
    }
}

function Get-PingStatus($Computer){
    $Ping = New-Object System.Net.NetworkInformation.Ping
    try {
        $Ping.Send($Computer)
        $true
    }catch{
        $false
    }
}

function Get-LoggedOnUser([string]$Computer){
    if ($Computer.Length -gt 0){
        if (Get-PingStatus($Computer)){
            try {
                $Username = Get-WmiObject -ComputerName $Computer -Class Win32_ComputerSystem | select -Expand Username
                if ($Username -eq $null){ $Username = "Vacant" }
            } catch {
                $Username = "WMI Error"
            }
        } else {
            $Username = "PC offline"
        }
    } else {
        $Username = "PC name unidentified"
    }
    $Username
}

I re-wrote the $Script:procInfo because it was just messy and unclear to me and I didn’t use the ‘Get-LoggedOnUser’ script because it looks like was copied from the internet and not written specifically for your app. This version is tailored with some error control.

Hope this helps!

Wow!! Thank you!

I like how you’ve put that into an object to return the data for each.

You are correct on the ‘Get-LoggedOnUser’ script as i got it online and it gave me what i needed until now.

Many Thanks for this!!

Joe