I'm writing a script right now but I can't figure out why this adding to the script makes my -AsSecureString echo in the finished result while compiled to an CMD/window (.*Exe) with ISEsteroids.
I am using Read-Host
to use above and hide password written inside script. And while running the code in editor it works wonderful. But while compiled using ISEsteroids to executable my script runs and then at the end echos the password 3 times in plain text... like this(images)
im using this to add the "run again" boxes and script in between.
$choices = [System.Management.Automation.Host.ChoiceDescription[]] @("&Yes","&No")
while ( $true ) {
Script here:
$Host.UI.RawUI.WindowTitle = $PSScriptRoot
$choice = $Host.UI.PromptForChoice("Run again","",$choices,0)
if ( $choice -ne 0 ) {
break
}
}
ISE output:
Output from executable:
UPDATE - SOLVED got help from @mklement0! this solved the issue.
while ([Console]::KeyAvailable) { $null = [Console]::ReadKey($true) }
tl;dr
As a workaround for the unexpected behavior you see in your compiled application - characters typed in response to Read-Host
also showing up in a later, unrelated prompt - clear the console keyboard buffer before calling $Host.UI.PromptForChoice(...)
(taken from this answer):
# Clear any pending keystrokes.
while ([Console]::KeyAvailable) { $null = [Console]::ReadKey($true) }
The difference in behavior comes down to different PowerShell host implementations.
A PowerShell host is a .NET class derived from the abstract System.Management.Automation.Host.PSHost
class, and its purpose is to provide input to and display output from the PowerShell runtime.
Different PowerShell environments have different host implementations whose behavior can differ substantially, and hosts are allowed to not implement certain features. $Host.Name
reports a host's friendly name, such as ConsoleHost
in regular console windows.[1]
Read-Host -AsSecureString
, whereas a regular console window prompts directly in the console.I don't know what host implementation your compiled executable - created by wrapping a PowerShell script in a stand-alone executable - uses. In the simplest case, it uses the simple DefaultHost
implementation that is used by default when you embed PowerShell in an application via the PowerShell SDK.
The behavior you experienced smells like a bug, but at least the workaround shown above seems to be effective.
[1] Note that there's seemingly no way to determine the full type name of the host-specific PSHost
-derived class via the automatic $Host
variable, whose own type is the non-public
[System.Management.Automation.Internal.Host.InternalHost]` class. Similarly, the host-specific type may be non-public.