在多个 Windows Server 2016+ 端点上批量安装新证书

Cha*_*cho 4 automation iis deployment ssl-certificate windows-server-2016

多年来,我一直不情愿地手动更新我们购买的通配符证书,现在我已经拥有 100 多个 Web 和客户端服务器,我已经受够了。服务器大多是独立的,分布在几个不同的域中,但有几个服务器场在运行,这可能至少对少数几个服务器场来说更容易。

所有操作系统都是 Windows Server 2016 和 2019。

我目前在每个证书有效期结束时的流程是购买一个新的(续订)证书并从我的内部管理箱中完成 CSR,然后以 .pfx 格式导出证书,并在每个服务器上手动安装它个人商店。在 Web 服务器 ( IIS ) 上,我也手动修改绑定。

我知道如果我使用域中生成的证书,我可以简单地在每个域中使用 AD CA 将它们推出,但根据我的研究,我找不到一种方法来推出我们从供应商处购买的证书。

我还看到 GPO 可能至少是在服务器上获取证书的答案 - 设置项目级目标对我来说并不难,或者将所有网络服务器放在一个组或 OU 中每个领域。我遇到的唯一问题是我找不到使用此方法将证书放入Personal store 的方法,这是必需的。

这里可能有不止 1 个“正确”的答案,但我想知道你们每年是如何处理这个过程的,所以请随时加入。如果这个社区之前已经回答过这个问题,我深表歉意,但我的搜索没有结果。

Mas*_*imo 5

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 [...]
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要创建PSCredential对象,请查看此处

最后但并非最不重要的一点是,您可以使用Import-Csv从 CSV 文件中获取所需的所有内容(例如服务器名称、凭据、网站名称等)。


Cha*_*cho 3

哈喽,伙计们,伙计们,

看来我又与“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
    }
    
  }
Run Code Online (Sandbox Code Playgroud)

很抱歉这篇文章很长,但这是解决我的问题的一个强大而彻底的解决方案。为了打败这个,我下班后又多喝了几杯。如果这对你有用,请随时给我一杯饮料!