Outputting to multiple textboxes while job is running

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.
This topic is 1 year and 4 days old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
leroy_002
Posts: 9
Last visit: Thu Mar 07, 2024 1:02 pm

Outputting to multiple textboxes while job is running

Post by leroy_002 »

Hello,

I am redoing my old form to look more modern and I'm updating the scripts. I was looking at jobs and got them working fine but I was wondering if there was a way to output to multiple text boxes while the code is running, instead of populating all textboxes at the end. I'm also trying to update the progress bar after each textbox is filled. I tried adding my "completed" script block to the "updated" and now it's not working too great. Any help would be appreciated.
  1. $buttonStartJob_Click = {
  2.    
  3.     $buttonStartJob.Enabled = $false
  4.     #$toolstripprogressbar1.Visible = $true
  5.     $progressbaroverlay1.Visible = $true
  6.     $progressbaroverlay1.Text = "Please wait, this will take a few moments..."
  7.    
  8.     #Initialize the Progress Bar
  9.     $progressbaroverlay1.Maximum = 7;
  10.     $progressbaroverlay1.Step = 1;
  11.     $progressbaroverlay1.Value = 1;
  12.    
  13.     #Create a New Job using the Job Tracker
  14.     $paramAddJobTracker = @{
  15.         Name      = 'JobName'
  16.         JobScript = {
  17.             #--------------------------------------------------
  18.             #TODO: Set a script block
  19.             #Important: Do not access form controls from this script block.
  20.            
  21.             Param ($computerName) #Pass any arguments using the ArgumentList parameter
  22.            
  23.             for ($i = 0; $i -lt 50; $i++) { Start-Sleep -Milliseconds 1 }
  24.            
  25.             #region Gets username of current user
  26.             $userid = Get-CimInstance -ComputerName $computerName -Class win32_ComputerSystem | Select-Object UserName -ExpandProperty UserName
  27.            
  28.             #Email Gets email of current user without using AD module
  29.             $SAMName = "$userid"
  30.             $Results2 = @()
  31.             $Root = [ADSI]''
  32.            
  33.             $Searcher = New-Object System.DirectoryServices.DirectorySearcher($Root)
  34.             $Searcher.filter = "(&(objectClass=user)(sAMAccountName= $SAMName))"
  35.             $User = $Searcher.findall()
  36.             If ($User)
  37.             {
  38.                 # Create PS Object
  39.                 $Object = New-Object PSObject -Property @{
  40.                     Email = (($User.Properties).mail | Out-String)
  41.                 }
  42.                 $Results2 += $Object
  43.             }
  44.            
  45.             # Display results
  46.             $Email = $Results2 | Select-Object Email -ExpandProperty Email
  47.             #endregion
  48.                
  49.             #region Get Serial Number
  50.             $serialNumber = Get-CimInstance -ComputerName $computerName -Class win32_Bios | Select-Object SerialNumber -ExpandProperty SerialNumber
  51.             #endregion
  52.                        
  53.             #region Get Model
  54.             $model = Get-CimInstance -ComputerName $computerName -Class win32_ComputerSystem | Select-Object Model -ExpandProperty Model
  55.             #endregion
  56.                        
  57.             #region Get Build Number
  58.             $build = Invoke-Command -ComputerName $computerName {
  59.                 (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ReleaseId).ReleaseId
  60.             }
  61.             #endregion
  62.                        
  63.             #region Get-OS Version
  64.             $operatingSystem = (Get-CimInstance -ComputerName $computerName -class Win32_OperatingSystem).Caption
  65.             #endregion
  66.                        
  67.             #region Get-Office Version
  68.             $officeVersion = invoke-command -computername $computerName -scriptblock {
  69.                
  70.                 if (test-path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\O365*')
  71.                 {
  72.                    
  73.                     Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\O365*' | Select-Object DisplayVersion -ExpandProperty DisplayVersion
  74.                     Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Office\16.0\Outlook' -Name Bitness | Select-Object Bitness -ExpandProperty Bitness
  75.                    
  76.                 }
  77.             }
  78.             #endregion
  79.            
  80.             #region Get Last Reboot
  81.             $restart = Get-CimInstance -ComputerName $computerName -ClassName win32_operatingsystem | select -ExpandProperty lastbootuptime
  82.             $date = Get-Date
  83.             $ts = New-TimeSpan -Start $restart -End $date
  84.             $its = $ts.Days
  85.             #endregion
  86.                        
  87.             $obj = @{ }
  88.             $obj.user = $userid
  89.             $obj.email = $email
  90.             $obj.serial = $serialNumber
  91.             $obj.model = $model
  92.             $obj.build = $build
  93.             $obj.os = $operatingSystem
  94.             $obj.version = $officeVersion
  95.             $obj.restart = $its        
  96.                        
  97.             New-Object psobject -property $obj
  98.            
  99.             #--------------------------------------------------
  100.         }
  101.         ArgumentList = $textbox1.Text
  102.         CompletedScript = {
  103.             Param ([System.Management.Automation.Job]$Job)
  104.                          #THIS IS WHAT I HAD BEFORE MOVING IT TO UPDATESCRIPT#IT OUTPUT FINE BUT WAS ONLY AT THE END OF THE SCRIPT#
  105.             #$results = Receive-Job -Job $Job
  106.             #$textbox3.Text = $results.user
  107.             #$textbox2.Text = $results.email
  108.             #$textbox4.Text = $results.serial
  109.             #$textbox5.Text = $results.build
  110.             #if ($textbox5.TextLength -eq 0) { $textbox5.Text = "N/A" }
  111.             #$textbox6.Text = $results.model
  112.             #$textbox7.Text = $results.os
  113.             #$textbox18.Text = $results.restart
  114.             #$textbox19.Text = $results.version
  115.             #if ($textbox19.textLength -eq 0) { $textbox19.Text = "Old Version of Office Detected. Please Update" }
  116.            
  117.             $progressbaroverlay1.Value = 7
  118.             $progressbaroverlay1.Text = "Complete"
  119.            
  120.             #Enable the Button
  121.             $buttonStartJob.ImageIndex = -1
  122.             $buttonStartJob.Enabled = $true
  123.         }
  124.         UpdateScript = {
  125.             Param ([System.Management.Automation.Job]$Job)
  126.             $results = Receive-Job -Job $Job -Keep
  127.            
  128.             ## - Grab results from background job:
  129.             $textbox3.Text = $results.user
  130.             $textbox2.Text = $results.email
  131.             $progressbaroverlay1.PerformStep();
  132.             $textbox4.Text = $results.serial
  133.             $progressbaroverlay1.PerformStep();
  134.             $textbox5.Text = $results.build
  135.             if ($textbox5.TextLength -eq 0) { $textbox5.Text = "N/A" }
  136.             $progressbaroverlay1.PerformStep();
  137.             $textbox6.Text = $results.model
  138.             $progressbaroverlay1.PerformStep();
  139.             $textbox7.Text = $results.os
  140.             $progressbaroverlay1.PerformStep();
  141.             $textbox18.Text = $results.restart
  142.             $progressbaroverlay1.PerformStep();
  143.             $textbox19.Text = $results.version
  144.             if ($textbox19.textLength -eq 0) { $textbox19.Text = "Old Version of Office Detected. Please Update" }
  145.                    
  146.             ## - Increment progress bar:
  147.            
  148.            
  149.             #Animate the Button
  150.             if ($null -ne $buttonStartJob.ImageList)
  151.             {
  152.                 if ($buttonStartJob.ImageIndex -lt $buttonStartJob.ImageList.Images.Count - 1)
  153.                 {
  154.                     $buttonStartJob.ImageIndex += 1
  155.                 }
  156.                 else
  157.                 {
  158.                     $buttonStartJob.ImageIndex = 0
  159.                 }
  160.             }
  161.         }
  162.     }
  163.    
  164.     Add-JobTracker @paramAddJobTracker
  165. }
  166. }
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Outputting to multiple textboxes while job is running

