Допустим, что первоначальная настройка сервера после установки включает в себя:
- Настройку сетевых интерфейсов
- Установку часового пояса
- Включение удаленного рабочего стола
- Переименование компьютера
- Присоединение к домену
Вопрос в следующем: а можно ли эти задачи выполнить удаленно средствами PowerShell? Ну вот, допустим, есть удаленный сервер где-нибудь в тайге, на который местный умелец поставил 2012 сервер, пошел отметить это дело и потерял ключ от шкафа. Шкаф бронебойный, водо-, звуконепроницаемый и вообще предполагает защиту от несанкционированного доступа медведей. А настроить надо. Допустим, есть VPN или какой-нибудь «прямой провод» (очень часто вижу эту услугу в прайсах провайдеров) и сервер доступен по сети. И только по сети.
В исходных данных письмо от местного умельца:
Привет, поставил венду на сервер. IP – 169.254.23.43. Логин – Администратор. Пароль – qwe123!@#. Пока.
Готовимся
Удаленный сервер в рабочей группе, в свежеустановленном состоянии, RPC не понимает (порты на брандмауэре закрыты), не пингуется, с непроизносимым именем и московским часовым поясом в Сибири. Если бы это был 2008 R2 на этом бы наши приключения и закончились, так как все средства удаленного управления в нем по умолчанию отключены. В 2012 есть способ удаленно управлять из коробки – включенный по умолчанию WinRM, реализация стандарта WS-MAN от Microsoft. С одной стороны вроде дыра в безопасности, с другой – в нормально спроектированной сети, в которой сервера находятся в отдельном VLAN, доступ к которому ограничен для доверенных пользователей, вероятность использования этой дыры незначительна. Но все-таки есть.
Для управления удаленным сервером в рабочей группе с помощью WinRM, мы должны доверять удаленному серверу. Тут мне логика немного непонятна. По идее, удаленный сервер должен доверять нам, мы же им управляем, а не он нами. Возможно, это от неполного понимания принципов работы WS-MAN. Но в любом случае, сказать WinRM, что мы доверяем удаленному серверу нужно. Это реализовано занесением имени или IP-адреса удаленного сервера в список «доверенных хостов» (TrustedHosts)
si WSMan:\localhost\Client\TrustedHosts 169.254.23.43
Теперь как-то нужно выполнить первоначальную настройку удаленного сервера. Я знаю 2 командлета, которые могут помочь с этой задачей: Enter-Pssession и Invoke-Command. Оба используют WinRM. Enter-Pssession дает нам консоль удаленного сервера, Invoke-Command отправляет блок команд на удаленный сервер и возвращает результат их выполнения. Ниже используется Invoke-Command (мы же собрались вообще не видеть удаленную консоль).
Действия будем выполнять по следующему принципу:
- PowerShell
- Если не получается выполнить задачу через PowerShell, подключаем cmd
- Если не в PowerShell, не в cmd нет подходящих инструментов – WMI через PowerShell
- Ну и как последний вариант – ковыряние реестра также через PowerShell
Настройка сетевых интерфейсов
Делать нечего, меняем свой адрес на что-нибудь из APIPA-диапазона, ну например 169.254.0.1 и садимся думать, как удаленно изменить IP-адрес у таёжного сервера. Думать тут нечего:
- Определить на каком адаптере производить изменения
- Отключить DHCP
- Назначить статический адрес для сервера с маской подсети и шлюзом по умолчанию.
- Hазначить DNS-серверы
И все это желательно не отцепляясь от сервера.
В PowerShell 3.0 появилась целая группа Network Adapter Cmdlets, которая позволяет нам делать с сетевыми адаптерами все что угодно.
Получаем объект сетевого адаптера и сохраняем его в переменной $adapter. Ethernet – это новое имя для «Подключение по локальной сети». Это изменение, несмотря на кажущуюся незначительность, очень радует.
$adapter = Get-NetAdapter Ethernet
Отключаем DHCP
$adapter | Set-NetAdapter –Dhcp disabled
Меняем IP-адрес на нормальный с необходимой маской и шлюзом. Для этого существует другая группа Net TCP/IP Cmdlets
$adapter | New-NetIPAddress 192.168.0.5 –PrefixLength 24 –DefaultGateway 192.168.0.1
Добавляем DNS-серверы. Третья группа DNS Client Cmdlets
Set-DnsClientServerAddress Ethernet –addresses (“192.168.0.2”,”192.168.0.3”)
Как все это выполнить на удаленном сервере? Сделать скрипт и с помощью Invoke-Command запустить его на выполнение.
Сохраним этот набор команд где-нибудь с именем скрипта, например, remotechangeip.
Set-ExecutionPolicy remotesigned
Политика выполнения скриптов устанавливается на локальном компьютере, на удаленном такой необходимости нет, потому что Invoke-Command перед выполнением скрипта на удаленном компьютере преобразовывает файл скрипта в просто набор команд. Соответственно, на удаленном компьютере выполняется не скрипт (файл с расширением .ps1), а набор команд, которым политика выполнения скриптов по барабану.
Отправляем наш скрипт на удаленный сервер.
Invoke-Command 169.254.23.43 C:\scripts\remotechangeip.ps1 –Credential Администратор
Пароль от учетной записи Администратор у нас есть в письме. После выполнения получаем сервер со статическим адресом 192.168.0.5 с маской подсети /24, шлюзом по умолчанию 192.168.0.1 и DNS-серверами 192.168.0.2 и 192.168.0.3
Еще нужно не забыть изменить IP в TrustedHosts, иначе на этом наше удаленное администрирование закончится.
$newvalue = ((ls WSMan:\localhost\Client\TrustedHosts).value).replace("169.254.23.43","192.168.0.5")
si WSMan:\localhost\Client\TrustedHosts $newvalue
Изменение часового пояса
Я очень долго пытался решить эту задачу с помощью PowerShell. Я нашел функцию, меняющую часовой пояс локально. Но если мы попытаемся выполнить эту функцию через Invoke-Command, получим граблями по лбу в виде «Имя Set-Timezone не распознано как имя командлета, функции, файла сценария или выполняемой программы».
Invoke-Command при выполнении естественно не копирует с локальной машины, а выполняет имеющиеся на удаленном сервере командлеты. Это понятно и логично. Задача была ясна — перед выполнением Invoke-Command нужно сбросить функцию на удаленный сервер. Но… тут мне стало лень.
Если заглянуть в код функции, то становится понятно, что она всего лишь проверяет версию ОС и в зависимости от нее выполняет либо timedate.cpl (XP и ниже), либо tzutil (Vista и выше). Проверять версию ОС незачем, мы ее знаем. Поэтому просто изменим часовой пояс с помощью tzutil
Invoke-Command 192.168.0.5 {tzutil /s “North Asia Standard Time”} –Credential Администратор
$strComputer = "."
$objWMI = gwmi win32_computersystem" -computername $strComputer
$objWMI.CurrentTimeZone = 207
$objWMI.Put()
Что здесь происходит? Точка (.) говорит, что мы работаем с локальным компьютером. Обращаемся на локальном компьютере к классу win32_computersystem. Присваиваем свойству CurrentTimeZone значение 207, соответствующее “North Asia Standard Time”. И методом Put сохраняем изменение часового пояса.
Также сохранить и передать скрипт на удаленный компьютер с помощью Invoke-Command. По-моему, использовать tzutil проще.
Значения часовых поясов можно взять отсюда или из вывода tzutil /l
Ну и без PowerShell все-таки не обошлось.
Включение удаленного рабочего стола
В PowerShell 3.0 появилось множество командлетов, для работы с RDS. Их группа так и называется Remote Desktop Cmdlets. Но, как я понял, они рассчитаны на работу с RDS-сервером, просто включить удаленный рабочий стол для администратора с их помощью нельзя.
Остается два способа включения рабочего стола. Через WMI-вызовы и неправильный через модификацию реестра. Модификация реестра мне никогда не нравилась. Одно неловкое движение пальца и никто не гарантирует, что сервер поднимется после перезагрузки.
Что касается включения удаленного рабочего стола, то модификация ключа HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\fDenyTSConnections, которому нужно присвоить значение 0, чтобы разрешить удаленный рабочий стол: во-первых, требует перезагрузки, во-вторых, не добавляет исключение для удаленного рабочего стола в правила брандмауэра.
Поэтому я буду использовать WMI-класс win32_terminalservicesetting и его метод setallowtsconnections, что позволит обойтись без перезагрузки и добавить правила исключения в брандмауэре одной командой.
Invoke-Command 192.168.0.5 {(gwmi win32_terminalservicesetting -namespace root\cimv2\terminalservices).setallowtsconnections(1,1)} –Credential Администратор
Теперь у нас есть доступ к таёжному серверу по RDP! Можно радоваться? Представим, что единственный канал связи с внешним миром у удаленного сервера через спутник с грабительскими тарифами, диалапной скоростью, зашкаливающим пингом и продолжим настраивать сервер удаленно через PowerShell.
Переименование сервера и присоединение его к домену
Тем более, что осталось совсем немного.
По идее, командлет Add-Computer позволяет переименовать компьютер при присоединении его к домену. Но на практике, я сталкивался с тем, что при присоединении к домену и одновременным переименованием с помощью этой команды, компьютер входит в домен под своим старым именем. И понеслась – вывести компьютер из домена, перезагрузиться, удалить учетку в AD, запустить репликацию если контроллеров несколько, подождать, переименовать компьютер, перезагрузиться, ввести в домен, перезагрузиться.
Поэтому я предпочитаю операции переименования компьютера и ввода в домен выполнять отдельно.
Переименование
Invoke-Command 192.168.0.5 {rename-computer taiga -restart} -credential Администратор
Как только нам вернули управление, значит удаленный сервер перезагружается. Проверить результат команды (и готовность сервера) можно так:
Invoke-Command 192.168.0.5 {$env:computername} -credential Администратор
И наконец-то ввод в домен
Invoke-Сommand 192.168.0.5 {add-computer contoso.com -credential contoso.com\domainadmin -restart} -credential Администратор
Заканчиваем
Все поставленные в начале задачи выполнены. Теперь уже можно думать, как дальше жить и где искать этот чертов ключ от шкафа.
И напоследок небольшая шпаргалка по CMD и PowerShell.
| CMD | PowerShell | |
| Изменить сетевые настройки |
|
|
| Изменить часовой пояс |
|
|
| Включить удаленный рабочий стол |
|
|
| Переименовать сервер |
|
|
| Присоединить к домену |
|
|
Объединяет их одно: им всем для удаленной работы нужен RPC, по умолчанию закрытый брандмауэром. Поэтому единственным способом доставить их на удаленный компьютер, является WinRM.
А Enter-Pssession у меня не заработал :)
Использован материал из:
MSDN
Technet
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends: 'You Say What You Like, Because They Like What You Say' - http://www.medialens.org/index.php/alerts/alert-archive/alerts-2013/731-you-say-what-you-like-because-they-like-what-you-say.html
Комментариев нет:
Отправить комментарий