Я сделаю удар, хотя у меня нет опыта работы с PHP вообще.
У меня такое ощущение, что происходит то, что ваш символ канала интерпретируется командной оболочкой вместо PowerShell. Например, если вы запустили в командной строке cmd.exe следующее:
dir /s | more
Выход первой команды передается на вход второй, как вы и ожидали в PowerShell.
Экранирование строки только усугубит проблему, поскольку вы преобразуете строку таким образом, что PowerShell не знает, как ее удалить.
Попробуйте заключить оригинальное выражение PowerShell в кавычку, подобную следующей:
$output = shell_exec('powershell.exe -c "get-service | group-object"');
Или, предпочтительно, похоже, что есть функция exec (), которая не проходит через командную оболочку. Это может работать лучше.
$output = exec('powershell.exe -c get-service | group-object');