GUI - Display data - table format - color? how?

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
User avatar
lontru
Posts: 48
Joined: Fri Aug 18, 2017 4:36 am

Re: GUI - Display data - table format - color? how?

Post by lontru » Fri Nov 16, 2018 2:01 pm

Was it something like this you had in mind? creating a custom object with all the data

Code: Select all

function Get-sysinfo ($ComputerName)
{
	$sysCompp = Get-WmiObject Win32_ComputerSystemProduct -ComputerName $ComputerName
	$sysComp = Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName
	$sysOS = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName
	$sysBIOS = Get-WmiObject Win32_BIOS -ComputerName $ComputerName
	$sysCPU = Get-WmiObject Win32_Processor -ComputerName $ComputerName
	$sysRAM = Get-WmiObject Win32_PhysicalMemory -ComputerName $ComputerName
	$sysNAC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -Filter "IPEnabled='True'"
	$sysMon = Get-WmiObject Win32_DesktopMonitor -ComputerName $ComputerName
	$sysVid = Get-WmiObject Win32_VideoController -ComputerName $ComputerName
	$sysOD = Get-WmiObject Win32_CDROMDrive -ComputerName $ComputerName
	$sysHD = Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
	$sysProc = Get-WmiObject Win32_Process -ComputerName $ComputerName
	
    $sysinfo = @()

    ### General #####################################
    $customobject = [pscustomobject]@{
        Property = "Computer Name"
        Value = "$($sysCompp.PSComputerName)"
        Group = 'General'
    }
    $sysinfo += $customobject

    $customobject = [pscustomobject]@{
        Property = "Last Restart"
        Value = "$($sysOS.ConvertToDateTime($sysOS.LastBootUpTime))"
        Group = 'General'
    }
    $sysinfo += $customobject
	
	### Build Info #####################################
    $customobject = [pscustomobject]@{
        Property = "Manufactorer"
        Value = "$($sysCompp.Vendor)"
        Group = 'Build Info'
    }
    $sysinfo += $customobject

    $customobject = [pscustomobject]@{
        Property = "Model"
        Value = "$($sysCompp.Version)"
        Group = 'Build Info'
    }
    $sysinfo += $customobject

    $customobject = [pscustomobject]@{
        Property = "Name"
        Value = "$($sysCompp.Name)"
        Group = 'Build Info'
    }
    $sysinfo += $customobject
	
	### Operating System #####################################
    $customobject = [pscustomobject]@{
        Property = "OS"
        Value = "$($sysOS.Caption)"
        Group = 'Operating System'
    }
    $sysinfo += $customobject

    $customobject = [pscustomobject]@{
        Property = "Service Pack"
        Value = "$($sysOS.CSDVersion)"
        Group = 'Operating System'
    }
    $sysinfo += $customobject

    $customobject = [pscustomobject]@{
        Property = "Version"
        Value = "$($sysOS.Version)"
        Group = 'Operating System'
    }
    $sysinfo += $customobject
    
    $customobject = [pscustomobject]@{
        Property = "Version"
        Value = "$($sysOS.Version)"
        Group = 'Operating System'
    }
    $sysinfo += $customobject

    $customobject = [pscustomobject]@{
        Property = "OS Architecture"
        Value = "$($sysOS.OSArchitecture)"
        Group = 'Operating System'
    }
    $sysinfo += $customobject
	
    $customobject = [pscustomobject]@{
        Property = "Install Date"
        Value = "$($sysOS.ConvertToDateTime($sysOS.InstallDate))"
        Group = 'Operating System'
    }
    $sysinfo += $customobject

	### Hardware #####################################
    $customobject = [pscustomobject]@{
        Property = "CPU"
        Value = "$($sysCPU.Name)"
        Group = 'Hardware'
    }
    $sysinfo += $customobject
    
    $tRAM = "{0:N2} GB Usable - " -f $($sysComp.TotalPhysicalMemory / 1GB)
	$sysRAM | %{ $tRAM += "[$($_.Capacity / 1GB)]" }
    $customobject = [pscustomobject]@{
        Property = "RAM"
        Value = "$tRAM"
        Group = 'Hardware'
    }
    $sysinfo += $customobject

    	$sysHD | Where-Object { $_.DriveType -eq 3 } | %{
		$HDD++
		$HDInfo = "{0} {1} {2:N1} GB Free / {3:N1} GB Total" -f $_.DeviceID, $_.FileSystem, ($_.FreeSpace / 1GB), ($_.Size / 1GB)
        $customobject = [pscustomobject]@{
            Property = "HD[$HDD]"
            Value = "$HDInfo"
            Group = 'Hardware'
        }
        $sysinfo += $customobject
	}
	$sysOD | %{
		$OpDrive++
        $customobject = [pscustomobject]@{
            Property = "[$OpDrive++]Optical Drive"
            Value = "$($sysOD.Drive) $($sysOD.Caption)"
            Group = 'Hardware'
        }
        $sysinfo += $customobject
	}

	$Monitors = $null
	$sysMON | %{ $Monitors += "[{0} x {1}] " -f $_.ScreenWidth, $_.ScreenHeight }

    $customobject = [pscustomobject]@{
        Property = "Monitor(s)"
        Value = "$Monitors"
        Group = 'Hardware'
    }
    $sysinfo += $customobject
	
	## Network Adapters
	$sysNAC | %{
		$NAC++
        $customobject = [pscustomobject]@{
            Property = "Description[$NAC]"
            Value = "$($_.Description)"
            Group = 'Network Adapters'
        }
        $sysinfo += $customobject
        $customobject = [pscustomobject]@{
            Property = "IPAddress[$NAC]"
            Value = "$($_.IPAddress)"
            Group = 'Network Adapters'
        }
        $sysinfo += $customobject
        $customobject = [pscustomobject]@{
            Property = "MACAddress[$NAC]"
            Value = "$($_.MACAddress)"
            Group = 'Network Adapters'
        }
        $sysinfo += $customobject
	}
	
	return $sysinfo
}

