@@ -176,10 +176,12 @@ private function prompt() {
176176 }
177177
178178 private static function create_prompt_cmd ( $ prompt , $ history_path ) {
179- $ prompt = escapeshellarg ( $ prompt );
180- $ history_path = escapeshellarg ( $ history_path );
179+ $ is_windows = \ WP_CLI \ Utils \is_windows ( );
180+
181181 if ( getenv ( 'WP_CLI_CUSTOM_SHELL ' ) ) {
182182 $ shell_binary = (string ) getenv ( 'WP_CLI_CUSTOM_SHELL ' );
183+ } elseif ( $ is_windows ) {
184+ $ shell_binary = 'powershell.exe ' ;
183185 } elseif ( is_file ( '/bin/bash ' ) && is_readable ( '/bin/bash ' ) ) {
184186 // Prefer /bin/bash when available since we use bash-specific commands.
185187 $ shell_binary = '/bin/bash ' ;
@@ -191,10 +193,19 @@ private static function create_prompt_cmd( $prompt, $history_path ) {
191193 $ shell_binary = 'bash ' ;
192194 }
193195
194- if ( ! is_file ( $ shell_binary ) || ! is_readable ( $ shell_binary ) ) {
195- WP_CLI ::error ( "The shell binary ' {$ shell_binary }' is not valid. You can override the shell to be used through the WP_CLI_CUSTOM_SHELL environment variable. " );
196+ $ is_powershell = $ is_windows && 'powershell.exe ' === $ shell_binary ;
197+
198+ if ( $ is_powershell ) {
199+ // PowerShell uses ` (backtick) for escaping but for strings single quotes are literal.
200+ // If prompt contains single quotes, we double them in PowerShell.
201+ $ prompt_for_ps = str_replace ( "' " , "'' " , $ prompt );
202+ $ cmd = "\$line = Read-Host -Prompt ' {$ prompt_for_ps }'; Write-Output \$line; " ;
203+ return "powershell.exe -NoProfile -Command \"{$ cmd }\"" ;
196204 }
197205
206+ $ prompt = escapeshellarg ( $ prompt );
207+ $ history_path = escapeshellarg ( $ history_path );
208+
198209 $ is_ksh = self ::is_ksh_shell ( $ shell_binary );
199210 $ shell_binary = escapeshellarg ( $ shell_binary );
200211
0 commit comments