Last active
January 29, 2023 13:45
-
-
Save gillissm/d67348b8c0b04772bf41fa9c8f00a0f3 to your computer and use it in GitHub Desktop.
**Add-SecureSiteBinding** script has been created to provide the ability to add one or more domains to an IIS website each tied to a self-signed certificate providing SSL capabilities. The script contains three parts which I'll review, the full script can be found in the [Add-SecureSiteBindings Gist](GIST URL).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -RunAsAdministrator | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory = $true, | |
Position=0, | |
HelpMessage = "Name of the IIS Site the new URLs should be associated to")] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$SiteName, | |
[Parameter(Mandatory = $true, | |
Position=1, | |
HelpMessage = "Comma delimited list of all URLs to add to the site")] | |
[ValidateNotNullOrEmpty()] | |
[string[]] | |
$NewDnsNames, | |
[Parameter(Mandatory = $false, | |
Position=2, | |
HelpMessage = "Password to be used to export and import the certificate. Will be converted into a Secure String")] | |
[string] | |
$CertPassphrase = "Password12345", | |
[Parameter(Mandatory=$false, | |
Position=3, | |
HelpMessage="Port that the site bindings will be established on, defaults to 443.")] | |
[string] | |
$Port = "443" | |
) | |
<# | |
.SYNOPSIS | |
THIS IS DUPLICATED FROM THE SITECORE DOCKER TOOLS MODULE AVAILABLE FROM https://sitecore.myget.org/feed/sc-powershell/package/nuget/SitecoreDockerTools | |
Duplication was done to eliminate any | |
Adds a host entry to the system hosts file. | |
.DESCRIPTION | |
Adds a host entry with the specified Hostname and IPAddress to the system hosts file (if it does not already exist). | |
A backup of the current hosts file is taken before updating. | |
.PARAMETER Hostname | |
The hostname to use for the entry. | |
.PARAMETER IPAddress | |
The IP address to use for the entry. Default is 127.0.0.1. | |
.INPUTS | |
None. You cannot pipe objects to Add-HostsEntry. | |
.OUTPUTS | |
None. Add-HostsEntry does not generate any output. | |
.EXAMPLE | |
PS C:\> Add-HostsEntry 'my.host.name' | |
#> | |
function Add-HostsEntry | |
{ | |
Param ( | |
[Parameter(Mandatory = $true, Position = 0)] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$Hostname, | |
[string] | |
[ValidateNotNullOrEmpty()] | |
$IPAddress = "127.0.0.1", | |
[string] | |
$Path = (Join-Path -Path $env:windir -ChildPath "system32\drivers\etc\hosts") | |
) | |
if (-not (Test-Path $Path)) { | |
Write-Warning "No hosts file found, hosts have not been updated" | |
return | |
} | |
# Create backup | |
Copy-Item $Path "$Path.backup" | |
Write-Verbose "Created backup of hosts file to $Path.backup" | |
# Build regex match pattern | |
$pattern = '^' + [Regex]::Escape($IPAddress) + '\s+' + [Regex]::Escape($HostName) + '\s*$' | |
$hostsContent = @(Get-Content -Path $Path -Encoding UTF8) | |
# Check if exists | |
$existingEntries = $hostsContent -match $pattern | |
if ($existingEntries.Count -gt 0) { | |
Write-Verbose "Existing host entry found for $IPAddress with hostname '$HostName'" | |
return | |
} | |
# Add it | |
$hostsContent += "$IPAddress`t$HostName" | |
$hostsContent | Out-File -FilePath $Path -Encoding utf8 | |
Write-Verbose "Host entry for $IPAddress with hostname '$HostName' has been added" | |
} | |
<# | |
.SYNOPSIS | |
Following logic is a modification to the examples demonstrating New-IISSiteBinding command | |
at https://docs.microsoft.com/en-us/powershell/module/iisadministration/new-iissitebinding?view=windowsserver2022-ps | |
Creates Self-Signed certifacte for all DNS/hostnames provided and then adds the appropriate binding to the named IIS web application | |
.PARAMETER NewDnsNames | |
REQUIRED, Comma delimited list of all URLs to add to the site | |
.PARAMETER SiteName | |
REQUIRED, Name of the IIS Site the new URLs should be associated to | |
.PARAMETER CertPassword | |
REQUIRED, Secure string of a password/phrase to secure the export and import of the self-signed certificate | |
.PARAMETER BindingPort | |
OPTIONAL, Default is 443. Port that the site bindings will be established on. | |
.INPUTS | |
None. | |
.OUTPUTS | |
None. | |
.EXAMPLE | |
PS C:\> Set-NewSiteBinding -NewDnsNames rainflytours.com,rainflyadbenture.com -SiteName rainflysites -CertPassword PassIsSecure | |
.EXAMPLE | |
PS C:\> Set-NewSiteBinding rainflytours.com,rainflyadbenture.com rainflysites PassIsSecure | |
.EXAMPLE | |
PS C:\> Set-NewSiteBinding rainflytours.com,rainflyadbenture.com rainflysites PassIsSecure -BindingPort 8080 | |
#> | |
function Set-NewSiteBinding { | |
Param ( | |
[Parameter(Mandatory = $true, | |
Position = 0, | |
HelpMessage = "Comma delimited list of all URLs to add to the site")] | |
[ValidateNotNullOrEmpty()] | |
[string[]] | |
$NewDnsNames, | |
[Parameter(Mandatory = $true, | |
Position = 1, | |
HelpMessage = "Name of the IIS Site the new URLs should be associated to")] | |
[ValidateNotNullOrEmpty()] | |
[string] | |
$SiteName, | |
[Parameter(Mandatory = $true, | |
Position = 2, | |
HelpMessage = "Password used to export and import the certificate")] | |
[ValidateNotNullOrEmpty()] | |
[SecureString] | |
$CertPassword, | |
[Parameter(Mandatory=$false, | |
HelpMessage = "Port that the site bindings will be established on, defaults to 443.")] | |
[string] | |
$BindingPort = "443" | |
) | |
Write-Host "Creating Self-Signed Certificate for: $NewDnsNames" | |
$storeLocation = "Cert:\LocalMachine\My" | |
$certificate = New-SelfSignedCertificate -DnsName $NewDnsNames -CertStoreLocation $storeLocation | |
$thumbPrint = $certificate.Thumbprint | |
$certificatePath = ("cert:\localmachine\my\" + $certificate.Thumbprint) | |
Export-PfxCertificate -FilePath "C:\temp\temp.pfx" -Cert $certificatePath -Password $CertPassword | |
Import-PfxCertificate -FilePath "C:\temp\temp.pfx" -CertStoreLocation "Cert:\LocalMachine\Root" -Password $securedString | |
foreach ($url in $NewDnsNames) { | |
$bindingInformation = "*:" + $BindingPort + ":" + $url | |
Write-Host "IIS Binding '$bindingInformation' to be added to $SiteName" | |
New-IISSiteBinding -Name $SiteName ` | |
-BindingInformation $bindingInformation ` | |
-CertificateThumbPrint $thumbPrint ` | |
-CertStoreLocation $storeLocation ` | |
-Protocol https ` | |
-SslFlag "Sni" ` | |
-Force | |
} | |
} | |
<# | |
.SYNOPSIS | |
Simple control method that makes the calls to created the certificates and bind them to IIS via Set-NewSiteBinding | |
Followed by a simple loop to add host file entries for all hostnames | |
Parameters for the file are used within this method. | |
#> | |
function Add-SecureSiteBindings { | |
$securedString = ConvertTo-SecureString -String $CertPassphrase -Force -AsPlainText | |
Set-NewSiteBinding -NewDnsNames $NewDnsNames -SiteName $SiteName -CertPassword $securedString -BindingPort $Port | |
$NewDnsNames | ForEach-Object{ Add-HostsEntry $_.Trim(); } | |
} | |
# Setup a log file to capture any messages at the location of the script | |
$logFilePath = Join-Path -path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ChildPath "invoke-newsitebinding-$(Get-date -f 'yyyyMMddHHmmss').log"; | |
Add-SecureSiteBindings *>&1 | Tee-Object $logFilePath |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment