Page 3 of 4

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

Posted: Fri Jun 15, 2018 4:51 pm
by jvierra
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.

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

Posted: Sat Jun 16, 2018 10:34 am
by Pallas
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 502 times
I am lost here.

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

Posted: Sat Jun 16, 2018 11:37 am
by Pallas
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.

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

Posted: Sat Jun 16, 2018 11:42 am
by jvierra
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.

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

Posted: Sat Jun 16, 2018 11:48 am
by jvierra
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.

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

Posted: Sat Jun 16, 2018 12:01 pm
by jvierra
Here is an old demo showing how to access the form during a JT run.

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

Posted: Sat Jun 16, 2018 12:14 pm
by Pallas
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.

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

Posted: Sat Jun 16, 2018 12:29 pm
by jvierra
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.

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

Posted: Sat Jun 16, 2018 12:51 pm
by jvierra
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
}

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

Posted: Sat Jun 16, 2018 1:09 pm
by jvierra
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