Post by jvierra »

You can output anywhere in the "UpdateScript".
leroy_002
Posts: 9
Last visit: Thu Mar 07, 2024 1:02 pm

Re: Outputting to multiple textboxes while job is running

Post by leroy_002 »

That's what I'm trying in my above script and it's not outputting.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Outputting to multiple textboxes while job is running

Post by jvierra »

What is it you are trying to output?

Don't receive the job just report on the properties of the job object. Why are you creating an object from an object?

Note that a job only returns items if you output them from the job. If the job does one thing you will only get one thing back. Your JobScript must return things continuously to the UpdateScript.
leroy_002
Posts: 9
Last visit: Thu Mar 07, 2024 1:02 pm

Re: Outputting to multiple textboxes while job is running

Post by leroy_002 »

Sorry, I think I read another forum saying that you had to create objects if you wanted to pull from jobs. Let's make this easy. In the JobScript, It searches for the serial number and model number. In the updatescript block, I want to pull the data once it's found. What's the best way to do this and also make the progress bar step in between the serial number and model search. I just need this example and then I can take it from there.
  1. $buttonStartJob_Click = {
  2.    
  3.     #Create a New Job using the Job Tracker
  4.     $paramAddJobTracker = @{
  5.         Name      = 'ComputerInfo'
  6.         JobScript = {
  7.             #--------------------------------------------------
  8.             #TODO: Set a script block
  9.             #Important: Do not access form controls from this script block.
  10.            
  11.             Param ($computerName) #Pass any arguments using the ArgumentList parameter
  12.            
  13.             for ($i = 0; $i -lt 50; $i++) { Start-Sleep -Milliseconds 1 }
  14.                            
  15.             $serialNumber = Get-CimInstance -ComputerName $computerName -Class win32_Bios | Select-Object SerialNumber -ExpandProperty SerialNumber
  16.            
  17.             $model = Get-CimInstance -ComputerName $computerName -Class win32_ComputerSystem | Select-Object Model -ExpandProperty Model
  18.             #--------------------------------------------------
  19.         }
  20.         ArgumentList = $textbox1.Text
  21.         CompletedScript = {
  22.             Param ([System.Management.Automation.Job]$Job)
  23.             #$results = Receive-Job -Job $Job
  24.                        
  25.             #Enable the Button
  26.             $buttonStartJob.ImageIndex = -1
  27.             $buttonStartJob.Enabled = $true
  28.         }
  29.         UpdateScript = {
  30.             Param ([System.Management.Automation.Job]$Job)
  31.             #$results = Receive-Job -Job $Job -Keep        
  32.             ## - Grab results from background job:
  33.             $textbox6.Text = $model
  34.                          $textbox7.Text  = $serialnumber
  35.            
  36.             ## - Increment progress bar:
  37.             #$progressbaroverlay1.PerformStep();
  38. }
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Outputting to multiple textboxes while job is running

Post by jvierra »

Why would you use a job to return one thing from a remote computer?

I think you do not understand that jobs are for long running tasks that return nothing or return incremental results.
leroy_002
Posts: 9
Last visit: Thu Mar 07, 2024 1:02 pm

Re: Outputting to multiple textboxes while job is running

Post by leroy_002 »

No, I know. I was just using a very simple example. Would you mind just showing me what I asked? It would be very helpful. I can get the $completedScript to work, I just can't get UpdateScript to work.

I just want to output to each box while the job is running and update the progress bar between getting the serial number and model. Again, this is very simple example that I can take and work with for my larger form. I would really appreciate the help.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Outputting to multiple textboxes while job is running

Post by jvierra »

Sorry but you didn't ask a question. You just said that the UpdateScript was not working. You have nothing being returned incrementally from the JobScript so you will likely never see the UpdateScript executed.JobTracker control does and why and how.

https://info.sapien.com/index.php/guis/ ... sive-forms

https://info.sapien.com/index.php/how-t ... -functions

All of the information you need to use the JobTracker is in those two articles assuming you understand WinForms and "asynchronous" execution and why and when to use it.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Outputting to multiple textboxes while job is running

Post by jvierra »

Here is a simple example of how to use the UpdateScript block.
Attachments
Demo-JobTrackerTextOut.psf
(30.54 KiB) Downloaded 59 times
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Outputting to multiple textboxes while job is running

Post by jvierra »

Here is an old piece of code that shows how to return objects to the UpdateScript and how to use the objects to output to a textbox.
Attachments
Demo-JobTrackerJobOutTextOut.psf
(29.98 KiB) Downloaded 27 times
This topic is 1 year and 4 days old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked