I've written a small program with PowerShell 5 which works. With PowerShell 7, the script stops executing.
This is a minimal sample I could build to reproduce the issue.
Without the dialog or the Out-Speech function, it's working.
I don't know why this combination isn't working.
I start my script with a small batch
pwsh.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0test.ps1"
pause
and
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0test.ps1"
pause
Start the script and close the window.
function Ask4Password()
{
    $pwdForm = New-Object System.Windows.Forms.Form
    $pwdForm.Text = 'Please enter password'
    $pwdForm.Size = New-Object System.Drawing.Size(300,140)
    $pwdForm.StartPosition = 'CenterScreen'
    $pwdForm.KeyPreview = $true
    $pwdForm.Topmost = $true
    [void] $pwdForm.ShowDialog()
    return 'abc'
}
function Out-Speech( $text )
{
    $speechy = New-Object 鈥揅omObject SAPI.SPVoice
    [void]$speechy.Speak( $text, 1 ) # 1 = async
}
# only needed for PowerShell 5
[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
Ask4Password
Write-Host 'Wrong Password'
Out-Speech 'Wrong Password'
Script should exit like with PowerShell 5
Execution stops
Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
                        Follow works in PowerShell Core:
[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
$pwdForm = New-Object System.Windows.Forms.Form
                    I wouldn't be at all surprised if the COM object either works differently with .NET Core or simply doesn't work. I've not had a great many COM objects work well in .NET Core.
The hang is definitely worth investigating.
Pragmatically speaking, the problem only arises due to the _asynchronous_ call to .Speak(), and even though Windows PowerShell doesn't _hang_, the speech output _doesn't actually work_ - unless you make the call _synchronous_, simply by omitting the 1 argument: $speechy.Speak($text)
You can also avoid the hang if you explicitly release the COM component before exiting your script (though speech output still won't work): [System.Runtime.InteropServices.Marshal]::ReleaseComObject($speechy)
@Jawz84, .NET Core 3 added WinForms and WPF support (on Windows), so PowerShell 7 automatically supports it too.
@Tragen, as an aside, I suggest using the PowerShell-idiomatic way of loading a well-known assembly (by simple name):
Add-Type -AssemblyName System.Windows.Forms, rather than the declared-obsolete [System.Reflection.Assembly]::LoadWithPartialName method.
Thanks for the hint about loading the the assembly. It's an old script.
I also think you should investigate it.
It's not a problem about COM not working, But the async speed ouput or something else seems to block the exit.
Most helpful comment
Follow works in PowerShell Core: