Button - Start Job, how to multiple arguments, how to work with objects

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
jvierra
Posts: 13392
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by jvierra » Fri Jun 15, 2018 4:51 pm

I thought I would take a minute to add some extra info about control events, the naming method and management of the events.

Every control has a default event. If you double click any control it will open the editor to an inserted event block or to an existing event block. All events are initially named with the following structure:

<control class><name property>_<event name>

You can rename a control and all events associated using the rename item on the right context menu.

If a controls default event becomes disconnected just double click the control and it will be reattached. Other events can be attached via the events tab of the designer's PropertyGrid panel.

User avatar
Pallas
Posts: 14
Joined: Wed Jan 18, 2017 2:44 am
Contact:

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by Pallas » Sat Jun 16, 2018 10:34 am

Thank you for the insight. I compared a completly new form with the Button Start Job and my old one. They behave exactly the same. That is, the $timerJobTracker_Tick is halted (when running debug in Power Shell Studio) when the form loads. And then never again, no matter what. Even complete blank forms like the one on the screenshot do exactly the same: They never enter $timerJobTracker_Tick={Update-JobTracker}. I did not touch a single line of code in the blank one. Just added the breakpoint
1.JPG
1.JPG (26.3 KiB) Viewed 494 times
I am lost here.

User avatar
Pallas
Posts: 14
Joined: Wed Jan 18, 2017 2:44 am
Contact:

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by Pallas » Sat Jun 16, 2018 11:37 am

I have a working version, using the Button - start Job, which is fine with me. Now I would love to know how to get some sort of progress from that

Code: Select all

  -UpdateScript {
		Param ($Job)
		$Counter = 1 + $Counter
		$results = Receive-Job -Job $Job -Keep
I added a Counter to have some value that counts up at least. BUT, how do I display this in the main form? I know I have to use $results. Actually I do not mind just moving a progress bar or counting from 1 to infinity in my richttextbox. Just how? I did not manage to find a good explanation on how to work with the results from a recieve-job.
Furthermore If I watch $results I see that the code is executed but the $Value is (Empty). (My $Counter is 1). This puzzles me.
Last edited by Pallas on Sat Jun 16, 2018 11:43 am, edited 1 time in total.

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

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by jvierra » Sat Jun 16, 2018 11:42 am

Try this form. Don't run under the debugger just open and run the form. Click the Start button anf notice that it shows the rotating image for about 5 seconds then the button is re-enabled.

If this doesn't work then you have system issues.
Attachments
Demo-RawJobTracker.psf
(27.13 KiB) Downloaded 22 times

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

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by jvierra » Sat Jun 16, 2018 11:48 am

Pallas wrote:
Sat Jun 16, 2018 11:37 am
I have a working version, using the Button - start Job, which is fine with me. Now I would love to know how to get some sort of progress from that

Code: Select all

  -UpdateScript {
		Param ($Job)
		$Counter = 1 + $Counter
		$results = Receive-Job -Job $Job -Keep
I added a Counter to have some value that counts up at least. BUT, how do I display this in the main form? I know I have to use $results. Actually I do not mind just moving a progress bar or counting from 1 to infinity in my richttextbox. Just how? I did not manage to find a good explanation on how to work with the results from a recieve-job.
Furthermore If I watch $results I see that the code is executed but the $Value is (Empty). (My $Counter is 1). This puzzles me.
Most of your issues are because you have very little experience with PowerShell and lack a clear understanding of how forms are designed to work. THis makes every step incremental in that each new thing is a mystery.

Your original code has no output therefore "Receive-Job" produces no results. The demo form created using the "Start Job" button has no output from the job. It's results are to animate button.

Again - in your original form, the timer is not connected to anything.

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

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by jvierra » Sat Jun 16, 2018 12:01 pm

Here is an old demo showing how to access the form during a JT run.
Attachments
Demo-JobTrakker.psf
(23.71 KiB) Downloaded 20 times

User avatar
Pallas
Posts: 14
Joined: Wed Jan 18, 2017 2:44 am
Contact:

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by Pallas » Sat Jun 16, 2018 12:14 pm

Hi, thank you for your help. I never said I was a professional developer. The whole point of using a second job and a sql query to ask the MS SQL Server about the progress, which it answers perfectly, was that the backup db job, no matter how I ran it, does NOT produce any increment, any result, that I could track. Thats how I ended up looking into asynchronous Powershell Jobs. If the sqlcmd cmdlet would return any of the messages MS SQL Studion does when I run the exact same code, I would not need this. If backup-db cmdlet would return anything while backing up 2 TB of database, I would not need this. As it is, I need to figure this out. Any help is appreciated.

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

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by jvierra » Sat Jun 16, 2018 12:29 pm

Another issues you are missing which are making this impossible for you is an understanding of SQLServer.

A backup request is just a request. It will be executed by the SQLServer instance and not by PowerShell. A job will complete once the backup is requested. The way SSMS does this is to use an async call and then it monitors the progress events. As I noted much earlier, this method is not available in PowerShell forms. To monitor a backup you will need to use a compiled language that can return async events or you must poll the table in SQS to get the info.

You can try a blind async wait.

$smoBackup.SqlBackupAsync($server)
$smoBackup.Wait()


This should cause the call to wait until the backup has completed. I suspect that currently your job is completing almost instantaneously so there can be no progress output.

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

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by jvierra » Sat Jun 16, 2018 12:51 pm

Try this at a CLI prompt with your database. It might provide updates:

Code: Select all

$Database ='master'
$BackupSetName = 'testser33'
$FilePath = 'd:\testdb\testdb.bkp'
$Server = 'Alpha'

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
$smoBackup = New-Object Microsoft.SqlServer.Management.Smo.Backup 
$smoBackup.Action = 'Database'
$smoBackup.BackupSetDescription = "Full (copyonly)backup of $Database"
$smoBackup.BackupSetName = $BackupSetName
$smoBackup.Database = $Database
$smoBackup.Copyonly = $true
$smoBackup.MediaDescription = "Full (copyonly)backup of $Database File = $FilePath"
$smoBackup.CompressionOption = 1
$smoBackup.Devices.AddDevice($FilePath, 'File')
$smoBackup.SqlBackupAsync($Server)

while(1) {
    if ($smoBackup.AsyncStatus.ExecutionStatus -eq 'Succeeded'){
        'Succeeded'
        break
    }elseif($smoBackup.AsyncStatus.ExecutionStatus -eq 'Failed') {
        'Failed'
        Throw $dbbk.AsyncStatus.LastException 
        break
    }else{
        $dbbk.AsyncStatus.ExecutionStatus
    }
    Start-Sleep 1
}

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

Re: Button - Start Job, how to multiple arguments, how to work with objects

Post by jvierra » Sat Jun 16, 2018 1:09 pm

Here is a method to trap the events of the async call.

Code: Select all

$Database ='master'
$BackupSetName = 'testser33'
$FilePath = 'd:\testdb\testdb.bkp'
$Server = 'Alpha'

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
$smoBackup = New-Object Microsoft.SqlServer.Management.Smo.Backup 
$smoBackup.Action = 'Database'
$smoBackup.BackupSetDescription = "Full (copyonly)backup of $Database"
$smoBackup.BackupSetName = $BackupSetName
$smoBackup.Database = $Database
$smoBackup.Copyonly = $true
$smoBackup.MediaDescription = "Full (copyonly)backup of $Database File = $FilePath"
$smoBackup.CompressionOption = 1
$smoBackup.Devices.AddDevice($FilePath, 'File')

Register-ObjectEvent $smoBackup Complete -Action {
      [Console]::Beep(100,100)
      Write-Host 'Complete'
      $global:bRunning = $false
}
Register-ObjectEvent $smoBackup PercentComplete -Action {
      [Console]::Beep(100,100)
      Write-Host 'Percent increased'
      $global:bRunning = $false
}

$smoBackup.PercentCompleteNotification = 1
$global:bRunning = $true
$smoBackup.SqlBackupAsync($Server)
while($bRunning){sleep 1}  # waits until the backup signals complete

Locked