Поиск по сайту:

Как использовать PowerShell для настройки IIS на нескольких серверах


PowerShell — отличный инструмент для управления всем, что связано с Windows. Тем не менее, он также может сделать немало работы для вас при настройке информационных служб Интернета (IIS) и становится еще лучше, когда вы можете использовать его для массовой настройки серверов IIS.

По мере того, как вы приобретаете все больше и больше опыта в области системного проектирования/администрирования, вы склонны спрашивать себя: «Может ли PowerShell упростить мне эту задачу?» Это почти всегда начинается с обучения, которое только помогает вам лучше понять PowerShell. Рассматривая задачу настройки различных компонентов IIS для нескольких серверов, шаги можно разбить на логические шаги, которые в основном являются шагами, которые вы должны выполнить в графическом интерфейсе на одном сервере Windows. Давайте поработаем с кратким списком шагов, которые помогут вам начать работу и которые при желании можно добавить для дальнейших конфигураций:

  • Импорт сертификата PFX из удаленного общего ресурса
  • Создайте новую привязку для https в IIS.
  • Прикрепите импортированный сертификат к привязке https
  • Установите флажок Требовать SSL в диспетчере IIS.
  • Добавить пользовательское ведение журнала для получения значения X-Forwarded-For из балансировщика нагрузки.

Большинство этих шагов представляют собой простые щелчки в графическом интерфейсе, так почему же все это нельзя было сделать с помощью нескольких команд PowerShell? А еще лучше запустить список нескольких удаленных серверов, чтобы выполнить ту же задачу? Большая часть шагов, которые будут продемонстрированы в этом посте, представляют собой фрагменты кода, которые вы можете вставить в свою типичную структуру PowerShell. У вас может быть настраиваемое ведение журнала и элементы, уникальные для того, как вы отлаживаете сценарии PowerShell. Если нет, вы можете легко скомпоновать их вместе для быстрого выполнения того, что вам нужно сделать для ваших конфигураций IIS.

Несколько вещей, которые нужно настроить спереди

Для начала необходимо несколько переменных. Рабочий список серверов для настройки и доступный сетевой ресурс, где находится файл сертификата PFX:

$Servers = Get-Content -Path C:WebServers.txt
$CertFolder = '\FileServer01SharedCerts'

Это возьмет список серверов из TXT-файла и установит место, где будет найден сертификат для импорта.

Если вы будете запускать это на нескольких серверах, вы в конечном итоге захотите убедиться, что вы работаете на серверах, которые находятся в сети. Следующее использование командлета Test-Connection для проверки связи с каждым сервером хотя бы один раз, чтобы убедиться, что он активен, прежде чем двигаться дальше. Если сервер подключен к сети, логика скопирует папку из общего сетевого ресурса, содержащего сертификат, в папку C:WindowsTemp удаленного сервера. Таким образом, командлет Invoke-Command для импорта сертификата не столкнется с проблемами разрешений при копировании из сетевого расположения:

foreach ($Server in $Servers) {
     if (Test-Connection -ComputerName $Server -Quiet -Count 1) {
          Copy-Item -Path $CertFolder `
          -Destination \\$Server\C$\Windows\Temp\CertAssets `
          -Recurse -Force
          Write-Host "Assets successfully copied!"
     }
     else {
          Write-Host "$Server appears to be offline!"
     }
...code demonstrated below...
}

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

Импортируйте сертификат и создайте новую привязку

Это действие выполняется с помощью командлета Invoke-Command, который выполняет это действие локально на каждом сервере. В зависимости от уровня безопасности, который вы хотите внедрить, вы можете сделать несколько вещей с паролем, который необходим для импорта сертификата PFX. Вы можете сохранить его на лету, используя Get-Credential, или вы можете просто ввести пароль в виде обычного текста, встроенного в команду, используемую для импорта. Я бы предложил как минимум защитить пароль с помощью Get-Credential, хотя здесь есть множество других способов безопасно ввести пароль. Чтобы собрать пароль, вы можете использовать:

$MyPwd = Get-Credential -UserName 'Enter password below' -Message 'Enter password below'

Это сохранит пароль сертификата без необходимости иметь пароль в виде обычного текста внутри вашего скрипта. Мы передадим эту локальную переменную в удаленную команду, используя компонент $Using:. Поскольку Invoke-Command и сопровождающий его блок сценария выполняются в другой области (локальной по отношению к удаленному компьютеру), он ничего не знает о каких-либо локальных переменных, определенных за пределами блока сценария. Это позволяет вам передавать любые локальные переменные в удаленный сеанс и использовать их соответствующим образом.

