Update-IISCertificate.psm1
#Requires -Modules Microsoft.PowerShell.Core #Requires -Modules Microsoft.PowerShell.Utility #Requires -Modules Microsoft.PowerShell.Management Function Get-File { [CmdletBinding()] param ( [string]$InitialDirectory, [string]$Filter ) [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog if ($InitialDirectory) { $OpenFileDialog.InitialDirectory = $InitialDirectory } if ($Filter) { $OpenFileDialog.Filter = "$Filter (*.$Filter)|*.$Filter" } else { $OpenFileDialog.Filter = 'All Files (*.*)|*.*' } [void]$OpenFileDialog.ShowDialog() return $OpenFileDialog.FileName } Function Update-IISCertificate { <# .SYNOPSIS This function allows you to update IIS certificates across multiple servers .DESCRIPTION This commandlet will allow you to update the SSL certificate and IIS binding on an array of servers that you give it. Currently you have to provide a pfx file and password to use this command. In the future it might support auto generation of pfx files .PARAMETER FQDN Specify the FQDN also known as Common Name (CN) of the SSL certificate .PARAMETER Servers Put the name(s) of the server(s) you want to update. This can be a comma separated list for multiple servers .INPUTS There are no inputs for this function .OUTPUTS There are no outputs for this function .EXAMPLE Update-IISCertificate -FQDN *.domain.com -servers server Updates IIS sites that are using the *.domain.com certificate common name .EXAMPLE Update-IISCertificate -FQDN *.domain.com -servers server,server2,server3 Updates IIS sites that are using the *.domain.com certificate common name for server, server2, and server3 .NOTES Author: Joe Fabrie Last Edit: 2023-11-08 Version 1.0 - Initial version #> [CmdletBinding(SupportShouldProcess)] param ( [Parameter(Mandatory=$true, HelpMessage="FQDN of cert")] [string]$FQDN, [Parameter(ParameterSetName='Server list', HelpMessage="Use one server name")] [string[]]$servers, [Parameter(ParameterSetName='CSV server list', DontShow, HelpMessage="You will be prompted to select csv file")] [switch]$CSVservers ) #Prompt for PFX password $password = Read-Host -AsSecureString -Prompt "Enter PFX Password" #Prompts you to select the pfx file $certname = Get-File -Filter pfx # Convert plain text password to a secure string #$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force #If using CSV parameter import values if($CSVservers) { $servers = Import-Csv -Path (Get-File -Filter csv) $servers } #Get just the file name from $certname parameter $cert = Split-Path $Certname -Leaf #Copy PFX to all servers $servers | foreach-Object { try { copy-item -Path $certname -Destination "\\$_\c`$" } catch { "$_"} } #Establish a connection to all of those servers: try {$session = New-PsSession -ComputerName $servers} catch{"$_"} #Import certificate script block that is ran with Invoke-Command at end of script $importCertificatesCommand = ({ $newCert = Import-PfxCertificate ` -FilePath "c:\$($using:cert)" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -password $using:Password Import-Module Webadministration $sites = Get-ChildItem -Path IIS:\Sites foreach ($site in $sites) { foreach ($binding in $site.Bindings.Collection) { if ($binding.protocol -eq 'https') { $search = "Cert:\LocalMachine\My\$($binding.certificateHash)" $certs = Get-ChildItem -path $search -Recurse $hostname = hostname if (($certs.count -gt 0) -and ($certs[0].Subject.StartsWith($FQDN))) { Write-Output "Updating $hostname, site: `"$($site.name)`", binding: `"$($binding.bindingInformation)`", current cert: `"$($certs[0].Subject)`", Expiry Date: `"$($certs[0].NotAfter)`"" $binding.AddSslCertificate($newCert.Thumbprint, "my") } } } } }) Invoke-Command -session $session -scriptblock $importCertificatesCommand Invoke-Command -Session $session { remove-item -path "c:\$($using:cert)" } Get-PSSession | Remove-PSSession } # SIG # Begin signature block # MIIFlAYJKoZIhvcNAQcCoIIFhTCCBYECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU7HkOMxYSuItsWwoDvkCiqw8V # 0DWgggMiMIIDHjCCAgagAwIBAgIQSP7nVWZu9YlCukDlDLd7hTANBgkqhkiG9w0B # AQsFADAnMSUwIwYDVQQDDBxQb3dlclNoZWxsIENvZGUgU2lnbmluZyBDZXJ0MB4X # DTIzMTEwOTAwMzgxMVoXDTI0MTEwOTAwNTgxMVowJzElMCMGA1UEAwwcUG93ZXJT # aGVsbCBDb2RlIFNpZ25pbmcgQ2VydDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC # AQoCggEBAKbO2oq0Vf8M89wBOE8Vz6E7RCAl48H+0s0Q9E6szrMKIpVRTyHJymC/ # Bq6RBuus21jdU3mhuok/VRsbgcUk3tpW8Gk2qCFqxAmkJT17siBsLC+jMDTEw7mR # OVJoQT+AQGXAyPaqUKh5GJrVrnPTmI1gM9EMEe7vxi4JBdUgLT2HLH4iUYzB/I4q # rkRpceabHUEHVm+FZjTozyLZhDnSlwAJT38dep2xvQvP9vAKa5r73wOzbTIJjoBZ # ss4HJraGfXj1LaN1Aaek/u0T35BblcOOaKcTlu1GmiXom+6dzv26WnDHdXEQZtNx # FMXzZbmzciYKRYHsLPtNz2dnhAvrrW0CAwEAAaNGMEQwDgYDVR0PAQH/BAQDAgeA # MBMGA1UdJQQMMAoGCCsGAQUFBwMDMB0GA1UdDgQWBBQAgkx8jeIWNP5m30GGZc22 # 2nAchzANBgkqhkiG9w0BAQsFAAOCAQEAEpsP4ZKLcp83TmFq0QBKOPa0PeWX88xj # vwiwkKg6KlCgMCn1ofrzDOSGKdtnhJaueBqN4OCPHXGuxPctvyKznn2lAW0KNRyt # lizaQgvC0+MHrdpvLkPmjYtRX07pbEpovF2q/XXPbzKYiOQDT8mAcTjJ2+oQSrMR # uGJpp3dTu1jcHCKissJSQR1yuS8gutfUSd+LglhFEgX8ZrSIU7wEXh+5P/bzKrvw # VE5BTN1FjkNuhgUiEnFEdkcWJ7iJYQITR5DegQctsINwfs2z81DzsD3zypHXHP82 # dhGEXietJuMHcGx9zyBBSbX4gpir6Uzz1rejKWTK4hZN8f/sd4JkTzGCAdwwggHY # AgEBMDswJzElMCMGA1UEAwwcUG93ZXJTaGVsbCBDb2RlIFNpZ25pbmcgQ2VydAIQ # SP7nVWZu9YlCukDlDLd7hTAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAig # AoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgEL # MQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUSADB9OssQM0NfW+aAMdY # SuH63mIwDQYJKoZIhvcNAQEBBQAEggEALYeMqWsgFcMer8WmkRc1IrJhlEPllQ5P # a849FC0/t3ccfL2UA5DeB8WLswnfD+XflKJfRf6s3CXyX/fz1WyS2/7W65+azALR # 9SF63oYY+PZLOY1VddnpgFbz+rFqeKbwgbGWbdny/iWHVqEPG38FzXfphqHZdBN0 # JqAA6v6uWEf+xvG0W1MYNEotsohjZ15yvq8J+FM7aN0ay4qswtOmCOTn8ElpNP3S # nMZVsbmujdSRXIP4IeUcMdBnk22IqEpUtJ3PIysJrdTpVfvE0BvwpbxhYfHu3cuu # guvsNLW7nieYQZ07dKhKDTIfvcsc/xIswSVqfwlNgGHsXDXAK8iHlg== # SIG # End signature block |