Как стать автором
Обновить

Настраиваем серверные платформы с помощью PowerShell-модуля: от проверки конфигурации до монтирования образа

Уровень сложностиПростой
Время на прочтение31 мин
Количество просмотров5.8K
Всего голосов 9: ↑9 и ↓0+12
Комментарии19

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

Да, Вы правы. Стоило указать как импортировать модуль с префиксом и как задать префикс в манифесте. Добавим в статью. Спасибо.

Наверное префикс в манифесте задать должен не пользователь модуля, а его разработчик?

На самом деле, это вопрос достаточно открытый. Пересечения по именованию командлетов вполне нормальная ситуация, поэтому при импорте модуля поддерживается указание префикса, если это необходимо, и в целом допускает правку манифеста, правда это конечно накладывает дополнительные неудобства, например в случае обновления версии. При использовании ОС Windows, вероятность конфликта действительно выше, ввиду достаточно обширного функционала, поставляемого вместе с ОС. К примеру, VMware PowerCLI в некоторых командлетах кофликтует с функционалом, поставляемым в Windows для управления Hyper-V.

Вы на PowerShell только для клиентов пишите, сами его не используете? — явный импорт 12 лет как не нужен:

Beginning in Windows PowerShell 3.0, modules are imported automatically when any cmdlet or function in the module is used in a command.

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

Т.к. пользователи будут каждый свой префикс придумывать, нагуглить примеры, решение проблем будет почти невозможно.

Почему, используем. Для того, чтобы модуль импортировался автоматически, его нужно положить в директорию, которая указана в PSModulePath. В этом случае, конечно либо нужно указание префикса в манифесте, либо в случае конфликтной ситуации, использовать командлет с явным указанием модуля, например 'Yadro.Automation.Server\Set-DnsServer'.
Мы Вам очень благодарны за обратную связь, мы обязательно выложим версию с префиксом и обновим документацию.

Спасибо.

Расскажите, пожалуйста, если у вас есть опыт, компетенции в PowerShell, то почему решили сделать модуль бинарным, а не на том же PowerShell написали? Хотя бы верхнеуровневую реализацию командлетов? - и ваши наработки бы остались закрытыми и пользователям было бы проще разобраться, что происходит, добавить алиасы и проверки параметрам. Потом вернуть это вам в виде пул-реквеста.

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

К примеру, VMware PowerCLI в некоторых командлетах кофликтует с функционалом, поставляемым в Windows для управления Hyper-V.

Это не значит, что они правы и надо повторять за ними.

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

Find-ServerSystems: в параметры, принимающие на вход IP-адреса, лучше принимать объекты типа [ipaddress]

Для получения информации в табличном формате используйте алиас командлета Format-Table — ft

Такая фраза подразумевает, что только ft можно использовать, а Format-Table - нельзя

Connect-Server: Почему вы назвали параметр ManagementAddress? В PowerShell принято называть его ComputerName. Также этот командлет появляется в примерах раньше, чем его полное описание.

Get-Connection: ClientOriginAddress Тип установленной операционной системы <- тут кажется напутали что-то

Disconnect-Server - отсутствует параметр -Force - лучше добавить его для скриптов

Get-System: "if ($_.IsPoweredOn) { return "Включен" } else { "Выключен" }" <- зачем тут return?

Get-Memory: $_.ErrorCorrection -notlike "NoECC" <- либо забыли звёздочку, либо неправильный оператор сравнения

Get-ChassisPowerVoltages: "множественное число" в существительном

Restart-Manager: почему-то у этого командлета в документации появляются [-PassThru] [-WhatIf] [-Confirm], а у остальных их нет

Set-MananagerNetworkProtocol: [-IsEnabled] - почему тут тип bool, а не -Enabled типа switch?

Find-ServerSystems: в параметры, принимающие на вход IP-адреса, лучше принимать объекты типа [ipaddress]

Вы имеете ввиду тип System.Net.IPAddress? Думаю не стоит лишать пользователей возможностей передавать IP-адреса как строки, но думаю Вы правы и можно добавить отдельный Parameter Set который будет принимать параметры типа IPAddress.

Connect-Server: Почему вы назвали параметр ManagementAddress? В PowerShell принято называть его ComputerName. Также этот командлет появляется в примерах раньше, чем его полное описание.

Из практики, я встречал разные варианты именования параметров подключения к удаленному узлу. ComputerName использует в своих командлетах Microsoft. При разработке мы старались именовать параметры так, что бы имена были говорящими и отражали назначение параметра. Я не исключаю, что такие рекомендации существуют, не могли бы Вы поделится ссылкой?

Get-Connection: ClientOriginAddress Тип установленной операционной системы <- тут кажется напутали что-то

Спасибо большое за Вашу внимательность, тут действительно ошибка. "Тип установленной операционной системы" - это из другого PowerShell модуля.

Disconnect-Server - отсутствует параметр -Force - лучше добавить его для скриптов

В скриптах можно использовать -Confirm:$false, но в документации этот параметр не описан, это наше упущение, проведем повторное детальное ревью и внесем исправления.

Get-System: "if ($_.IsPoweredOn) { return "Включен" } else { "Выключен" }" <- зачем тут return?

Согласен, исправим. Спасибо.

Get-Memory: $_.ErrorCorrection -notlike "NoECC" <- либо забыли звёздочку, либо неправильный оператор сравнения

Забыли звездочку, исправим. Спасибо.

Get-ChassisPowerVoltages: "множественное число" в существительном

Согласен, исправим. Спасибо.

Restart-Manager: почему-то у этого командлета в документации появляются [-PassThru] [-WhatIf] [-Confirm], а у остальных их нет

В документации есть упущения и ошибки, обязательно все исправим. Спасибо.

Set-MananagerNetworkProtocol: [-IsEnabled] - почему тут тип bool, а не -Enabled типа switch?

Вы правы, там должен быть switch и это не единственный командлет, где в описании параметров допущена эта ошибка. Все исправим.

Еще раз спасибо Вам за внимательное чтение документации и что указали нам на все ошибки и недочеты.

Вы имеете ввиду тип System.Net.IPAddress? Думаю не стоит лишать пользователей возможностей передавать IP-адреса как строки, но думаю Вы правы и можно добавить отдельный Parameter Set который будет принимать параметры типа IPAddress.

При указании типа параметра [ipaddress], он не теряет возможность принимать на вход строки - эта функциональность продолжает работать. Плюс срабатывает неявная конвертация и внутри функции вы получаете вместо строки - объект IP-адреса.
Плюс дополнительно вы получаете встроенную валидацию на правильность переданного значение - а IP-адрес ли это вообще.
Плюс всё это автоматически принимает на вход не только IPv4, но и IPv6. Короче тут даже больше программисту командлета жизнь упрощается.

Я не исключаю, что такие рекомендации существуют, не могли бы Вы поделится ссылкой

Нет, таких рекомендаций записанных я не видел, но я вижу как Microsoft в своих командлетах называет параметры, и как - сообщество.

Я в своих модулях тоже всегда, где возможно, называю это ComputerName

Find-ServerSystems
Connect-Server
Get-Connection
Disconnect-Server

по идее, Noun должен быть одинаковый, а сейчас семантика нарушена

New-Account

  1. от командлетов New- ждут, что они вернут объект. У вас он молчаливый. Лучше тогда переделать его на Add-

  2. параметр Password не должен быть string, правильнее будет пару параметров Username и Password заменить на Credential

  3. присоединяюсь к вопросу @exchange12rocks: почему -IsEnabled типа bool, а не -Enabled типа switch? Да и то же касается всех прочих bool.

  4. состояние Enable традиционно управляется отдельными командлетами. Было бы неплохо добавить Enable-Account и Disable-Account

Измените порт:
PS> Set-RemoteLoggingServer -Manager $manager -Address 1.10.1.11 -Port 3034
Пример вывода:

Succeed
-------
True

Зачем этот вывод? — его потом приходится принудительно заглушать. При ошибке должно сформироваться исключение. При успехе должна быть "тишина". То же самое с Start-System и Restart-System

Судя по документации Set-HttpsCertificate и Add-HttpsCertificate делают одно и то же — задают единственный сертификат web-интерфейса. Или первый раз нужно делать только Add, а потом только Set?

-PassThru
Запрашивает выходные данные, если по умолчанию командлет их не выводит.

не запрашивает (интерактивно у пользователя), а возвращает изменённый объект

-AccountService
Учетная запись сервиса. Принимает на вход результат выполнения командлета Get-AccountService (стр. 52).

а не наоборот: учётная запись сервиса — Service Account ?

Если

Командлет Get-VirtualMedia возвращает информацию о подключенных виртуальных носителях.

а

Командлет Mount-VirtualMedia подключает виртуальный носитель информации.

