Iis

在多個 Windows Server 2016+ 端點上批量安裝新證書

  • May 27, 2021

多年來,我一直不情願地手動更新我們購買的萬用字元證書,現在我已經受夠了,因為我擁有 100 多個 Web 和客戶端伺服器。這些伺服器大多是獨立的,分佈在幾個不同的域中,但是有幾個正在執行的伺服器場,這可能至少對那些少數人來說更容易。

所有作業系統都是 Windows Server 2016 和 2019。

我在每個證書有效期結束時的目前流程是從我的內部管理框中購買新(更新)證書並完成 CSR,然後以 .pfx 格式導出證書,並在每個伺服器上手動安裝它個人店鋪。在 Web 伺服器 ( IIS ) 上,我也手動修改綁定。

我知道如果我使用域中生成的證書,我可以簡單地在每個域中使用 AD CA 將它們推出,但根據我的研究,我找不到推出我們從供應商處購買的證書的方法。

我還看到 GPO 至少可能是在伺服器上獲取證書的答案 - 設置項目級目標或將所有 Web 伺服器放在一個組或 OU 中對我來說並不難領域。我遇到的唯一問題是我找不到使用此方法將證書放置在Personal store中的方法,這是一項要求。

這裡可能有超過 1 個“正確”答案,但我想知道你們每年如何處理這個過程,所以請隨時加入。抱歉,如果這個社區之前已經回答過這個問題,但我的搜尋沒有結果。

你好伙計們,伙計們,

似乎我在這裡用“ol PowerShell”爭論了另一個。感謝@Massimo 讓我朝著正確的方向前進。

到目前為止,下面的 PS 腳本對我來說非常有效。我在腳本中留下了評論,所以即使是最新手的牛仔/女牛仔也應該很清楚。

注意事項:

  1. 這是作為域管理員從管理機器執行的,該管理機器的子網對所有其他網段具有 VLAN 訪問權限。(我知道這聽起來像是一場安全噩夢,但它需要經過全面審核和訪問日誌記錄,並且在不使用時保持離線狀態。)
  2. 這僅在 Windows Server 2016 和 2019 上進行了測試——如果它適用於 2016 年以下的任何版本,將會感到驚訝。
  3. Windows Server 2016 預設為 IISAdmin 模組 1.0,但此腳本需要 1.1.0.0,因此我從遠端儲存庫內置了下載/安裝。隨意刪除以供您自己使用,或自行決定使用它。
  4. 我選擇將 .pfx 文件複製到每台機器上,而不是從網路共享中安裝它,因為它簡化了過程(身份驗證、循環、冗餘、等等)。不過,在腳本結束時, .pfx 會被刪除。如果您的文件有一個複雜的密碼,這應該沒問題,但請自行決定。
  5. 此解決方案為 IIS 應用新證書和綁定,並為本地 SMTP 啟用 TLS。
#Setup the vars below.  Yes, you gotta do some of the work...
$OldCertDirHash = 'Cert:\LocalMachine\My\1234567890QWERTYUIOPLKJHGFDSA' # Old/Expired cert's store path and hash ID
$NewCertHash = '0987654321POIUYTREWQASDFGHJKL' 
$NewCertSharePath = '\\FS01.foo.internal\ITStuff\SCENSATIVE\install\STAR.foo.com_2022.pfx' # PFX file's shared location on the network
$CertPass = Get-Credential -UserName 'Type PFX password below' -Message 'Enter password below' #Stores PXF's password obscurely
$IISSiteName = 'Default Web Site' #Website's name for new binding
$ADCPUs = Get-ADComputer -Filter * -SearchBase "OU=Testing Lab,OU=Web Servers,DC=Foo,DC=com" |  select-object -expandproperty name  #Target machines in AD using an OU's Distinguished Name
$NetworkPFXPath = 'C$\Temp\Certs' #Network path for each remote machine
$LocalPXFPath = 'C:\temp\Certs\STAR.foo.com_2022.pfx'  #Path were the .pxf file will be accessed locally on each machine


ForEach ($ADCPU in $ADCPUs)
{Write-Host Copying file $NewCertSharePath to $ADCPU $NetworkPFXPath -ForegroundColor Yellow
New-Item -Path \\$ADCPU\$NetworkPFXPath -ItemType Directory #Creates local folder on each remote machine
Copy-Item -Path $NewCertSharePath -Destination \\$ADCPU\$NetworkPFXPath # Copies pfx file from network to each remote machine's local folder
}


# ~~~ End of Setup. Magic happens below ~~~


ForEach  ($ADCPU in $ADCPUs)
 {
Write-Host $ADCPU -ForegroundColor Yellow # Highlights Server names while in process
Invoke-Command -ComputerName $ADCPU -ScriptBlock { 

#Get latest IISAdmin version from online repo with suppressed dialog
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Install-Module -Name IISAdministration -RequiredVersion 1.1.0.0 -SkipPublisherCheck -Confirm:$False -Force

#The default IISAdmin version for server 2016 is 1.0 - below brings it up to the required version which was installed above.       
Import-Module IISAdministration -Version 1.1.0.0

#This line installs the cert from the .pfx using the password set earlier into the Computer's Personal cert store.
Import-PfxCertificate -FilePath $Using:LocalPXFPath -CertStoreLocation Cert:\LocalMachine\My -Password $Using:CertPass.Password -ErrorAction Inquire

#Use below if importing .crt rather than .pfx ~ Not in use here ~
       #Import-Certificate -FilePath "UNCPath" -CertStoreLocation Cert:\LocalMachine\My -ErrorAction Inquire

#Clear out any other active or pending IIS Server Manager tasks - prevents config file collision.        
Reset-IISServerManager -Confirm:$false

#Remove current HTTPS binding using old/expired cert
Remove-IISSiteBinding -Name 'Default Web Site' -BindingInformation '*:443:' -Protocol https -Confirm:$false

#Delete expired cert - not required but is good houskeeping
Get-ChildItem $Using:OldCertDirHash | Remove-Item -ErrorAction Ignore

#Delete Cert by subject,serialnumber,issuer,etc... ~ Not in use here. ~
#Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.FriendlyName -match '*.foo.com_2021' } | Remove-Item

#Setup https binding on 443 using new cert
New-IISSiteBinding -Name $Using:IISSiteName -BindingInformation "*:443:" -CertificateThumbPrint $Using:NewCertHash -CertStoreLocation "Cert:\LocalMachine\My" -Protocol https 

IISRESET #for obvious reasons...

Remove-Item -Path $Using:LocalPXFPath -Recurse -Verbose  #Cleanup the dir created to store the pfx file

Write-Host $ADCPU Done -ForegroundColor Green #This is more of a marker for reviewing output and would be helpful if writing to log/oputfile
   }
   
 }

很抱歉,這篇文章很長,但這是對我的問題的強大而徹底的解決方案。下班後我多喝了幾杯,以擊敗這杯。如果這對你有用,請隨時給我送一杯飲料!

PowerShell 是您的朋友。

https://docs.microsoft.com/en-us/powershell/module/pki/import-pfxcertificate

https://docs.microsoft.com/en-us/powershell/module/iisadministration/remove-iissitebinding

https://docs.microsoft.com/en-us/powershell/module/iisadministration/new-iissitebinding

\\server\share\filename.pfx如果您具有所需的權限,您可以直接從網路路徑 ( ) 拉取 PFX 文件;如果您需要指定憑據,請使用New-PSDrive

您可以將所有內容放在一個腳本塊中,並使用Invoke-Command在遠端伺服器上執行它;如果需要,您也可以在此處指定憑據。

這當然可以在伺服器列表上的循環中完成,例如

$serverlist = "server1","server2","server3"

foreach ($server in $serverlist)
{
   Invoke-Command -ComputerName $server -ScriptBlock
   {
       Import-PfxCertificate [...]
       Remove-IISSiteBinding [...]
       New-IISSiteBinding [...]
   }
}

如果您需要創建PSCredential對象,請查看此處

最後但同樣重要的是,您可以使用Import-Csv從 CSV 文件中獲取所需的所有內容(例如伺服器名稱、憑據、網站名稱等)。

引用自:https://serverfault.com/questions/1064566