button-start job no results

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.
Locked
mikondrashov
Posts: 4
Meble kuchenne na zamówienie - na wymiar - Wrocław
Joined: Wed Feb 26, 2020 1:18 am

button-start job no results

Post by mikondrashov »

Hi all, found this button-start job very useful. modified a few parts and trying to update a text box with count of active sessions, simple number pulled from job, once done using completed function to update text box as seen below, but not seeing results. i haven't modified other parts as it seems everything should be good as it is, thoughts? i did notice the example given has a little bit different syntax, might be outdated?

Any help appreciated
Thanks all

Code: Select all

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$SessionCounter                  = New-Object system.Windows.Forms.Form
$SessionCounter.ClientSize       = '281,160'
$SessionCounter.text             = "Session Counter"
$SessionCounter.TopMost          = $false
$SessionCounter.MaximizeBox      = $false
$SessionCounter.FormBorderStyle  = 'Fixed3D'

$buttonStartJob                  = New-Object system.Windows.Forms.Button
$buttonStartJob.text             = "Start Count"
$buttonStartJob.width            = 86
$buttonStartJob.height           = 31
$buttonStartJob.location         = New-Object System.Drawing.Point(173,42)
$buttonStartJob.Font             = 'Microsoft Sans Serif,10'

$Button2                         = New-Object system.Windows.Forms.Button
$Button2.text                    = "Exit"
$Button2.width                   = 84
$Button2.height                  = 30
$Button2.location                = New-Object System.Drawing.Point(173,85)
$Button2.Font                    = 'Microsoft Sans Serif,10'

$Label1                          = New-Object system.Windows.Forms.Label
$Label1.text                     = "Epic Prod Sessions"
$Label1.AutoSize                 = $true
$Label1.width                    = 25
$Label1.height                   = 10
$Label1.location                 = New-Object System.Drawing.Point(19,20)
$Label1.Font                     = 'Microsoft Sans Serif,10'

$Label2                          = New-Object system.Windows.Forms.Label
$Label2.text                     = "Epic SRO Sessions"
$Label2.AutoSize                 = $true
$Label2.width                    = 25
$Label2.height                   = 10
$Label2.location                 = New-Object System.Drawing.Point(19,84)
$Label2.Font                     = 'Microsoft Sans Serif,10'

$TextBox1                        = New-Object system.Windows.Forms.TextBox
$TextBox1.multiline              = $false
$TextBox1.width                  = 90
$TextBox1.height                 = 50
$TextBox1.location               = New-Object System.Drawing.Point(21,42)
$TextBox1.Font                   = 'Microsoft Sans Serif,10,style=Bold'
$TextBox1.ReadOnly               = $true
$TextBox1.Text                   = "0"

$TextBox2                        = New-Object system.Windows.Forms.TextBox
$TextBox2.multiline              = $false
$TextBox2.width                  = 90
$TextBox2.height                 = 50
$TextBox2.location               = New-Object System.Drawing.Point(21,106)
$TextBox2.Font                   = 'Microsoft Sans Serif,10,style=Bold'
$TextBox2.ReadOnly               = $true
$TextBox2.Text                   = "0"

$SessionCounter.controls.AddRange(@($buttonStartJob,$Button2,$Label1,$Label2,$TextBox1,$TextBox2))

#Actions
$Button2.Add_Click({
    $SessionCounter.Close()
    }
)

$buttonStartJob_Click={
	
	$buttonStartJob.Enabled = $false
	
	#Create a New Job using the Job Tracker
	$paramAddJobTracker = @{
		Name	  = 'JobName'
		JobScript = {
			#--------------------------------------------------
			#TODO: Set a script block
			#Important: Do not access form controls from this script block.
			Param ($Argument1) #Pass any arguments using the ArgumentList parameter
			#load cmldet
			asnp citrix*
            #pull active sessions
            $PRDSessions = Get-BrokerSession -CatalogName "epic prod" -MaxRecordCount 12000 | where {$_.ApplicationsInUse -like "*Epic Hyperspace*"}
            #get count int
            $PRDSessions.Count
                        			
			#--------------------------------------------------
		}
		ArgumentList = $null
		CompletedScript = {
			Param ([System.Management.Automation.Job]$Job)
			$results = Receive-Job -Job $Job
            $textbox1.Text = $results
			#Enable the Button
			$buttonStartJob.ImageIndex = -1
			$buttonStartJob.Enabled = $true

		}
		UpdateScript = {
			Param ([System.Management.Automation.Job]$Job)
			$results = Receive-Job -Job $Job -Keep
			#Animate the Button
			if ($null -ne $buttonStartJob.ImageList)
			{
				if ($buttonStartJob.ImageIndex -lt $buttonStartJob.ImageList.Images.Count - 1)
				{
					$buttonStartJob.ImageIndex += 1
				}
				else
				{
					$buttonStartJob.ImageIndex = 0
				}
			}
		}
	}
	
	Add-JobTracker @paramAddJobTracker
}

$jobTracker_FormClosed=[System.Windows.Forms.FormClosedEventHandler]{
#Event Argument: $_ = [System.Windows.Forms.FormClosedEventArgs]
	#Stop any pending jobs
	Stop-JobTracker
}

$timerJobTracker_Tick={
	Update-JobTracker
}

#region Job Tracker
$JobTrackerList = New-Object System.Collections.ArrayList
function Add-JobTracker
{
	<#
		.SYNOPSIS
			Add a new job to the JobTracker and starts the timer.
	
		.DESCRIPTION
			Add a new job to the JobTracker and starts the timer.
	
		.PARAMETER  Name
			The name to assign to the job.
	
		.PARAMETER  JobScript
			The script block that the job will be performing.
			Important: Do not access form controls from this script block.
	
		.PARAMETER ArgumentList
			The arguments to pass to the job.
		.PARAMETER  CompletedScript
			The script block that will be called when the job is complete.
			The job is passed as an argument. The Job argument is null when the job fails.
	
		.PARAMETER  UpdateScript
			The script block that will be called each time the timer ticks.
			The job is passed as an argument. Use this to get the Job's progress.
	
		.EXAMPLE
			Add-JobTracker -Name 'JobName' `
			-JobScript {	
				Param($Argument1)#Pass any arguments using the ArgumentList parameter
				#Important: Do not access form controls from this script block.
				Get-WmiObject Win32_Process -Namespace "root\CIMV2"
			}`
			-CompletedScript {
				Param($Job)		
				$results = Receive-Job -Job $Job
			}`
			-UpdateScript {
				Param($Job)
				#$results = Receive-Job -Job $Job -Keep
			}
	
		.LINK
			
	#>
	
	Param(
	[ValidateNotNull()]
	[Parameter(Mandatory=$true)]
	[string]$Name,
	[ValidateNotNull()]
	[Parameter(Mandatory=$true)]
	[ScriptBlock]$JobScript,
	$ArgumentList = $null,
	[ScriptBlock]$CompletedScript,
	[ScriptBlock]$UpdateScript)
	
	#Start the Job
	$job = Start-Job -Name $Name -ScriptBlock $JobScript -ArgumentList $ArgumentList
	
	if($null -ne $job)
	{
		#Create a Custom Object to keep track of the Job & Script Blocks
		$members = @{	'Job' = $Job;
						'CompleteScript' = $CompletedScript;
						'UpdateScript' = $UpdateScript}
		
		$psObject = New-Object System.Management.Automation.PSObject -Property $members
		
		[void]$JobTrackerList.Add($psObject)
		
		#Start the Timer
		if(-not $timerJobTracker.Enabled)
		{
			$timerJobTracker.Start()
		}
	}
	elseif($null -ne $CompletedScript)
	{
		#Failed
		Invoke-Command -ScriptBlock $CompletedScript -ArgumentList $null
	}

}

function Update-JobTracker
{
	<#
		.SYNOPSIS
			Checks the status of each job on the list.
	#>
	
	#Poll the jobs for status updates
	$timerJobTracker.Stop() #Freeze the Timer
	
	for($index = 0; $index -lt $JobTrackerList.Count; $index++)
	{
		$psObject = $JobTrackerList[$index]
		
		if($null -ne $psObject) 
		{
			if($null -ne $psObject.Job)
			{
				if ($psObject.Job.State -eq 'Blocked')
                {
                    #Try to unblock the job
                    Receive-Job $psObject.Job | Out-Null
                }
                elseif($psObject.Job.State -ne 'Running')
				{				
					#Call the Complete Script Block
					if($null -ne $psObject.CompleteScript)
					{
						#$results = Receive-Job -Job $psObject.Job
						Invoke-Command -ScriptBlock $psObject.CompleteScript -ArgumentList $psObject.Job
					}
					
					$JobTrackerList.RemoveAt($index)
					Remove-Job -Job $psObject.Job
					$index-- #Step back so we don't skip a job
				}
				elseif($null -ne $psObject.UpdateScript)
				{
					#Call the Update Script Block
					Invoke-Command -ScriptBlock $psObject.UpdateScript -ArgumentList $psObject.Job
				}
			}
		}
		else
		{
			$JobTrackerList.RemoveAt($index)
			$index-- #Step back so we don't skip a job
		}
	}
	
	if($JobTrackerList.Count -gt 0)
	{
		$timerJobTracker.Start()#Resume the timer
	}
}

function Stop-JobTracker
{
	<#
		.SYNOPSIS
			Stops and removes all Jobs from the list.
	#>
	#Stop the timer
	$timerJobTracker.Stop()
	
	#Remove all the jobs
	while($JobTrackerList.Count -gt 0)
	{
		$job = $JobTrackerList[0].Job
		$JobTrackerList.RemoveAt(0)
		Stop-Job $job
		Remove-Job $job
	}
}
#endregion

$SessionCounter.Add_Shown({$SessionCounter.Activate()})
[void]$SessionCounter.ShowDialog()



jvierra
Posts: 14444
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: button-start job no results

Post by jvierra »

If there are errors of if you get no results then there will be no results. Try testing the job script outside of the form to be sure you are receiving a correct result.

jvierra
Posts: 14444
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: button-start job no results

Post by jvierra »

If you are hand coding this form then it is missing many pieces that make the job tracker method fail to run. The code was designed to be used in a Sapien generated form as a custom control set. This allows the form to be configured correctly for the tracker to work. Without the timer and other items it will not work as designed.

mikondrashov
Posts: 4
Joined: Wed Feb 26, 2020 1:18 am

Re: button-start job no results

Post by mikondrashov »

i tested the job and get results
  1. $job = Start-Job -ScriptBlock {
  2.  
  3.  
  4.  
  5.             asnp citrix*
  6.  
  7.             #pull active sessions
  8.  
  9.             $PRDSessions = Get-BrokerSession -CatalogName "epic prod" -MaxRecordCount 12000 | where {$_.ApplicationsInUse -like "*Epic Hyperspace*"}
  10.  
  11.             #get count int
  12.  
  13.             $PRDSessions.Count
  14.  
  15.  
  16.  
  17.             }
  18.  
  19. $res = Receive-Job $Job
  20.  
  21. $res
  22.  
  23. 7524

jvierra
Posts: 14444
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: button-start job no results

Post by jvierra »

The code you posted above does not have many of the required components. It specifically lacks a timer. I cannot see how you can expect it t work.

mikondrashov
Posts: 4
Joined: Wed Feb 26, 2020 1:18 am

Re: button-start job no results

Post by mikondrashov »

when i click start button wouldn't it run at least once? i removed timer

jvierra
Posts: 14444
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: button-start job no results

Post by jvierra »

No. The code only runs on a timer tick. "Start" just configures the job and the timer.

Go back and carefully read the complete article on the Job Tracker design and implementation and how it is designed to be used will it will become clear .

mikondrashov
Posts: 4
Joined: Wed Feb 26, 2020 1:18 am

Re: button-start job no results

Post by mikondrashov »

i think i got it to work by fully generating script it added the tick and some other pieces, next question is how could i run this in a loop once the start button is pressed? thanks for replies

< code removed to improve thread readability >

jvierra
Posts: 14444
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: button-start job no results

Post by jvierra »

When posting PowerShell Studio code please only post the PSF as an attachment. The code posted is useless on this site. The code posting tool is designed for small snippets of code and not for large files. ALso just post snippets as code since the tool is broken and does not provide a readable or copy-able post.

I have deleted the code from your last post to make the thread less impossible to use. Please post the PSF as an attachment.

Locked