
Ich habe vergeblich nach einer Lösung für diese spezielle Abfrage gesucht, kann jedoch keine mit meiner identische Situation finden.
Angenommen, ich habe in IIS 8.5 mehrere Domänen und an jede dieser Domänen ist über SNI ein SAN-SSL-Zertifikat (kein Platzhalter) gebunden:
a.domain.com
b.domain.com
c.domain.com
Wenn ich ein neues SAN hinzufügen d.domain.com
und generieren möchte, das die neue Domäne enthält, möchte ich das aktuelle Zertifikat ersetzen können, ohne das neue Zertifikat erneut an die drei oben genannten Domänen binden zu müssen (ich kann dann die neue vierte Domäne manuell binden).
Stellen Sie sich nun in meinem obigen Beispiel vor, dass ich tatsächlich 20 Domänen habe. Dies ist ziemlich zeitaufwändig, insbesondere wenn Sie alle paar Wochen eine neue Site hinzufügen. Ganz zu schweigen von der Ausfallzeit, während ich das SSL für jede Site neu binde.
Gibt es eine Lösung, mit der ich diesen Prozess automatisieren kann? Ich könnte mir vorstellen, dass ein PS-Skript dies tut, vorausgesetzt, ich habe den Hash des neuen Zertifikats, aber mein PS-Fu ist nicht stark genug, um herauszufinden, wie man alle Sites durchläuft und das Zertifikat erneut anwendet (falls dies so gemacht werden muss). Idealerweise wäre es eine Lösung, die das neue Zertifikat (.pfx) automatisch importiert, das alte entfernt und die Sites erneut bindet.
BEARBEITEN:Zur Bestätigung: Ich verwende für alle Sites eine IP-Adresse.
Antwort1
Kopieren Sie die folgenden Funktionen und fügen Sie sie in Ihr PowerShell-Fenster ein:
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.")
}
}
Führen Sie dann Folgendes aus:
- So listen Sie alle Sites und ihre Bindungen auf:
Get-IisSslBinding
- So aktualisieren Sie alle Sites und ihre SSL-Bindungen:
Get-IisSslBinding | Set-IisSslBinding -AfterThumbprint AAAAAAAAAAABBBBBBBBBBCCCCCCCCCCCCCCCCCCC
** Stellen Sie sicher, dass sich das neue SSL-Zertifikat bereits im SSL-Speicher befindet. Verwenden Sie die Get-IisSslBinding
Funktion auch als -FilterBySiteName
Parameter, damit Sie genau die Site(s) ansprechen können, die Sie möglicherweise berühren müssen.