$info = Get-sysinfo $env:computername




User avatar
jvierra
Posts: 13182
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: GUI - Display data - table format - color? how?

Post by jvierra » Fri Nov 16, 2018 2:11 pm

That is the same code I asked you to turn into an object collection. Now just convert the collection to a DataTable or change it to create a DataTable.
Create the table and columns and add each item to the table as a row.

$dt.Rows.Add($property, $value, $group)

Add the DataTable to the DGV DataSource property.

Or …

Convert the object collection to a DataTable as such:

$datagridview1.DataSource = ConvertTo-DataTable $info

User avatar
lontru
Posts: 48
Joined: Fri Aug 18, 2017 4:36 am

Re: GUI - Display data - table format - color? how?

Post by lontru » Sun Nov 18, 2018 12:28 pm

i be using the Load-ListView. Cause i want the grouped layout.

Here the final result for other who want to walk the same way ;D
Attachments
get-sysinfo_pscustom.psf
(31.01 KiB) Downloaded 8 times

User avatar
jvierra
Posts: 13182
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: GUI - Display data - table format - color? how?

Post by jvierra » Sun Nov 18, 2018 1:18 pm

Note. You don't have to do this:

Value = "$($sysCompp.Version)"

Just assign directly:
Value = $sysCompp.Version

It is never necessary to add quotes when assigning values to a property. It is then not necessary to use a subexpression evaluator to extract a property.

This is how to use cariables and properties in your event:

Code: Select all

$buttonGetinfo_Click={
	if ([string]::IsNullOrEmpty($textbox1.Text)){
		$textbox1.Text = $env:computername
	}
	
	$sysinfo = GetSysInfo $textbox1.Text
	Load-ListView $sysinfo
}
The object generator only need to generate objects there is no need to collect them in an array. They will be the output of the function.

The same is true of this and reorder the operations to make the code cleaner and easier to read and understand:

Code: Select all

function Load-ListView ($collection){
    
	$listview1.Items.Clear()
	foreach ($iteminfo in $collection){
        
		# add a list item
		$item = New-Object System.Windows.Forms.ListViewItem
		$listview1.Items.Add($item)
		$item.Text = $iteminfo.Property
		$item.Name = 'Property'
		$item.Group = $listview1.Groups[$iteminfo.Group]
		
		# add subitems
		$subitem = New-Object System.Windows.Forms.ListViewItem+ListViewSubItem
		$subitem.Text = $iteminfo.Value
		$subitem.Name = 'Value'
		$item.SubItems.Add($subitem)
		
	}
}
The object generator should be like this:

Code: Select all

function Get-sysinfo ($ComputerName){
	$sysOS = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName
	$sysBIOS = Get-WmiObject Win32_BIOS -ComputerName $ComputerName
	$sysCPU = Get-WmiObject Win32_Processor -ComputerName $ComputerName
	$sysRAM = Get-WmiObject Win32_PhysicalMemory -ComputerName $ComputerName
	$sysNAC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -Filter "IPEnabled='True'"
	$sysMon = Get-WmiObject Win32_DesktopMonitor -ComputerName $ComputerName
	$sysVid = Get-WmiObject Win32_VideoController -ComputerName $ComputerName
	$sysOD = Get-WmiObject Win32_CDROMDrive -ComputerName $ComputerName
	$sysHD = Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
	$sysProc = Get-WmiObject Win32_Process -ComputerName $ComputerName
	
	### General #####################################
    $sysComp = Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName
	[pscustomobject]@{
		Property = "Computer Name"
		Value    = $sysComp.PSComputerName
		Group    = 'General'
	}
	$sysinfo += $customobject
	
	[pscustomobject]@{
		Property = "Last Restart"
		Value    = $sysOS.ConvertToDateTime($sysOS.LastBootUpTime)
		Group    = 'General'
	}
	
	### Build Info #####################################
	[pscustomobject]@{
		Property = "Manufactorer"
		Value    = $sysComp.Vendor
		Group    = 'Build Info'
	}
	
	[pscustomobject]@{
		Property = "Model"
		Value    = $sysComp.Version
		Group    = 'Build Info'
	}
	
	[pscustomobject]@{
		Property = "Name"
		Value    = $sysComp.Name
		Group    = 'Build Info'
	}
	
	### Operating System #####################################
	[pscustomobject]@{
		Property = "OS"
		Value    = $sysOS.Caption
		Group    = 'Operating System'
	}
	
	[pscustomobject]@{
		Property = "Service Pack"
		Value    = $sysOS.CSDVersion
		Group    = 'Operating System'
	}
		
	[pscustomobject]@{
		Property = "Version"
		Value    = $sysOS.Version
		Group    = 'Operating System'
	}
	
	[pscustomobject]@{
		Property = "OS Architecture"
		Value    = $sysOS.OSArchitecture
		Group    = 'Operating System'
	}
	
	[pscustomobject]@{
		Property = "Install Date"
		Value    = $sysOS.ConvertToDateTime($sysOS.InstallDate)
		Group    = 'Operating System'
	}
	
	### Hardware #####################################
	[pscustomobject]@{
		Property = "CPU"
		Value    = $sysCPU.Name
		Group    = 'Hardware'
	}
	
	$tRAM = "{0:N2} GB Usable - " -f $($sysComp.TotalPhysicalMemory / 1GB)
	$sysRAM | %{ $tRAM += "[$($_.Capacity / 1GB)]" }
	[pscustomobject]@{
		Property = "RAM"
		Value    = "$tRAM"
		Group    = 'Hardware'
	}
	
	$sysHD | Where-Object { $_.DriveType -eq 3 } | %{
		$HDD++
		$HDInfo = "{0} {1} {2:N1} GB Free / {3:N1} GB Total" -f $_.DeviceID, $_.FileSystem, ($_.FreeSpace / 1GB), ($_.Size / 1GB)
		[pscustomobject]@{
			Property = "HD[$HDD]"
			Value    = "$HDInfo"
			Group    = 'Hardware'
		}
	}
    
	$sysOD | %{
		$OpDrive++
		[pscustomobject]@{
			Property = "[$OpDrive++]Optical Drive"
			Value    = "$($sysOD.Drive) $($sysOD.Caption)"
			Group    = 'Hardware'
		}
	}
	
	$Monitors = $null
	$sysMON | %{ $Monitors += "[{0} x {1}] " -f $_.ScreenWidth, $_.ScreenHeight }
	
	[pscustomobject]@{
		Property = "Monitor(s)"
		Value    = "$Monitors"
		Group    = 'Hardware'
	}
	
	## Network Adapters
	$sysNAC | %{
		$NAC++
		[pscustomobject]@{
			Property = "Description[$NAC]"
			Value    = $_.Description
			Group    = 'Network Adapters'
		}
		[pscustomobject]@{
			Property = "IPAddress[$NAC]"
			Value    = $_.IPAddress
			Group    = 'Network Adapters'
		}
		[pscustomobject]@{
			Property = "MACAddress[$NAC]"
			Value    = $_.MACAddress
			Group    = 'Network Adapters'
		}
	}
}
It removes a lot of confusion with the code. If you used tags this would also be greatly simplified. You have all of the infor in "Get-SysInfo" which is where you should just add it to the ListView and not save the objects. Just create a function to add subitems as you query for them.

Your project looks good even with the suggestions. Keep working and you will get good with Forms. I recommend solidifying your PowerShell by taking the following tutorial until you clearly understand what it is showing you about PowerShell.

https://mva.microsoft.com/en-us/training-courses/getting-started-with-microsoft-powershell-8276?l=r54IrOWy_2304984382

Again. Very good job. Keep PosHing.

User avatar
jvierra
Posts: 13182
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: GUI - Display data - table format - color? how?

Post by jvierra » Sun Nov 18, 2018 1:32 pm

