PowerShell Read-Host: Get User Input in Scripts

PowerShell Read-Host: Get User Input in Scripts

PowerShell Tips Editor 4 min read
PowerShell Read-Host: Get User Input in Scripts

Scripts that run completely silently are ideal for automation, but many real-world scripts need to confirm a destructive action, ask for a target environment, or accept a password at runtime. Read-Host handles PowerShell Read-Host user input with a single cmdlet that pauses execution and waits for keyboard input. This post covers text prompts, secure password input, validation loops, menus, and when to use function parameters instead.

Quick Answer / TL;DR

Use $value = Read-Host -Prompt 'Enter value' for text input and $pass = Read-Host -Prompt 'Password' -AsSecureString for passwords. Always convert the returned string to the expected type explicitly.

Basic Read-Host Prompt

Read-Host displays a prompt string and waits for the user to type a value and press Enter. The return value is always a String — even if the user types a number. The -Prompt parameter is optional; if omitted, no prompt text appears, which is confusing for users.

# Simple text prompt
$serverName = Read-Host -Prompt 'Enter the target server name'
Write-Host "You entered: $serverName"

# Prompt with a default suggestion in the message
$logPath = Read-Host -Prompt 'Log directory [C:\Logs]'
if ($logPath -eq '') { $logPath = 'C:\Logs' }

Read Secure Password with -AsSecureString

The -AsSecureString switch masks typed characters with asterisks and returns a SecureString object rather than a plain string. Use this whenever you prompt for passwords or secrets. To use the value in a PSCredential, pass it directly to New-Object System.Management.Automation.PSCredential.

# Prompt for password — returns SecureString, not plain text
$securePass = Read-Host -Prompt 'Enter password' -AsSecureString

# Build a PSCredential object from the secure string
$username = Read-Host -Prompt 'Username'
$credential = New-Object System.Management.Automation.PSCredential($username, $securePass)

# Use the credential
Invoke-Command -ComputerName server01 -Credential $credential -ScriptBlock { hostname }

Validate Input with a While Loop

Because Read-Host always returns a string, you must validate manually. A do/while loop keeps prompting until the user supplies a value that passes validation. This pattern handles empty input, type conversion errors, and format requirements cleanly.

# Keep prompting until user enters a valid integer
do {
    $inputStr = Read-Host -Prompt 'Enter a number between 1 and 100'
    $valid = [int]::TryParse($inputStr, [ref]$null) -and
             ([int]$inputStr -ge 1) -and ([int]$inputStr -le 100)
    if (-not $valid) { Write-Warning 'Invalid input. Please try again.' }
} while (-not $valid)

$number = [int]$inputStr
Write-Host "Valid number: $number"

Offer a Default Value

A common pattern is to show the default in the prompt text and use it when the user presses Enter without typing anything. This provides a convenient shortcut while still allowing overrides.

$defaultEnv = 'Production'
$env = Read-Host -Prompt "Target environment [$defaultEnv]"
if ([string]::IsNullOrWhiteSpace($env)) { $env = $defaultEnv }

Write-Host "Deploying to: $env"

Build a Simple Menu

Combine Read-Host with a switch statement to create a numbered menu. This is appropriate for interactive helpdesk tools where users choose an action from a small fixed set of options.

Write-Host "`n=== User Management ==="
Write-Host "1. Create user"
Write-Host "2. Disable user"
Write-Host "3. Reset password"
Write-Host "4. Exit"

$choice = Read-Host -Prompt 'Select option'

switch ($choice) {
    '1' { Write-Host 'Creating user...' }
    '2' { Write-Host 'Disabling user...' }
    '3' { Write-Host 'Resetting password...' }
    '4' { Write-Host 'Goodbye.'; exit }
    default { Write-Warning "Invalid selection: $choice" }
}

Read-Host vs Parameter Input

For scripts that run unattended or in CI pipelines, prefer function parameters with [CmdletBinding()] over Read-Host. Parameters support -WhatIf, tab completion, help documentation, and validation attributes. Use Read-Host only for genuinely interactive scripts where the user is sitting at the keyboard. A hybrid approach accepts a parameter but falls back to Read-Host when the parameter is empty.

param(
    [string]$TargetServer
)

# Fallback to interactive prompt if not provided
if ([string]::IsNullOrWhiteSpace($TargetServer)) {
    $TargetServer = Read-Host -Prompt 'Enter target server'
}

Write-Host "Target: $TargetServer"

Common Errors and Fixes

  • Read-Host always returns string — convert type explicitly. If you type 5 at a Read-Host prompt, you get the string "5", not the integer 5. Arithmetic with strings causes unexpected results. Always cast: [int]$inputStr, [bool]::Parse($inputStr), etc.
  • Interactive prompts break unattended scheduled scripts. A script with Read-Host that runs as a scheduled task will hang indefinitely waiting for input that never comes. Either remove Read-Host calls from scheduled scripts or protect them with a parameter-based guard that skips prompts in non-interactive mode.

Related Cmdlets / See Also

Wrapping Up

Read-Host is the right tool for genuinely interactive scripts. Always use -AsSecureString for passwords, validate with a loop, and cast the returned string to the correct type before using it. For automation scripts that run unattended, switch to function parameters instead.

Send-Item -To