To prompt for yes/no input in PowerShell, ask with Read-Host and check the answer with -in 'y', 'yes'. The -in operator ignores case, so Y, y and YES all count:
$reply = Read-Host -Prompt 'Restart the print spooler now? (y/n)'
if ($reply -in 'y', 'yes') { 'Restarting the spooler...' } else { 'Skipped. Nothing was restarted.' }
Output (I typed Y):
Restart the print spooler now? (y/n): Y
Restarting the spooler...
That’s enough for a quick script. Below are sturdier options: a loop that rejects bad answers, a reusable function with a default, PowerShell’s built-in choice menu, and -Confirm support.
I ran every example in PowerShell 7.6 and Windows PowerShell 5.1, with the same results.
Keep asking until you get a yes or no
People type “sure”, press Enter by accident, or add spaces. A do/until loop asks again until the answer is valid, and .Trim() drops the extra spaces:
do {
$reply = (Read-Host -Prompt 'Archive the 2025 invoices? (y/n)').Trim()
$valid = $reply -in 'y', 'yes', 'n', 'no'
if (-not $valid) { 'Please answer y or n.' }
} until ($valid)
if ($reply -like 'y*') { 'Archiving 318 invoices...' } else { 'Cancelled.' }
Output (I typed sure, then nothing, then ” no “):
Archive the 2025 invoices? (y/n): sure
Please answer y or n.
Archive the 2025 invoices? (y/n):
Please answer y or n.
Archive the 2025 invoices? (y/n): no
Cancelled.
-like 'y*' works for the final check because the loop has already limited the answer to y, yes, n or no. PowerShell while and do loops covers the loop types in more detail.
A reusable Confirm-Action function with a default
Most command-line tools show the default in capitals, like [y/N], and use it when you just press Enter. This function does the same and returns $true or $false:
function Confirm-Action {
param(
[Parameter(Mandatory)] [string]$Question,
[switch]$DefaultYes
)
$hint = if ($DefaultYes) { '[Y/n]' } else { '[y/N]' }
while ($true) {
$reply = (Read-Host -Prompt "$Question $hint").Trim()
if ($reply -eq '') { return [bool]$DefaultYes }
if ($reply -in 'y', 'yes') { return $true }
if ($reply -in 'n', 'no') { return $false }
}
}
if (Confirm-Action -Question 'Delete 12 temp files') { 'Deleting...' } else { 'Kept the files.' }
if (Confirm-Action -Question 'Email the summary to IT' -DefaultYes) { 'Sending...' } else { 'Not sent.' }
Output (I pressed Enter at both prompts):
Delete 12 temp files [y/N]:
Kept the files.
Email the summary to IT [Y/n]:
Sending...

Default to No for anything destructive, like deleting files. Save Yes as the default for safe steps, like sending a report.
Use PowerShell’s built-in choice prompt
$Host.UI.PromptForChoice() shows the same [Y] Yes [N] No menu that PowerShell’s own cmdlets use. It returns the index of the choice, so 0 is Yes here:
$yes = [System.Management.Automation.Host.ChoiceDescription]::new('&Yes', 'Disable the account now')
$no = [System.Management.Automation.Host.ChoiceDescription]::new('&No', 'Leave the account as it is')
$answer = $Host.UI.PromptForChoice('Disable account', 'Disable the account for jsmith?', @($yes, $no), 1)
if ($answer -eq 0) { 'Account disabled.' } else { 'No change made.' }
Output (I typed ? for help, then y):
Disable account
Disable the account for jsmith?
[Y] Yes [N] No [?] Help (default is "N"): ?
Y - Disable the account now
N - Leave the account as it is
[Y] Yes [N] No [?] Help (default is "N"): y
Account disabled.

