powershellconfirmationunattended-processing

Powershell, pass an answer to a script that requires a choice


I have a PowerShell script that has a y/n question asked in the script. I cannot change the script as it is downloaded from a url, but I would like to run it such that my choice is passed to the script and processing continues unattended.

I found this question, which is on a similar topic, but more related to cmdlets (and I tried everything here, but no luck).

Here is the relevant code (say this is in a script test.ps1)

function Confirm-Choice {
    param ( [string]$Message )
    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Yes";
    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "No";
    $choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no);
    $caption = ""   # Did not need this before, but now getting odd errors without it.
    $answer = $host.ui.PromptForChoice($caption, $message, $choices, 1)   # Set to 0 to default to "yes" and 1 to default to "no"
    switch ($answer) {
        0 {return 'yes'; break}  # 0 is position 0, i.e. "yes"
        1 {return 'no'; break}   # 1 is position 1, i.e. "no"
    }
}

$unattended = $false   # default condition is to ask user for input
if ($(Confirm-Choice "Prompt all main action steps during setup?`nSelect 'n' to make all actions unattended.") -eq "no") { $unattended = $true }

i.e. Without altering the script, I would like to pass 'n' to this so that it will continue processing. Something like test.ps1 | echo 'n' (though, as before, this specific syntax does not work unfortunately, and I'm looking for a way to do this).


Solution

  • PromptForChoice appears to read input directly from the console host, so it can't be supplied with input from stdin.

    You may override the function Confirm-Choice instead, by defining an alias that points to your own function which always outputs 'n'. This works because aliases take precedence over functions.

    function MyConfirm-Choice {'no'}
    New-Alias -Name 'Confirm-Choice' -Value 'MyConfirm-Choice' -Scope Global
    
    .\test.ps1   # Now uses MyConfirm-Choice instead of its own Confirm-Choice
    
    # Remove the alias again
    Remove-Item 'alias:\Confirm-Choice'