Я тщетно искал решение этого конкретного запроса, но не могу найти ситуацию, идентичную моей.
В IIS 8.5, скажем, у меня есть несколько доменов, и у меня есть сертификат SAN SSL (не подстановочный знак), привязанный к каждому из них с использованием SNI:
a.domain.com
b.domain.com
c.domain.com
Если бы я хотел добавить d.domain.com
и сгенерировать новый SAN, который включает новый домен, я хочу иметь возможность заменить текущий сертификат без необходимости повторно связывать новый сертификат с 3 указанными выше доменами (затем я могу вручную привязать новый 4-й домен).
Теперь представьте в моем примере выше, что у меня на самом деле 20 доменов - это довольно затратно по времени, особенно если вы добавляете новый сайт каждые пару недель - не говоря уже о времени простоя, пока я повторно привязываю SSL-сайт к каждому. сайт.
Есть ли решение, которое я могу применить для автоматизации этого процесса? Я мог бы представить себе сценарий PS, выполняющий это, при условии, что у меня есть новый хэш сертификата, но мой PS-fu недостаточно силен, чтобы решить, как перебирать все сайты и повторно применять сертификат (если это то, как это нужно сделать ). В идеале это было бы решение, которое автоматически импортирует новый сертификат (.pfx), удаляет старый и повторно связывает сайты.
РЕДАКТИРОВАТЬ: Для подтверждения, я использую один IP-адрес для всех сайтов.
Скопируйте и вставьте в окно PowerShell следующие функции:
function Get-IisSslBinding{
[CmdletBinding()]
Param(
[Parameter(Position=0)] [Alias("fi","sn")]
[string]$FilterBySiteName,
[Parameter(Position=1, ValueFromPipelineByPropertyName=$true)] [Alias("co")] [ValidateNotnullOrEmpty()]
[string[]]$ComputerName=$env:ComputerName
)
Begin{
Write-Verbose ("$(Get-Date) - INFO - Load Microsoft.Web.Administration assembly...")
$null=[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
}
Process{
Foreach($computer in $ComputerName){
Try{
If($computer -eq "$env:ComputerName"){
Write-Verbose ("$(Get-Date) - INFO - Open connection to local computer [ {0} ]..." -f $computer)
$webServer=New-Object Microsoft.Web.Administration.ServerManager
$null=$webServer
}
Else{
Write-Verbose ("$(Get-Date) - INFO - Open connection to remote computer [ {0} ]..." -f $computer)
$webServer=[Microsoft.Web.Administration.ServerManager]::OpenRemote($computer)
}
# filter sites
$sites=($webServer.Sites | Where{$_.Name -match $FilterBySiteName})
Foreach($site in $sites){
Write-Verbose ("$(Get-Date) - INFO - Get binding(s) for [ {0} ]..." -f $site.Name)
# filter bindings
$siteHttpsBindings=($site.Bindings | Where{$_.Protocol -eq "https"})
Foreach($siteHttpsBinding in $siteHttpsBindings){
Write-Verbose ("$(Get-Date) - INFO - Get binding information ...")
New-Object -Type PSObject -Property @{
'ComputerName'=$computer.ToUpper()
'SiteId'=$site.ID
'SiteName'=$site.Name
'BindingInformation'=$siteHttpsBinding.GetAttributeValue("bindinginformation")
'Thumbprint'=$siteHttpsBinding.GetAttributeValue("certificateHash")
'CertificateStore'=$siteHttpsBinding.GetAttributeValue("certificateStoreName")
'Protocol'=$siteHttpsBinding.GetAttributeValue("protocol")
}
}
}
}
Catch{
Write-Verbose ("$(Get-Date) - ERROR - {0}" -f $_.Exception.GetBaseException().Message)
}
Finally{
Write-Verbose ("$(Get-Date) - INFO - Dispose web server resources...")
$webServer.Dispose()
}
}
}
End{
Write-Verbose ("$(Get-Date) - INFO - Done")
}
}
##
function Set-IisSslBinding{
[CmdletBinding()]
Param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true)] [Alias("oh")] [ValidateNotnullOrEmpty()]
[string]$Thumbprint,
[Parameter(Position=1, Mandatory=$true)] [Alias("nh")] [ValidateNotnullOrEmpty()]
[string]$AfterThumbprint,
[Parameter(Position=2, Mandatory=$false, ValueFromPipelineByPropertyName=$true)] [Alias("sn")] [ValidateNotnullOrEmpty()]
$SiteName,
[Parameter(Position=3, Mandatory=$false, ValueFromPipelineByPropertyName=$true)] [Alias("co")] [ValidateNotnullOrEmpty()]
[string[]]$ComputerName=$env:ComputerName
)
Begin{
Write-Verbose ("$(Get-Date) - INFO - Load Microsoft.Web.Administration assembly...")
$null=[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
}
Process{
Foreach($computer in $ComputerName){
Try{
If($computer -eq "$env:ComputerName"){
Write-Verbose ("$(Get-Date) - INFO - Open connection to local computer [ {0} ]..." -f $computer)
$webServer=New-Object Microsoft.Web.Administration.ServerManager
$IsCertificateInStore=((Get-ChildItem -Path CERT:\LocalMachine\My) -match $AfterThumbprint)
}
Else{
Write-Verbose ("$(Get-Date) - INFO - Open connection to remote computer [ {0} ]..." -f $computer)
$webServer=[Microsoft.Web.Administration.ServerManager]::OpenRemote($computer)
}
# If(-not $IsCertificateInStore){
# Write-Verbose ("$(Get-Date) - INFO - The computer [ {0} ] does not contain the certificate [ {1} ]... " -f $computer,$AfterThumbprint)
# Break
# }
Write-Verbose ("$(Get-Date) - INFO - Filter sites...")
$sites=($webServer.Sites|where{$_.Name -match $SiteName})
Foreach($site in $sites){
#filter bindings
$siteHttpsBindings=($site.Bindings|where{$_.Protocol -eq "https"})
Foreach($siteHttpsBinding in $siteHttpsBindings){
Switch($siteHttpsBinding.GetAttributeValue("certificateHash")){
$Thumbprint{
Write-Verbose ("$(Get-Date) - INFO - Remove old certificate [ {0} ]... " -f $siteHttpsBinding.GetAttributeValue("certificateHash"))
$BindingMethod=$siteHttpsBinding.Methods["RemoveSslCertificate"]
$BindingMethodInstance=$BindingMethod.CreateInstance()
$BindingMethodInstance.Execute()
Write-Verbose ("$(Get-Date) - INFO - Add new certificate [ {0} ]..." -f $AfterThumbprint)
$BindingMethod=$siteHttpsBinding.Methods["AddSslCertificate"]
$BindingMethodInstance=$BindingMethod.CreateInstance()
$BindingMethodInstance.Input.SetAttributeValue("certificateHash", $AfterThumbprint)
$BindingMethodInstance.Input.SetAttributeValue("certificateStoreName", "My")
$BindingMethodInstance.Execute()
New-Object -Type PSObject -Property @{
'ComputerName'=$computer.ToUpper()
'SiteId'=$site.ID
'SiteName'=$site.Name
'BindingInformation'=$siteHttpsBinding.GetAttributeValue("bindingInformation")
'Thumbprint'=$siteHttpsBinding.GetAttributeValue("certificateHash")
'PreviousThumbprint'=$Thumbprint
}
}
Default{
Write-Verbose ("$(Get-Date) - INFO - Could not get https binding(s) attribute for [ {0} ]" -f $site.Name)
break
}
}
}
}
}
Catch{
Write-Verbose ("$(Get-Date) - ERROR - {0}" -f $_.Exception.GetBaseException().Message)
}
Finally{
Write-Verbose ("$(Get-Date) - INFO - Dispose web server resources...")
$webServer.Dispose()
}
}
}
End{
Write-Verbose ("$(Get-Date) - INFO - Done.")
}
}
Затем выполните:
Get-IisSslBinding
Get-IisSslBinding | Set-IisSslBinding -AfterThumbprint AAAAAAAAAAABBBBBBBBBBCCCCCCCCCCCCCCCCCCC
** Убедитесь, что новый сертификат SSL уже находится в хранилище SSL. Так же Get-IisSslBinding
функционировать как -FilterBySiteName
param, чтобы вы могли настроить таргетинг на именно те сайты, которые вам, возможно, потребуется коснуться.