то зачем у командлета Mount-VirtualMedia параметр

-VirtualMedia
Подключаемый виртуальный носитель информации. Принимает на вход результат выполнения командлета Get-VirtualMedia

зачем подключать (монтировать) уже смонтированное?

-DnsServers
Настраиваемый клиент DNS-сервера.

наверное всё же «список DNS-серверов»?

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

++

Find-ServerSystems
Connect-Server
Get-Connection
Disconnect-Server

по идее, Noun должен быть одинаковый, а сейчас семантика нарушена

Согласен, надо придерживаться одинакового Noun. Спасибо, поправим.

New-Account

  1. от командлетов New- ждут, что они вернут объект. У вас он молчаливый. Лучше тогда переделать его на Add-

  2. параметр Password не должен быть string, правильнее будет пару параметров Username и Password заменить на Credential

  3. присоединяюсь к вопросу @exchange12rocks: почему -IsEnabled типа bool, а не -Enabled типа switch? Да и то же касается всех прочих bool.

  4. состояние Enable традиционно управляется отдельными командлетами. Было бы неплохо добавить Enable-Account и Disable-Account

  1. Add это добавление чего-то существующего, а не создание нового, поэтому в данной ситуации Verb верный. Насчет возврата созданного объекта - согласен. Добавим.

  2. Это желательно, но не строгое правило. Думаю тут лучше сделать через Parameter Set возможность передавать Password как SecureString или передавать, как Вы справедливо указали, Username и Password как PSCredential.

  3. Ответил в комментарии @exchange12rocks- это ошибка в документации, исправим.

  4. Согласен, добавим. Спасибо.

Измените порт:
PS> Set-RemoteLoggingServer -Manager $manager -Address 1.10.1.11 -Port 3034
Пример вывода: 

Succeed
-------
True

Зачем этот вывод? — его потом приходится принудительно заглушать. При ошибке должно сформироваться исключение. При успехе должна быть "тишина". То же самое с Start-System и Restart-System

Соглашусь, можно убрать. Добавим в документацию пример с ошибкой и -ErrorAction

Судя по документации Set-HttpsCertificate и Add-HttpsCertificate делают одно и то же — задают единственный сертификат web-интерфейса. Или первый раз нужно делать только Add, а потом только Set?

Это особенность Redfish API сервера. В первый раз HTTPS сертификат нужно добавить, потом только заменить.

-PassThru
Запрашивает выходные данные, если по умолчанию командлет их не выводит.

не запрашивает (интерактивно у пользователя), а возвращает изменённый объект

Вы правы, в документации неверное описание параметра PassThru. Исправим спасибо.

-AccountService
Учетная запись сервиса. Принимает на вход результат выполнения командлета Get-AccountService (стр. 52).

а не наоборот: учётная запись сервиса — Service Account ?

Нет, тут ошибка в описании объекта. Это не учетная запись сервиса, а объект сервиса, отвечающего за управление пользователями, ролями, подключениями к службам каталогов и т.д... Исправим, спасибо.

Командлет Get-VirtualMedia возвращает информацию о подключенных виртуальных носителях.

а

Командлет Mount-VirtualMedia подключает виртуальный носитель информации.

то зачем у командлета Mount-VirtualMedia параметр

-VirtualMedia
Подключаемый виртуальный носитель информации. Принимает на вход результат выполнения командлета Get-VirtualMedia

зачем подключать (монтировать) уже смонтированное?

Тут возможно не достаточно подробно расписано. VirtualMedia - это виртуальное устройство для подключения образов дисков. Таких устройств на сервере может быть несколько. Устройство присутствует в независимости от того, смонтирован ли образ на это устройство или нет. Командлет Get-VirtualMedia, покажет доступные устройства, Mount-VirtualMedia - смонтрирует образ в конкретное устройство.

-DnsServers
Настраиваемый клиент DNS-сервера.

наверное всё же «список DNS-серверов»?

Вы абсолютно правы, описание некорректно.

Я так же хочу выразить Вам нашу благодарность за внимательное чтение документации и на то, что указали нам на ошибки, недочеты и дополнения, которые могут быть полезны. Вы и @exchange12rocksдали замечательную обратную связь, нам есть над чем поработать, чтобы сделать продукт лучше. Спасибо еще раз.

Спасибо ?

У меня два вопроса:
1. Почему PowerShell?
2. Почему модуль бинарный?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий