Powershell:  More elegant method of creating a visual interface

Darrell Porter
Darrell Porter used Ask the Experts™
on
I have the following code block:
$tspan = @(
    New-Object -TypeName PSObject -Property @{'id'='01';'name'='Previous hour';'seconds'='3600'}
    New-Object -TypeName PSObject -Property @{'id'='02';'name'='Previous 2 hours';'seconds'='7200'}
    New-Object -TypeName PSObject -Property @{'id'='03';'name'='Previous 4 hours';'seconds'='14400'}
    New-Object -TypeName PSObject -Property @{'id'='04';'name'='Previous 8 hours';'seconds'='28800'}
    New-Object -TypeName PSObject -Property @{'id'='05';'name'='Previous day';'seconds'='86400'}
    New-Object -TypeName PSObject -Property @{'id'='06';'name'='Previous week';'seconds'='604800'}
    New-Object -TypeName PSObject -Property @{'id'='07';'name'='Previous 2 weeks';'seconds'='1209600'}
    New-Object -TypeName PSObject -Property @{'id'='08';'name'='Previous month';'seconds'='2419200'}
)
$tmspan = ($tspan | Select-Object -Property name, seconds | Sort-object -Property id | out-gridview -OutputMode Single -Title "Select a timeframe").seconds

Open in new window

Is there a more elegant / best-practice method of creating this interface?
I am trying to write a more complete Powershell-based interface to Cisco MEraki's API.

Thank you in advance!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Sam JacobsCitrix Technology Professional / Director of TechDev Services, IPM

Commented:
Pretty much the same:
$menu = @"
    'id', Name, Seconds
    '01','Previous hour','3600'
    '02','Previous 2 hours','7200'
    '03','Previous 4 hours','14400'
    '04','Previous 8 hours','28800'
    '05','Previous day','86400'
    '06','Previous week','604800'
    '07','Previous 2 weeks','1209600'
    '08','Previous month','2419200'
"@ | ConvertFrom-Csv
Do {
	If ($selection = $menu | Select Name, Seconds | Out-GridView -Title "Select a timeframe" -OutputMode Single) {
		& $selection.Script
	}
} Until (-not $selection)

Open in new window

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
		& $selection.Script

Open in new window

should be
		selection.Seconds

Open in new window

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
But I think it doesn't really improve the interface, only how to feed it. A "proper" interface IMO requires .NET (XAML) or something similar, a GUI form designed for the particular purpose.
Sam JacobsCitrix Technology Professional / Director of TechDev Services, IPM

Commented:
Yep … I had a copy/paste error, thanks. However, I believe it should be:

      $selection.Seconds

Open in new window

I totally agree about it only improving the feed. Not sure why the ID field is needed, since it comes out in the same order it was entered.
Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
You believe correct.
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Here's a WinForms GUI using a DateTimePicker:
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$propFormMain = @{
	Text = 'Select a timeframe'
	Size = '300, 200'
	StartPosition = 'CenterScreen'
	FormBorderStyle = 'FixedSingle'
}
$propLabelSelectDate = @{
	Text = 'Date:'
	Location = '15, 20'
	Size = '100, 25'
}
$propDtPickerDate = @{
	Location = '120, 17'
	Width = 150
	Format = 'Short'
	MaxDate = Get-Date
}
$propLabelSelectTime = @{
	Text = 'Time:'
	Location = '15, 50'
	Size = '100, 25'
}
$propDtPickerTime = @{
	Location = '120, 47'
	Width = 150
	Format = 'Custom'
	CustomFormat = 'HH:mm:ss'
	ShowUpDown = $true
}
$propButtonOK = @{
	Location = '80, 120'
	Size = '90, 25'
	Text = '&OK'
	DialogResult = 'OK'
}
$propButtonCancel = @{
	Location = '180, 120'
	Size = '90, 25'
	Text = '&Cancel'
	DialogResult = 'Cancel'
}

$formMain =				New-Object -TypeName System.Windows.Forms.Form -Property $propFormMain
$labelSelectDate =		New-Object -TypeName System.Windows.Forms.Label -Property $propLabelSelectDate
$dtPickerSelectDate =	New-Object -TypeName System.Windows.Forms.DateTimePicker -Property $propDtPickerDate
$labelSelectTime =		New-Object -TypeName System.Windows.Forms.Label -Property $propLabelSelectTime
$dtPickerSelectTime =	New-Object -TypeName System.Windows.Forms.DateTimePicker -Property $propDtPickerTime
$buttonOK =				New-Object -TypeName System.Windows.Forms.Button -Property $propButtonOK
$buttonCancel =			New-Object -TypeName System.Windows.Forms.Button -Property $propButtonCancel

@(
	$labelSelectDate
	$dtPickerSelectDate
	$labelSelectTime
	$dtPickerSelectTime
	$buttonOK
	$buttonCancel
) | ForEach-Object {$formMain.Controls.Add($_)}
$formMain.AcceptButton = $buttonOK
$formMain.CancelButton = $buttonCancel

$result = $formMain.ShowDialog()
If ($result -eq [Windows.Forms.DialogResult]::OK) {
	$dateTime = $dtPickerSelectDate.Value.Date + $dtPickerSelectTime.Value.TimeOfDay
	$difference = [int]((Get-Date) - $dateTime).TotalSeconds
	If ($difference -le 0) {
		Throw "The selected date is in the future: $($dateTime.ToString())"
	}
	Write-Host "Date selected: $($dateTime.ToString())"
	Write-Host "Difference to current date: $($difference)"
}

Open in new window

Darrell PorterEnterprise Business Process Architect

Author

Commented:
I will try out the GUI tomorrow.  Thank you for that.
I appreciate all of your responses.
Darrell PorterEnterprise Business Process Architect

Author

Commented:
Thank you, Gentlemen.
I had not considered using a "genuine" GUI as I am often asked for Quick & Dirty solutions and the picker was the easiest thing to implement.
I do have to tweak oBda's code because I need to reference a specific, limited set of times (those specified in my original code snippet) due to the API being used (Cisco-Meraki) and the defined business needs.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial