Pull to refresh

Простой способ не разрушить работающий Exchange/Lync шаловливыми руками

IT-companies
Sandbox
Tutorial

Как быстро сохранить настройки безопасности IIS?


Многие администраторы сталкивались с ситуацией, когда изменение пары-тройки параметров авторизации в IIS чтобы «вот сейчас точно заработало, как надо, не мучая пользователя лишними запросами авторизации» приводило к частично полностью неработающей конфигурации всей системы.
К сожалению, типовые настройки IIS для того же Exchange 2013 в официальных источниках не охватывают всех возможных конфигураций в особенности сценариев сосуществования Exchange 2010/Lync 2013/Exchange 2013/Edge TMG 2010. Задача сохранить (выписать) все рабочие настройки после очередного «тюнинга» зачастую откладывается на потом. Типовая рекомендация: "накрутили IIS — переустановите систему" — работает, но времени отнимает очень много.
Но ведь есть же PowerShell!
Разбор разработки простого, но полезного скрипта, призванного переломить ситуацию, и приведен в этой статье.

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

Поэтому сохранять настройки, «как есть» нужно не для одного а двух сайтов.
Что ж, получим сайты:
# по каждому из найденных cайтов выполним несколько простых шагов 
get-website | ForEach-Object -Process  {
# получение пути приложения в символьную переменную 
$xPath="IIS:\sites\"+$_.Name 
# переход в пространстве имен IIS $xPath 
cd $xPath 
# вывод для наглядности, куда мы попали 
$xPath
# получение коллекции веб приложений в текущем сайте 
$myWebApp=get-webApplication 
# вывод всех членов коллекции  
$myWebApp 
}


Результат работы скрипта:
Результат работы скрипта - список приложений во всех сайтах


Каталоги приложений на руках, что нам это даёт?
А вот, что: теперь мы можем для каждого их них получить способ аутентификации!
Хорошее описание, как добраться до этих параметров есть по этой ссылке.
Вот например, код, который выводит, включена ли базовая аутентификация для приложения $WebApp в сайте «Exchange Back End»:

(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/basicAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $WebApp.Path).value


Нам нужно «завернуть» этот код в итератор, чтобы не вписывать руками имя сайта и само приложение. Т.е. один итератор будет бегать по сайтам, а внутри него цикл будет обходить все приложения сайта.

Чтобы было проще, сделаем получение настроек сначала только для одного сайта, а показ результата простым выводом значений переменных:
Вариант скрипта номер 1:

get-webSite
cd IIS:\Sites\"Exchange Back End"
get-webApplication | ForEach-Object -process { 
$propPath=$_.Path
$propAA=(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/anonymousAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value 
$propBA=(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/basicAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value 
$propCA=(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/clientCertificateMappingAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value 
$propDA=(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/digestAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value 
$propIA=(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/iisClientCertificateMappingAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value 
$propWA=(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/windowsAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value 
$_.Path; $propAA ; $propBA ; $propCA ; $propDA ; $propIA ; $propWA ;
} 


Уже работает, но некрасиво и не по всем сайтам.
В powerShell есть чудесная команда форматирования вывода: Format-Table, применим её на практике:

#Текст скрипта
get-webSite
cd IIS:\Sites\"Exchange Back End"
$myWebApp=get-webApplication
$myWebApp | Format-Table -AutoSize Path , 
@{Label=  "anonim:" ; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/anonymousAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value }},
@{Label=  "Basic:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/basicAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value }},
@{Label=  "ClientCert:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/clientCertificateMappingAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value }},
@{Label=  "Digest:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/digestAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value }},
@{Label=  "IIS client Cert:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/iisClientCertificateMappingAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value }},
@{Label=  "Windows"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/windowsAuthentication   -Name Enabled -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).value }},
@{Label=  "SSL Flags"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/access    -Name * -PSPath IIS:\sites\"Exchange Back End" -location $_.Path).SSLflags }}

cd IIS:\Sites\"Default Web Site"
$myWebApp=get-webApplication
$myWebApp | Format-Table -AutoSize Path , 
@{Label=  "anonim:" ; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/anonymousAuthentication   -Name Enabled -PSPath IIS:\sites\"Default Web Site" -location $_.Path).value }},
@{Label=  "Basic:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/basicAuthentication   -Name Enabled -PSPath IIS:\sites\"Default Web Site" -location $_.Path).value }},
@{Label=  "ClientCert:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/clientCertificateMappingAuthentication   -Name Enabled -PSPath IIS:\sites\"Default Web Site" -location $_.Path).value }},
@{Label=  "Digest:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/digestAuthentication   -Name Enabled -PSPath IIS:\sites\"Default Web Site" -location $_.Path).value }},
@{Label=  "IIS client Cert:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/iisClientCertificateMappingAuthentication   -Name Enabled -PSPath IIS:\sites\"Default Web Site" -location $_.Path).value }},
@{Label=  "Windows"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/windowsAuthentication   -Name Enabled -PSPath IIS:\sites\"Default Web Site" -location $_.Path).value }},
@{Label=  "SSL Flags"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/access    -Name * -PSPath IIS:\sites\"Default Web Site" -location $_.Path).SSLflags }}
 


Здесь в качестве итератора выступает Format-Table, а ещё я добавил существенный и часто теряемый после «опытов» флаг использования SSL.

Чтобы не писать дикий повторяющийся код, вписывая имя сайта руками, добавим итератор по сайтам, как это было сделано в самом начале статьи:

Финальный вариант скрипта:


get-website | ForEach-Object -Process { 
$xSite="IIS:\sites\"+$_.Name  
cd $xSite  
$xSite 
$myWebApp=get-webApplication
$myWebApp | Format-Table -AutoSize Path , 
@{Label=  "anonim:" ; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/anonymousAuthentication   -Name Enabled -PSPath $xSite -location $_.Path).value }},
@{Label=  "Basic:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/basicAuthentication   -Name Enabled -PSPath $xSite -location $_.Path).value }},
@{Label=  "ClientCert:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/clientCertificateMappingAuthentication   -Name Enabled -PSPath $xSite -location $_.Path).value }},
@{Label=  "Digest:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/digestAuthentication   -Name Enabled -PSPath $xSite -location $_.Path).value }},
@{Label=  "IIS client Cert:"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/iisClientCertificateMappingAuthentication   -Name Enabled -PSPath $xSite -location $_.Path).value }},
@{Label=  "Windows"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/authentication/windowsAuthentication   -Name Enabled -PSPath $xSite -location $_.Path).value }},
@{Label=  "SSL Flags"; Expression = {(Get-WebConfigurationProperty -Filter /system.webServer/security/access    -Name * -PSPath $xSite -location $_.Path).SSLflags }}
} 



В этом варианте $_ внутри команды Format-Table ссылается на текущее приложение, а $_ во второй строке — на текущий сайт из итератора ForEach-Object.

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

Результат работы скрипта - таблица способов авторизации приложений

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

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

Надеюсь, что мой скромный опыт кому-нибудь сэкономит время.
Tags: MicrosoftIISExchangeLyncPowerShell#dev3
Hubs: IT-companies
Total votes 10: ↑8 and ↓2 +6
Comments 7
Comments Comments 7

Popular right now