0

I have a powershell script that used to work. I tried adding a try --> finally part to encapsulate some script blocks in order to handle Ctrl+C during a for each part of the operation. After that when it reaches the finally part it exits the moment I mention an object array that is declared at the start of the script (not inside the try part). I tried using debug and when I put the breakpoint on the object mention and it reaches it I can see the objects inside. Then I press F11 and it stops, with no error and no exception anywhere..

$Artists = @()
...
finally {   ### Write CSV regardless of script break ###
write-host "VC-Artists file maintenance.." -ForegroundColor "Green"
pause; $Artists.count; pause;....

enter image description here

A short example that I came up that shows this behavior is the following:

$Artists = @(); try { $i=1; while($true) { "Artist..$($i)"; $Artists += New-Object PSObject -Property @{ Artist = "test";idArtist = $i;Style = "pop";Genre = {"Jazz", "Pop"};ArtistAlternate = "test2";discogsidArtist = $i }; $i++; Start-Sleep -Seconds 1 } } finally { write-host "Ended work."; $Artists.count; pause }

when Ctr+C is pressed it stops, executes the write host but nothing after that (at least for me).

Any ideas?

tfonias74
  • 136
  • 9

1 Answers1

1

The (perhaps unsurprising) answer is that what you see isn't always what you get!

From the about_Try_Catch_Finally help topic:

Note that pressing CTRL+C stops the pipeline. Objects that are sent to the pipeline will not be displayed as output. Therefore, if you include a statement to be displayed, such as "Finally block has run", it will not be displayed after you press CTRL+C, even if the Finally block ran.

So the Finally block executes (which explains why the pause function seems to run), the output just never escapes the running pipeline and aren't sent back to the caller.

You can verify this by running a pipeline statement with an observable side effect:

$Artists = @()
try {
    $i = 1
    while ($true) {
        "Artist..$($i)"
        $Artists += New-Object PSObject -Property @{ 
            Artist          = "test"
            idArtist        = $i
            Style           = "pop"
            Genre           = { "Jazz", "Pop" }
            ArtistAlternate = "test2"
            discogsidArtist = $i 
        }
        $i++
        Start-Sleep -Seconds 1 
    } 
}
finally {
    write-host "Ended work."
    $global:artistCount = $Artists.Count
    $Artists.Count |Set-Content .\artistCount.log
    pause 
}

Run the above, interrupt with Ctrl+C after a few artists, and you'll find the correct number assigned to $artistCount and written to the $PWD\artistCount.log file.

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • Yes, it seems to be doing stuff but does not show them. Also in the debug it also seems to stop abruptly.. Will probably have to come up with something else because it is impossible to iron out errors with this behavior. – tfonias74 Aug 24 '20 at 09:49
  • @tfonias74 Is interrupting the pipeline part of ... normal operations of whatever you're building? Just trying to understand what problem you're trying to solve – Mathias R. Jessen Aug 24 '20 at 09:53
  • I am getting info from files and then parse a web db for info via api (don't want to hammer it). So I need to limit the calls and manually review the info I get. The idea is to fetch some data then kill the script but still save the info gathered to a csv file. Anyway I will use a counter or limit for operation. – tfonias74 Aug 24 '20 at 09:58
  • 1
    @tfonias74 I'd suggest you package as a module and use a module-scoped variable to hold a data structure that can act as a cache (to avoid re-fetching the same data over and over). You could achieve the same with a global variable as well in lieu of a script module – Mathias R. Jessen Aug 24 '20 at 10:24