For future reference. Here is how to further simplify the build process.

This function does al of the item creation:

Code: Select all

function Add-ListViewSubItems{
    param(
        $Property,
        $Value,
        $Group
    )

    $item = New-Object System.Windows.Forms.ListViewItem
	$listview1.Items.Add($item)
	$item.Text = $Property
	$item.Name = 'Property'
	$item.Group = $listview1.Groups[$Group]
		
    $subitem = New-Object System.Windows.Forms.ListViewItem+ListViewSubItem
    $subitem.Text = $Value
    $subitem.Name = 'Value'
    $item.SubItems.Add($subitem)
		
}
This makes the loading trivial and easier to understand.

Code: Select all

function Get-sysinfo ($ComputerName){
    
    $sysComp = Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName
	$sysOS = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName
	$sysBIOS = Get-WmiObject Win32_BIOS -ComputerName $ComputerName
	$sysCPU = Get-WmiObject Win32_Processor -ComputerName $ComputerName
	$sysRAM = Get-WmiObject Win32_PhysicalMemory -ComputerName $ComputerName
	$sysNAC = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -Filter "IPEnabled='True'"
	$sysMon = Get-WmiObject Win32_DesktopMonitor -ComputerName $ComputerName
	$sysVid = Get-WmiObject Win32_VideoController -ComputerName $ComputerName
	$sysOD = Get-WmiObject Win32_CDROMDrive -ComputerName $ComputerName
	$sysHD = Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
	$sysProc = Get-WmiObject Win32_Process -ComputerName $ComputerName
	
	### General #####################################
    Add-ListViewSubItems -Property 'Computer Name' -Value $sysComp.PSComputerName -Group General
    Add-ListViewSubItems -Property 'Last Restart' -Value $sysOS.ConvertToDateTime($sysOS.LastBootUpTime) -Group General
	
	### Build Info #####################################
    Add-ListViewSubItems -Property Manufactorer -Value $$sysComp.Vendor -Group 'Build Info'
    Add-ListViewSubItems -Property Model -Value $$sysComp.Version -Group 'Build Info'
    Add-ListViewSubItems -Property Name -Value $sysComp.Name -Group 'Build Info'
	
	### Operating System #####################################
    Add-ListViewSubItems -Property OS -Value $$sysComp.Caption -Group 'Operating System'
    
    # add all of the other elements
 

User avatar
jvierra
Posts: 13182
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: GUI - Display data - table format - color? how?

Post by jvierra » Sun Nov 18, 2018 1:42 pm

We can now also do this and have the groups auto-generated:

Code: Select all

function Add-ListViewSubItems{
    param(
        $Property,
        $Value,
        $GroupName
    )
    
    if(-not $listview1.Groups[$Group]){
        $lvGroup = [System.Windows.Forms.ListViewGroup]::New($GroupName,$GroupName)
        $listview1.Groups.Add($lvGroup)
    }
    $item = New-Object System.Windows.Forms.ListViewItem
	$listview1.Items.Add($item)
	$item.Text = $Property
	$item.Name = 'Property'
	$item.Group = $listview1.Groups[$GroupName]
		
    $subitem = New-Object System.Windows.Forms.ListViewItem+ListViewSubItem
    $subitem.Text = $Value
    $subitem.Name = 'Value'
    $item.SubItems.Add($subitem)
		
}
Now we can just declare groups when we add items to the LV. Now we can just drop an LV on the form and add items and groups as needed. We can also adjust the items display once in the function if we want to set formatting and style.

User avatar
lontru
Posts: 48
Joined: Fri Aug 18, 2017 4:36 am

Re: GUI - Display data - table format - color? how?

Post by lontru » Sun Nov 18, 2018 2:32 pm

I have a long way with these forms :D

I will take your input and optimize the form for better understanding and perf.

Could you explain the "auto-generated" group function

Code: Select all

    if($listview1.Groups[$Group]){
        $lvGroup = [System.Windows.Forms.ListViewGroup]::New($GroupName,$GroupName)
        $listview1.Groups.Add($lvGroup)
    }
from what i can figure out is:
So if the groupname exist in the listview1
create new groupname
addgroup name to listview1

but should it not be if groupname doesnt exist in listview.groups then create new groupname?

User avatar
jvierra
Posts: 13182
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: GUI - Display data - table format - color? how?

Post by jvierra » Sun Nov 18, 2018 3:11 pm

Sorry. I typed it wrong and didn't see it. It should be:

if(-not $listview1.Groups[$Group]){

With this we wouldn't add groups in the designer we would just create them as needed. This also allows the code to explicitly state how and why groups are created rather than hiding them in the designer.

Locked