Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
2.6.4
* Fixed an issue with SSL Flags greater than 3 were not being applied correctly to newer IIS servers.
2.6.3
* Fixed re-enrollment or ODKG job when RDN Components contained escaped commas.
* Updated renewal job for IIS Certs to delete the old cert if not bound or used by other web sites.
Expand Down
106 changes: 76 additions & 30 deletions IISU/PowerShellScripts/WinCertScripts.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# 08/29/25 Fixed the add cert to store function to return the correct thumbprint
# Made changes to the IIS Binding logic, breaking it into manageable pieces to aid in debugging issues
# 09/16/25 Updated the Get CSP function to handle null values when reading hybrid certificates
# 11/17/25 Fixed issue with SSL Flags not being applied correctly to IIS bindings (2.6.4)

# Set preferences globally at the script level
$DebugPreference = "Continue"
Expand Down Expand Up @@ -388,74 +389,110 @@ function New-KFIISSiteBinding {
param (
[Parameter(Mandatory = $true)]
[string]$SiteName,

[string]$IPAddress = "*",

[int]$Port = 443,

[AllowEmptyString()]
[string]$Hostname = "",

[ValidateSet("http", "https")]
[string]$Protocol = "https",

[ValidateScript({
if ($Protocol -eq 'https' -and [string]::IsNullOrEmpty($_)) {
throw "Thumbprint is required when Protocol is 'https'"
}
$true
})]
[string]$Thumbprint,

[string]$StoreName = "My",

[int]$SslFlags = 0
)

Write-Information "Entering PowerShell Script: New-KFIISSiteBinding" -InformationAction SilentlyContinue
Write-Verbose "Function: New-KFIISSiteBinding"
Write-Verbose "Parameters: $(($PSBoundParameters.GetEnumerator() | ForEach-Object { "$($_.Key): '$($_.Value)'" }) -join ', ')"

try {
# This function mimics IIS Manager behavior:
# - Replaces exact binding matches (same IP:Port:Hostname)
# - Allows multiple bindings with different hostnames (SNI)
# - Lets IIS handle true conflicts rather than pre-checking

# Step 1: Verify site exists and get management approach
# Step 1: Perform verifications and get management info
# Check SslFlags
if (-not (Test-ValidSslFlags -SslFlags $SslFlags)) {
return New-ResultObject -Status Error 400 -Step "Validation" -ErrorMessage "Invalid SSL Flag bit configuration ($SslFlags)"
}

$managementInfo = Get-IISManagementInfo -SiteName $SiteName
if (-not $managementInfo.Success) {
return $managementInfo.Result
}

# Step 2: Remove existing HTTPS bindings for this exact binding information
# This mimics IIS behavior: replace exact matches, allow different hostnames
# Step 2: Remove existing HTTPS bindings for this binding info
$searchBindings = "${IPAddress}:${Port}:${Hostname}"
Write-Verbose "Removing existing HTTPS bindings for: $searchBindings"

$removalResult = Remove-ExistingIISBinding -SiteName $SiteName -BindingInfo $searchBindings -UseIISDrive $managementInfo.UseIISDrive
if ($removalResult.Status -eq 'Error') {
return $removalResult
}

# Step 3: Add new binding with SSL certificate
Write-Verbose "Adding new binding with SSL certificate"

# Step 3: Determine SslFlags supported by Microsoft.Web.Administration
if ($SslFlags -gt 3) {
Write-Verbose "SslFlags value $SslFlags exceeds managed API range (0–3). Applying reduced flags for creation."
$SslFlagsApplied = ($SslFlags -band 3)
} else {
$SslFlagsApplied = $SslFlags
}

# Step 4: Add the new binding with the reduced flag set
Write-Verbose "Adding new binding with SSL certificate (SslFlagsApplied=$SslFlagsApplied)"

$addParams = @{
SiteName = $SiteName
Protocol = $Protocol
IPAddress = $IPAddress
Port = $Port
Hostname = $Hostname
Thumbprint = $Thumbprint
StoreName = $StoreName
SslFlags = $SslFlags
SiteName = $SiteName
Protocol = $Protocol
IPAddress = $IPAddress
Port = $Port
Hostname = $Hostname
Thumbprint = $Thumbprint
StoreName = $StoreName
SslFlags = $SslFlagsApplied
UseIISDrive = $managementInfo.UseIISDrive
}

$addResult = Add-IISBindingWithSSL @addParams
return $addResult

if ($addResult.Status -eq 'Error') {
return $addResult
}

# Step 5: If extended flags, update via appcmd.exe
if ($SslFlags -gt 3) {
Write-Verbose "Applying full SslFlags=$SslFlags via appcmd"

$appcmd = Join-Path $env:windir "System32\inetsrv\appcmd.exe"

# Escape any single quotes in hostname
$safeHostname = $Hostname -replace "'", "''"
$bindingInfo = "${IPAddress}:${Port}:${safeHostname}"

# Quote site name only if it contains spaces
if ($SiteName -match '\s') {
$siteArg = "/site.name:`"$SiteName`""
} else {
$siteArg = "/site.name:$SiteName"
}

# Build binding argument for appcmd
$bindingArg = "/bindings.[protocol='https',bindingInformation='$bindingInfo'].sslFlags:$SslFlags"

Write-Verbose "Running appcmd: $appcmd $siteArg $bindingArg"
$appcmdOutput = & $appcmd set site $siteArg $bindingArg 2>&1
Write-Verbose "appcmd output: $appcmdOutput"

#& $appcmd set site $siteArg $bindingArg | Out-Null

if ($LASTEXITCODE -ne 0) {
Write-Warning "appcmd failed to set extended SslFlags ($SslFlags) for binding $bindingInfo."
} else {
Write-Verbose "Successfully updated SslFlags to $SslFlags via appcmd."
}
}

return $addResult
}
catch {
$errorMessage = "Unexpected error in New-KFIISSiteBinding: $($_.Exception.Message)"
Expand Down Expand Up @@ -1464,6 +1501,15 @@ function Parse-DNSubject {
return $subjectString
}

function Test-ValidSslFlags {
param([int]$SslFlags)

$validBits = 1,2,4,8,32,64,128
$invalidBits = $SslFlags -bxor ($SslFlags -band ($validBits | Measure-Object -Sum).Sum)

return ($invalidBits -eq 0)
}

# Note: Removed Test-IISBindingConflict function - we now mimic IIS behavior
# IIS replaces exact matches and allows multiple hostnames (SNI) on same IP:Port
function Get-IISManagementInfo {
Expand Down
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,18 @@ the Keyfactor Command Portal

![WinCert Entry Parameters Tab](docsource/images/WinCert-entry-parameters-store-type-dialog.png)


##### ProviderName

![WinCert Entry Parameter - ProviderName](docsource/images/WinCert-entry-parameters-store-type-dialog-ProviderName.png)


##### SAN

![WinCert Entry Parameter - SAN](docsource/images/WinCert-entry-parameters-store-type-dialog-SAN.png)



</details>
</details>

Expand Down Expand Up @@ -426,6 +438,48 @@ the Keyfactor Command Portal

![IISU Entry Parameters Tab](docsource/images/IISU-entry-parameters-store-type-dialog.png)


##### Port

![IISU Entry Parameter - Port](docsource/images/IISU-entry-parameters-store-type-dialog-Port.png)


##### IPAddress

![IISU Entry Parameter - IPAddress](docsource/images/IISU-entry-parameters-store-type-dialog-IPAddress.png)


##### HostName

![IISU Entry Parameter - HostName](docsource/images/IISU-entry-parameters-store-type-dialog-HostName.png)


##### SiteName

![IISU Entry Parameter - SiteName](docsource/images/IISU-entry-parameters-store-type-dialog-SiteName.png)


##### SniFlag

![IISU Entry Parameter - SniFlag](docsource/images/IISU-entry-parameters-store-type-dialog-SniFlag.png)


##### Protocol

![IISU Entry Parameter - Protocol](docsource/images/IISU-entry-parameters-store-type-dialog-Protocol.png)


##### ProviderName

![IISU Entry Parameter - ProviderName](docsource/images/IISU-entry-parameters-store-type-dialog-ProviderName.png)


##### SAN

![IISU Entry Parameter - SAN](docsource/images/IISU-entry-parameters-store-type-dialog-SAN.png)



</details>
</details>

Expand Down Expand Up @@ -549,6 +603,23 @@ the Keyfactor Command Portal

![WinSql Entry Parameters Tab](docsource/images/WinSql-entry-parameters-store-type-dialog.png)


##### InstanceName

![WinSql Entry Parameter - InstanceName](docsource/images/WinSql-entry-parameters-store-type-dialog-InstanceName.png)


##### ProviderName

![WinSql Entry Parameter - ProviderName](docsource/images/WinSql-entry-parameters-store-type-dialog-ProviderName.png)


##### SAN

![WinSql Entry Parameter - SAN](docsource/images/WinSql-entry-parameters-store-type-dialog-SAN.png)



</details>
</details>

Expand Down
Binary file modified docsource/images/IISU-advanced-store-type-dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docsource/images/IISU-basic-store-type-dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docsource/images/WinCert-advanced-store-type-dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docsource/images/WinCert-entry-parameters-store-type-dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docsource/images/WinSql-advanced-store-type-dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docsource/images/WinSql-basic-store-type-dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.