132 lines
4.9 KiB
PowerShell
132 lines
4.9 KiB
PowerShell
<#
|
|
|
|
.SYNOPSIS
|
|
Generates a self-signed certificate to be used by IIS for HTTPS communications
|
|
|
|
.DESCRIPTION
|
|
Generates a SAN self-signed certificate to be used by IIS for HTTPS communications.
|
|
The certificate will be automatically trusted by the local machine and assigned to the HTTPS binding of the defined IIS site.
|
|
|
|
The certificate by default will include the following items in the SAN for the cert:
|
|
Hostname
|
|
Short hostname limited to 15 characters
|
|
localhost
|
|
All IPv4 addresses
|
|
|
|
.PARAMETER IpAddress
|
|
IP Addresses to include in the Certificate. If not provided, the script will gather IPv4 addresses
|
|
|
|
.PARAMETER AdditionalDnsNames
|
|
Specifies additional DNS names that should be added to the certificate
|
|
|
|
.PARAMETER SiteName
|
|
Site name of the IIS site that should have the HTTPS binding configured. Defaults to Default Web Site
|
|
|
|
.PARAMETER Validity
|
|
Defines the validity of the certificate in years. Defaults to 15 years
|
|
|
|
.NOTES
|
|
Version: 1.0
|
|
Author: Tyler Hale
|
|
Creation Date: 2022.07.15
|
|
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateScript({foreach ($IP in $_) {[ipaddress]$IP}})]
|
|
[string[]]
|
|
$IpAddress = ((Get-NetIPAddress -AddressFamily IPv4 -Type Unicast -AddressState Preferred).IPAddress),
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string[]]
|
|
$AdditionalDnsNames,
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]
|
|
$SiteName = "Default Web Site",
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[int]
|
|
$Validity = 15
|
|
)
|
|
|
|
############################################### [Script Settings] ################################################
|
|
|
|
$Hostname = $Env:COMPUTERNAME
|
|
|
|
$CertParameters = @{
|
|
"Subject" = $Hostname
|
|
"NotAfter" = (Get-Date).AddYears($Validity)
|
|
"KeyExportPolicy" = "NonExportable"
|
|
"KeySpec" = "KeyExchange"
|
|
"KeyUsage" = "DigitalSignature","KeyEncipherment"
|
|
"CertStoreLocation" = "cert:\LocalMachine\My"
|
|
}
|
|
|
|
############################################# [Internal Processing] ##############################################
|
|
|
|
# Stop if not running as an admin
|
|
If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
Write-Error "Not running as an admin. Please relaunch running as an admin."
|
|
pause
|
|
exit
|
|
}
|
|
|
|
# Account for incompatibility for hostnames longer than 15 characters
|
|
if ($Hostname.Length -gt 15) {
|
|
Write-Verbose "Applying fixes for hostname length"
|
|
$ShortHostname = $Hostname.Substring(0,15)
|
|
$HostString = "127.0.0.1 $ShortHostname"
|
|
}
|
|
|
|
# Setup SAN text extension for the cert request
|
|
$TextExtension = "2.5.29.17={text}DNS=$Hostname&DNS=localhost"
|
|
|
|
# Add Compatibility hostname if defined to SAN
|
|
if ($null -ne $ShortHostname) {$TextExtension += "&DNS=$ShortHostname"}
|
|
|
|
# Add custom DNS names to SAN
|
|
if ($null -ne $DnsName) {foreach ($Name in $DnsName) {$TextExtension += "&DNS=$Name"}}
|
|
|
|
# Add IP Addresses to SAN
|
|
foreach ($Ip in $IpAddress) {$TextExtension += "&IPAddress=$Ip"}
|
|
if ($IpAddress -notcontains "127.0.0.1") {$TextExtension += "&IPAddress=127.0.0.1"}
|
|
|
|
# Add final text extension to cert request
|
|
$CertParameters['TextExtension'] = @($TextExtension)
|
|
|
|
################################################## [Execution] ###################################################
|
|
|
|
# Add hosts entry for short hostname if needed
|
|
if ($null,'' -ne $ShortHostname) {
|
|
if ((Get-Content "C:\Windows\System32\drivers\etc\hosts") -notcontains $HostString) {
|
|
Write-Verbose "Adding hosts entry"
|
|
Add-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Value $HostString
|
|
}
|
|
}
|
|
|
|
# Generate certificate
|
|
$GeneratedCert = New-SelfSignedCertificate @CertParameters
|
|
|
|
# Export certificate
|
|
$ExportedCert = $GeneratedCert | Export-Certificate -FilePath "$(Get-Item .\ | Select-Object -ExpandProperty FullName)\$Hostname`_$(Get-Date -Format yyyy-MM-dd_HH.mm.ss).cer"
|
|
Write-Host "Certificate exported to $($ExportedCert.FullName)`nYou will need to import the cert to the Local Machine - Trusted Root Certificate Authority on external clients that need to connect to this machine`n"
|
|
|
|
# Add certificate to trusted root CA
|
|
Import-Certificate -CertStoreLocation cert:\LocalMachine\Root -FilePath $ExportedCert.FullName | Out-Null
|
|
|
|
if (Get-Command -Name "Get-WebBinding" -ErrorAction SilentlyContinue) {
|
|
# Setup https binding if it is not configured
|
|
if ($null -eq (Get-WebBinding -Name $SiteName -Protocol "https")) {
|
|
Write-Verbose "Creating IIS Binding on Default Web Site"
|
|
New-WebBinding -Name $SiteName -IPAddress "*" -Port 443 -Protocol "https"
|
|
}
|
|
|
|
# Assign to IIS Binding
|
|
(Get-WebBinding -Name $SiteName -Port 443 -Protocol "https").AddSslCertificate($GeneratedCert.Thumbprint, "my")
|
|
}
|
|
else {
|
|
Write-Warning "IIS not installed so the binding was not configured`n"
|
|
}
|