Если вспомнить времена MS-DOS и первые версии Windows, то каждая версия содержала в комплекте утилиту с интерфейсом командной строки: command.com или cmd.exe, но они поддерживали крайне скудный список команд. Если для администрирования системы нужно было запустить скрипт, то он запускался из отдельного исполняемого файла с расширением .bat. Microsoft пыталась исправить ситуацию с помощью других вспомогательных инструментов, но не слишком удачно.

И вот тут на сцене появился Джеффри Сновер, ведущий разработчик консольной программы PowerShell, которая сильно изменила способ администрирования Windows-систем.

В 2003 году группа под руководством Джеффри Сновера начала разработку новой оболочки, которую назвали Monad (также известная как Microsoft Shell или MSH). Она должна была автоматизировать весь спектр административных задач. Первая публичная бета вышла 17 июня 2005 года. В 2006 году Monad официально переименовали в Windows PowerShell, а финальная версия (Release to Web, RTW) была выпущена 14 ноября 2006 года для Windows XP SP2 и Windows 2003.

▍ PowerShell



PowerShell — это кроссплатформенный инструмент (Windows, Linux и macOS) для автоматизации действий и настройки системы, который хорошо сочетается с существующими инструментами и оптимизирован для работы со структурированными данными (например, JSON, CSV, XML и т. д.), REST API и объектными моделями. Он включает в себя оболочку командной строки, соответствующий скриптовый язык и фреймворк для обработки команд.

Исходники программы открыли с началом разработки PowerShell Core в августе 2016 года.

▍ История создания


Недавно Джеффри Сновер дал интересное интервью в подкасте Recursive, где рассказал об истории создания PowerShell. Оказывается, для продвижения этой программы ему пришлось преодолевать сопротивление внутри компании. Корпоративная культура Microsoft натурально противилась созданию Unix-подобного инструмента и включению его в состав Windows.

Идея изначально была встречена с большим скептицизмом, потому что продвинутая текстовая консоль не вписывалась в стандартную идеологию GUI-интерфейсов Windows.

Но в то время перед Microsoft стояла важная задача — сделать Windows NT конкурентной с Linux на серверном рынке. Очевидно, что использовать GUI очень неудобно, если вам нужно настроить сотни или тысячи аккаунтов, это отнимает много времени. Ожидаемый рабочий процесс для серверов заключался в том, что администраторы вручную входили на каждый сервер, чтобы запустить процессы.

С другой стороны, консольными скриптами можно обмениваться. И если один администратор удачно выполнил задачу, он может поделиться своим скриптом с другими. Именно поэтому Unix доминирует на серверах с 80-х годов.

За пару лет до этого Билл Гейтс в одном из выступлений запустил command.com и сказал: «Посмотрите, вот command.com, и это последний раз, когда вы его видите, набрал команду exit и нажал Enter». Эта история началась ещё в 1999 году. Windows была очень успешна на рынке персональных компьютеров, но Билл Гейтс беспокоился о том, что она никак не совместима с дата-центрами, а ведь на этом корпоративном рынке крутятся огромные деньги, может даже больше, чем на рынке обычных ПК. В то время было очевидно, что рынок двигается в сторону облачных решений.

Хуже было то, что руководство Microsoft тоже привыкло жить в старых реалиях, они разбирались в персональных компьютерах, но не понимали серверный рынок. Вот тогда они и нашли Джеффри и пригласили его на работу. Поначалу он не соглашался и говорил: «Нет, у вас негодный софт», но собеседник Джим Алген тогда ответил: «Да, я это знаю, и поэтому мне нужна твоя помощь, чтобы исправить это. Если ты нам поможешь, подумай, какой эффект это произведёт на мир». Так его и убедили.

Значение PowerShell было не только в том, что он повлиял на разработку других CLI, но он ещё позволил Microsoft запустить облачный сервис и успешно конкурировать с другими. А самое важное, культивировал большую экосистему системных администраторов Windows.

Цель была понятна: установить Windows NT как реального конкурента для вендоров Unix-систем, таких как Sun, IBM и HP. Теоретически, у Microsoft было стратегическое преимущество благодаря сотрудничеству с Intel, оставалось только выпустить годный софт, и они могли предложить услуги за меньшую цену, чем конкуренты.

Проблемой ещё было системные интеграторы вроде IBM Professional Services, которые сильно накручивали цены на установку софта от Microsoft. На каждую машину программы надо было ставить вручную через графический интерфейс. А как избавиться от системных интеграторов? Разработать встроенный механизм системной интеграции. В Unix такое было, там клиенты сами настраивали системы, не обращаясь к системным интеграторам, а с помощью собственных админов. Вот что нужно было Microsoft. Воспитать собственный класс профессиональных администраторов. Это был в первую очередь финансовый вопрос, потому что свои админы гораздо дешевле системных интеграторов.

Джеффри присоединился к отделу Windows Server, чтобы решить эту задачу. Сотрудникам Microsoft было нелегко принять новую логику и думать о дата-цетрах и системном администрировании в Unix-стиле. Сервисы на серверах запускали из командной строки или через удалённый рабочий стол. То есть каждый раз при загрузке Windows кто-то должен был залогиниться туда и ввести команду.

Философия Unix отличалась от этого стиля. Там предполагается использовать конвейеры из маленьких инструментов, каждый инструмент для своей задачи. И если возникают какие-то проблемы, то администратор просто составляет эти маленькие инструменты в другой последовательности, чтобы решить эту проблему. В Microsoft противоположная логика: для каждой новой проблемы они выпускают новый инструмент. А если проблема меняется, то выпускают новую версию своей программы, и так далее.

Изначально в качестве консоли предлагали использовать Службы Windows для Linux, где была консоль и другие инструменты Unix. Вот тогда стала понятна серьёзная разница в архитектуре с Unix, где всё представляет собой файл. А в Windows файлов, собственно, очень мало, поэтому вы не можете эффективно использовать awk, grep, sed и проч. Здесь наоборот, всё спрятано за API, так что те же awk, grep, sed не будут искать в реестре, Active Directory или WMI. Так что Unix-инструменты здесь не работали.

Единственным средством настройки Windows были Windows Managemet Instrumention (WMI), но пользователи мало их использовали, и Джеффри увидел в этом возможность: создать текстовую консоль для управления всем: настройками пользователя, сетевой конфигурацией, установкой приложений — всё через WMI.

Если считать по количеству объектов в WMI, то эта консоль должна поддерживать тысячи команд. Интересно, что для разработки пришлось нанимать программистов по контракту, потому что штатные разработчики Microsoft не смогли осилить такую задачу.

Дедлайн ему поставили через десять недель. Логика была такая, что нужно выпустить хоть какую-то глючную версию программы, а потом исправлять баги. Джеффри оплатил работу контрактным программистам, и они успели реализовать примерно 70 функций (команд). Это было только начало.

Но затем оказалось, что никакая программа не может выйти без одобрения отдела тестирования. А это очень долгая бюрократическая процедура, они хотели буквально проверить каждую команду. Джеффри не мог допустить такой задержки, поэтому придумал другую процедуру с составлением файла метаданных, который проверяет корректность работы программы, а не проходит по всем функциям. Так вышла первая версия PowerShell с поддержкой 72 команд. Это было практически одновременно с выходом Windows XP на ядре NT.

Потом оказалось, что в Microsoft есть ещё одна группа, которая разрабатывает консоль. Но они просто взяли K-shell и портировали её. Тогда Джеффри буквально заперся в комнате и собственноручно написал то, что станет первым прототипом PowerShell, это было демо на 10 000 строк кода. Он показал его коллегам из того отдела, впечатлил их, и они стали работать вместе, а Джеффри удалось получить финансирование под проект. Так родился PowerShell (хотя изначально он назывался Monad), а самого Джеффри понизили в должности, потому что отдел PowerShell насчитывал всего несколько человек.

В итоге проекту PowerShell дали зелёный свет. Главная причина — попытка Microsoft укрепить свои позиции на серверном рынке. Нельзя сказать, что эта мера полностью изменила расклад сил, но позиции Microsoft всё-таки немного укрепились. По статистике W3Techs за июль 2024 года, сейчас доля Windows составляет 14,7%, а доля Unix-подобных систем — 85,6%.


Самое замечательное, что PowerShell сблизил между собой системных администраторов и программистов. Первые начали писать скрипты и автоматизировать сложные задачи. Они создавали группы в интернете и делились советами.

▍ Консоль стимулирует сотрудничество


В то же время есть мнение, что GUI вообще антисоциальная среда в том смысле, что не поощряет сотрудничество между людьми — в нём не сохраняются действия, поэтому вы не можете поделиться ими с коллегами.

В текстовой консоли любое решение проблемы, любая последовательность действий представляет собой «артефакт» (скрипт), который можно сохранить, воспроизвести или опубликовать в открытом доступе.

Это интересное мнение.

Как мы подробно разбирали раньше, плохой GUI допускает также множество злоупотреблений цветом, звуком, расположением элементов:

  • несочетающиеся ядовитые цвета,
  • непонятные кнопки,


  • всплывающие окна,
  • капчи с глупыми задачами,
  • окна, развёрнутые на весь экран, которые невозможно свернуть,
  • манипуляции поведением, когда нужный нам выбор спрятан маленьким шрифтом в углу, а ненужный выбор выделен по умолчанию,
  • и многое другое...

То есть в целом GUI может снижать производительность. Работа в консоли производит противоположный эффект: она повышает производительность и подталкивает к тому, чтобы использовать её максимально продуманным и эффективным способом.

В каком-то смысле, графический интерфейс кажется чем-то более примитивным. Хотя есть примеры, как GUI тоже используется максимально эффективно, в стиле спидрана (выполнение задачи на скорость):

Разумеется, в графических, видео- и звуковых редакторах, а также многих других областях графический интерфейс незаменим. Работа с ним может выглядеть очень профессионально. Но обычно действия в нём довольно простые, а повторять нечего. А вот в консоли можно составить такую последовательность команд с интересными параметрами, что будет выглядеть действительно гениально. Коллеги оценят ваш профессионализм. Более того, они могут использовать этот скрипт в своих системах. Вот что такое социальная среда.

Конечно, в GUI тоже можно записать маленький скринкаст с записью всех действий на экране, но здесь гораздо меньшая степень автоматизации.

Консоль в каком-то смысле более человечный инструмент, если так можно выразиться. Она поощряет общение, стимулирует креативность, изобретательность, любопытство и постоянное обучение новым трюкам и приёмам. Горячие клавиши, скрипты. К сожалению, в графических десктопных программах горячие клавиши доступны не для всех действий, да и вообще UI/UX зачастую оставляет желать лучшего.

В то же время в мире полно примеров замечательных графических интерфейсов, над которыми разработчики потратили тысячи человеко-часов, оттачивая все детали, так что умалять эффективность GUI мы тоже не будем. Дизайнеры, архитекторы, фотографы и представители сотен других профессий благодарны разработчикам GUI и специализированного софта.

Кстати, софт для автоматизации действий в GUI тоже имеется. Например, Automator и AppleScript в macOS, а также Power Automate и VBS в Windows.

Возвращаясь к карьере Джеффри Сновера, он отработал в Microsoft целых 22 года на различных должностях, последние три с половиной года как Technical Fellow и CTO, а два года назад перешёл в Google в роли «заслуженного инженера» (Distinguished Engineer) в отделе Site Reliability Engineering (SRE). Вообще, его карьера в IT началась с 1978 года, в ней были корпорации DEC, IBM и другие, так что это настоящий ветеран нашей отрасли.

По теме:


Telegram-канал со скидками, розыгрышами призов и новостями IT ?

Комментарии (19)


  1. GBR-613
    05.08.2024 17:04
    +3

    сейчас доля Windows составляет 14,7%, а доля Unix-подобных систем — 85,6%

    Вместе больше 100%??


    1. NeonMercury
      05.08.2024 17:04

      Та не, просто на некоторых серверах сразу две системы стоит


  1. voldemar_d
    05.08.2024 17:04

    Разумеется, в графических, видео- и звуковых редакторах, а также многих других областях графический интерфейс незаменим. Работа с ним может выглядеть очень профессионально. Но обычно действия в нём довольно простые, а повторять нечего. 

    То-то макросы и скрипты есть буквально во всём: текстовых редакторах, видеомонтажках, звуковых редакторах, графических - достаточно вспомнить Actions в Photoshop. И речь не просто о горячих клавишах. Хотя, есть и программы, позволяющие последовательности нажатий клавиш записывать и повторять.


  1. Kahelman
    05.08.2024 17:04
    +1

    Создал Windows Powershell а потом Powershell 7 которые между собой не совсем совместимы.

    Полюс версии Windows Powershell между собой не очень совместимы, как всегда MA в лучших традициях….

    Вместо того чтобы использовать имеющиеся утилиты, и просто добавить нормальный скриптовый язык, хоть тот же bash портировать, родили новое чудо в перьях, которое вроде работает но не как нормальный скрипт, и не как нормальный язык программирования с классами.

    Это как с file link, вроде добавили, но пользоваться нормально нельзя. Что-то Linux подобное только в development mode можно включить.


    1. Kahelman
      05.08.2024 17:04
      +4

      Сей час залез в wiki, очень порадовало:

      Powershell cmdlet : Test-Connection

      Alias: ping

      Windows command prompt: ping

      Linux: ping

      Кто этот гений, который для простой, де-факто стандартной команды: ping придумал имя Test-Connection?

      Интересно, есть статистика, кто Test-Connection пишет вместо ping?


      1. gavrilovegor519
        05.08.2024 17:04
        +1

        Дак там же (в Повершелле) под капотом Дотнет, насколько я помню. Оттуда и дотнетоподобные названия команд.


      1. ahabreader
        05.08.2024 17:04
        +3

        Там есть идея начинать команды с глагола из одобренного списка ради унификации, но обычно аз-за алиасов это проблем не вызывает ("Alias: ping" - откуда это? Ни в wiki, ни в 7.2 нет).

        Гениев надо искать другим образом.

        • Powershell до последнего времени не умел передавать через пайпы двоичные данные. Объекты внутри Powershell - нормально, текст и нативные приложения - нормально, двоичные данные и нативные предложения - нельзя, они парсятся как текст, ломаются и это не отключалось первые 17-18 лет. Решение - вызывать cmd.exe /с и использовать пайпы в нём.

        • Powershell при вызове нативных приложений автоматически парсит аргументы, чтобы их можно было записывать как в обычном шелле (а не массивом строк), но отдельно доступа к парсеру не даёт. ./metaflac --show-bps --show-md5sum "some name.flac" - да, но если аргументы лежат в переменной-строке, то никак нет, распарсить в массив строк надо как-нибудь самостоятельно. С помощью вызова cmd.exe, например.

        • Команды по умолчанию принимают пути с wildcard'ами. * и ? в Windows и так нельзя использовать в именах файлов, так в чём же проблема? А к ним добавили [ и ]. Проблема решается специальным параметром -LiteralPath (-lit) вместо [-Path], но его повсюду добавлять утомительно, поэтому во все команды его решили и не добавлять...

        • И так далее. Powershell то гениален, то гениально туповат. Неизбежное "разворачивание" массива из 1 объекта в объект. Театр безопасности с запретом запуска двойным кликом или перетаскиванием, что решается опять не без помощи cmd.exe, подобными файлами-химерами:

        <# : batch part begin
        @echo off & pwsh -c "cat '%~f0' | Out-String | Invoke-Expression" & pause & exit /b
        batch part end #>
        
        # powershell code...


        1. exchange12rocks
          05.08.2024 17:04

          передавать через пайпы двоичные данные

          Потому что Windows PowerShell делался для администрирования Windows, а там такое нужно супер-редко: за 15 лет мне ни разу такое не понадобилось.

          если аргументы лежат в переменной-строке, то никак нет, распарсить в массив строк надо как-нибудь самостоятельно

          Скажите, пожалуйста, в каком сценарии такое требуется? Тот пост на SO не даёт контекста зачем топикстартеру это нужно.


          1. mayorovp
            05.08.2024 17:04
            +1

            Потому что Windows PowerShell делался для администрирования Windows, а там такое нужно супер-редко: за 15 лет мне ни разу такое не понадобилось.

            Зато парсить вывод утилиты самостоятельно (из-за того что она пишет в своей особенно кодировке) нужно супер часто, а нельзя.

            Скажите, пожалуйста, в каком сценарии такое требуется? Тот пост на SO не даёт контекста зачем топикстартеру это нужно.

            В основном потому что люди привыкли аргументы записывать в строку "как в баше", и не в курсе что даже в баше для этих целей давно уже можно использовать массивы.


          1. ahabreader
            05.08.2024 17:04

            Всё-таки он уже 8 лет кроссплатформенный и на роль всесторонней замены cmd.exe его метили изначально.

            Mozjpeg'овский jpegtran, например, имеет вывод только в stdout, в Powershell перенаправление двоичного потока в файл тоже сломано в рамках этой багофичи.

            Скажите, пожалуйста, в каком сценарии такое требуется?

            Когда строка аргументов уже есть*, или когда её нужно сильно менять. В некоторых программах строка аргументов плавно перетекает в целый скриптовый язык, как в imagemagick, нужна гибкость хотя бы на уровне батников.

            * Выше можно дописать @echo off & set "bat_args=%*" & pwsh... и получить доступ из Powershell-части так:$env:bat_args (это будет сырая строка, которую надо парсить).


        1. mayorovp
          05.08.2024 17:04

          Powershell при вызове нативных приложений автоматически парсит аргументы, чтобы их можно было записывать как в обычном шелле (а не массивом строк), но отдельно доступа к парсеру не даёт

          Есть же Invoke-Expression, вы его даже использовали ниже

          Неизбежное "разворачивание" массива из 1 объекта в объект.

          Есть такое, "контрится" через Array subexpression operator, который @()

          А ввели его потому что иначе ни одна команда не смогла бы вернуть одиночный объект в принципе, они же всегда поток объектов возвращают.

          .Театр безопасности с запретом запуска двойным кликом или перетаскиванием, что решается опять не без помощи cmd.exe, подобными файлами-химерами:

          Что-то сложное у вас написано. зачем тут вообще Invoke-Expression?

          pwsh -file "%~f0" -executionpolicy bypass
          


          1. ahabreader
            05.08.2024 17:04
            +1

            Что-то сложное у вас написано. зачем тут вообще Invoke-Expression?

            Проще не выйдет, потому что cmd.exe и Powershell щепетильно относятся к расширениям. Файл должен иметь расширение .bat или .cmd, чтобы его выполнял cmd.exe. Но чтобы сработал pwsh -File, нужно расширение .ps1. Не обойтись без временного файла с правильным расширением (.ps1) или "eval" файла как строки.

            Есть такое, "контрится" через Array subexpression operator, который @()

            В одних случаях через @() , в других через ,(). Если если вместо первого по ошибке использовать второе, то вместо пустого массива можно получить массив с одним $null. Если наоборот, то где-то вместо двухмерного массива может получиться одномерный. В третьих случаях через -NoEnumerate, в четвёртых лучше заранее смириться. Для отладки полезен вывод ConvertTo-Json $obj.

            Не знаю, возврат массива из одного элемента мог бы оказаться меньшей проблемой - выручала бы фича member-access enumeration, когда обращение отсутствующему члену массива разворачивается в обращение к членам всех элементов: @('abc','def').ToUpper() (у массива нет методаToUpper() , поэтому метод вызовется у каждого элемента массива).

            Есть же Invoke-Expression, вы его даже использовали ниже

            У eval есть известные недостатки, иногда его стоит избегать... и нелепым образом как-нибудь добывать парсер аргументов (самописный / на регулярках / из cmd.exe / изConvertFrom-Csv / из WinAPI CommandLineToArgvW).


      1. Cujoko
        05.08.2024 17:04

        Я такое не пишу, конечно. Но пишу sl вместо cd и gci вместо dir.


      1. exchange12rocks
        05.08.2024 17:04
        +1

        ping - это встроенная команда в ОС

        Test-Connection - PowerShell командлет

        Они обладают разными возможностями, отдают результат в разных форматах. Делать алиас ping, значит усложнять доступ к нативной команде. Вон с алиасом wget сколько уже наелись.


      1. mayorovp
        05.08.2024 17:04

        Кто этот гений, который для простой, де-факто стандартной команды: ping придумал имя Test-Connection?

        Там все команды такие, лично меня уже через 10 минут работы они раздражать перестали (хвала автодополнению)


    1. exchange12rocks
      05.08.2024 17:04
      +1

      Создал Windows Powershell а потом Powershell 7 которые между собой не совсем совместимы.

      Скрипты/команды Windows PowerShell прекрасно работают в PowerShell (который Core/6/7 etc.). Но в PowerShell добавили новые возможности, которые отсутствуют в Windows PowerShell - вот и всего.


  1. RS6
    05.08.2024 17:04
    +2

    Выглядит очень похоже на краткий пересказ подкаста CORECURSIVE #102 "Navigating Corporate Giants Jeffrey Snover and the Making of PowerShell", но почему-то никакого его упоминания нет. Правильно ли это?


  1. AndrewJD
    05.08.2024 17:04
    +2

    С другой стороны, консольными скриптами можно обмениваться. И если один администратор удачно выполнил задачу, он может поделиться своим скриптом с другими. Именно поэтому Unix доминирует на серверах с 80-х годов

    Windows Script Host (WSH) поддерживается с середины 90-х. На JS или VBS можно было писать любые скрипты.


    1. mayorovp
      05.08.2024 17:04

      Только все эти приседания чтобы проделать простейшие вещи, вроде запуска дочернего процесса - не то, как должен выглядеть нормальный шелл