The last argument is the default index, so 1 makes No the default. The PromptForChoice reference covers the other overloads.
Add -Confirm and -WhatIf to your own function
If your script changes something, the most PowerShell-like way to ask is ShouldProcess. You get -Confirm and -WhatIf for free, and callers can skip the prompt in automation:
function Remove-OldReport {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
param([Parameter(Mandatory)] [string]$Name)
if ($PSCmdlet.ShouldProcess($Name, 'Delete report')) {
"Deleted $Name"
}
}
Remove-OldReport -Name 'q1-sales.csv'
Remove-OldReport -Name 'q2-sales.csv' -Confirm:$false
Output (I typed n):
Confirm
Are you sure you want to perform this action?
Performing the operation "Delete report" on target "q1-sales.csv".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): n
Deleted q2-sales.csv

Watch out: this prompt defaults to Yes, so pressing Enter deletes the file. ConfirmImpact = ‘High’ is what makes it ask without -Confirm.
Preview changes with -WhatIf
The same function also supports -WhatIf, which only describes what would happen:
function Remove-OldReport {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
param([Parameter(Mandatory)] [string]$Name)
if ($PSCmdlet.ShouldProcess($Name, 'Delete report')) {
"Deleted $Name"
}
}
Remove-OldReport -Name 'q3-sales.csv' -WhatIf
Output:
What if: Performing the operation "Delete report" on target "q3-sales.csv".
Microsoft’s guide to ShouldProcess explains ConfirmImpact and $ConfirmPreference in more depth.
Use choice.exe for a single keypress with a timeout
Windows’ choice command takes one keypress without Enter and can pick a default after a timeout. It sets $LASTEXITCODE to the position of the key pressed:
choice /C YN /D N /T 3 /M 'Install the update'
if ($LASTEXITCODE -eq 1) { 'Installing...' } else { 'Update skipped.' }
Output (no key pressed for 3 seconds):
Install the update [Y,N]?N
Update skipped.
/D sets the default and /T the seconds to wait, which keeps an unattended script from hanging forever. The choice command reference lists every switch.
Show a Yes/No message box
For users who don’t live in the console, a Windows Forms message box is friendlier. It returns Yes or No as a DialogResult:
Add-Type -AssemblyName System.Windows.Forms
$result = [System.Windows.Forms.MessageBox]::Show('Install the printer driver?', 'Setup', 'YesNo', 'Question')
if ($result -eq 'Yes') { 'Installing...' } else { 'Skipped.' }
The Add-Type line matters. Without it, the MessageBox type isn’t loaded in a plain console, which is why copied snippets often fail.
Don’t prompt in scheduled tasks
Read-Host, PromptForChoice and ShouldProcess prompts all fail under -NonInteractive, as in many scheduled tasks and CI pipelines. The error says “Read and Prompt functionality is not available.”
Give your script a -Force switch that skips the question, and call ShouldProcess functions with -Confirm:$false.
Microsoft notes this in the Read-Host documentation. For other kinds of input, like numbers and passwords, see prompting for input in PowerShell.
Frequently Asked Questions
How do I prompt for yes or no in PowerShell?
Use Read-Host and check the answer: $r = Read-Host 'Continue? (y/n)'; if ($r -in 'y', 'yes') { ... }. The -in operator ignores case.
How do I make Enter pick a default answer?
Check for an empty reply first: if ($reply -eq '') { $reply = 'n' }. Show the default in capitals, like [y/N], so users know.
What does PromptForChoice return?
The index of the chosen option. With ‘&Yes’ and ‘&No’ in that order, Yes returns 0 and No returns 1.
How do I add a confirmation prompt to my function?
Add [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] and wrap the change in if ($PSCmdlet.ShouldProcess($target)) { }. You also get -WhatIf.
How do I skip a confirmation prompt in PowerShell?
Pass -Confirm:$false to cmdlets and functions that support ShouldProcess. Some cmdlets also have a -Force switch.
Keep building interactive scripts with these:
- Prompt for user input with Read-Host
- Loop until a condition is met
- If, elseif and else in PowerShell
- Write PowerShell functions
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.