Мы будем импортировать сертификат в личное (Мое) хранилище сертификатов учетной записи компьютера.

Следующий код выполняет эти шаги:

  1. Запуск процесса на удаленном сервере
  2. Действие импорта с использованием предоставленного пароля на этапе Get-Credential
  3. Создайте привязку https к порту 443.
  4. Добавление импортированного сертификата в привязку https

*Это по-прежнему относится к циклу foreach, определенному выше:


Invoke-Command -ComputerName $Server -ScriptBlock {
     $SiteName = "My Web Site"
     Import-PfxCertificate -Password $Using:MyPwd.Password `
          -CertStoreLocation Cert:\LocalMachine\My `
          -FilePath C:\Windows\Temp\CertAssets\MyCert.pfx
     Import-Module WebAdministration
     New-WebBinding -Name $SiteName -IP "*" -Port 443 -Protocol https
     $SSLCert = Get-ChildItem -Path Cert:\LocalMachine\My `
          | Where-Object {$_.Subject.Contains("CertFriendlyName")}
     $Binding = Get-WebBinding -Name $SiteName -Protocol "https"
     $Binding.AddSslCertificate($SSLCert.GetCertHashString(), "My")
     Write-Host "Setup successful on: $env:COMPUTERNAME"
}

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

Также полезно навести порядок в своем беспорядке, поэтому добавьте несколько строк, чтобы удалить папку с файлом .pfx, который был скопирован на машину. Это будет находиться внутри цикла foreach, предпочтительно ближе к концу:

Remove-Item -Path "\\$Server\C$\Windows\temp\CertAssets" -Recurse -Force
Write-Host "Cleanup on $Server completed!"

Требовать SSL на вашем сайте

Этот следующий фрагмент команд будет использоваться при развертывании развертывания. Если вы хотите, чтобы это требовалось сразу, просто добавьте его к остальной части кода выше, и все готово. У вас может быть поэтапное развертывание, в котором вы можете захотеть включить это на определенных серверах. В любом случае, вы создадите это, суть работы будет заключаться в этих нескольких строках:

Import-Module WebAdministration
Set-WebConfiguration -Location "My Web Site" `
     -Filter 'system.webserver/security/access' -Value "Ssl"

Обратите внимание, что параметр -Location — это имя сайта IIS, для которого требуется SSL. Теперь это приведет к принудительному подключению всех безопасных соединений к вашей новой привязке с соответствующим сертификатом. В графическом интерфейсе это эквивалентно щелчку по значку настроек SSL в диспетчере IIS для вашего конкретного сайта и установке флажка Требовать SSL:

Настройка параметров ведения журнала IIS

Если вы управляете парком серверов IIS, которые находятся за балансировщиком нагрузки, вы можете воспользоваться информацией, которую балансировщик нагрузки собирает из входящих подключений. Предполагая, что ваш конкретный балансировщик нагрузки настроен на захват значения X-Forwarded-For , вы можете получить входящие IP-адреса всех входящих подключений к вашим серверам IIS и просмотреть их в хорошо известном IIS журналы. Это особенно полезно, когда речь идет об устранении неполадок, когда вам необходимо отслеживать соединения с определенными ресурсами, которые могли столкнуться с ошибками на конкретном сервере.

Таким образом, IIS не собирает значение X-Forwarded-For. Его необходимо настроить как пользовательское значение, чтобы IIS мог его захватить и зарегистрировать. Существует также способ настроить это в графическом интерфейсе, но вы можете добавить эту команду в наш текущий сценарий подготовки, чтобы он был на месте с самого начала:

Add-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
     -Filter "system.applicationHost/sites/siteDefaults/logFile/customFields" `
     -Name "." `
     -Value @{logFieldName='X-Forwarded-For';sourceName='X-Forwarded-For';sourceType='RequestHeader'}

После завершения вы можете убедиться, что это настраиваемое поле было добавлено в IIS на уровень сервера, открыв Диспетчер IIS и нажав Мой сервер > Ведение журнала > Файл журнала: выберите поля…

Как только это будет сделано, вы сможете видеть IP-адреса для входящих подключений к вашим серверам IIS в традиционных журналах IIS.

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