New-SanCertificate/New-SanCertificate.ps1

133 lines
4.9 KiB
PowerShell
Raw Normal View History

2022-07-15 12:33:42 -06:00
<#
.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.
2022-07-15 12:33:42 -06:00
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
2022-07-15 12:33:42 -06:00
.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()]
2022-07-15 12:33:42 -06:00
[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")) {
2022-07-15 12:33:42 -06:00
Write-Verbose "Creating IIS Binding on Default Web Site"
New-WebBinding -Name $SiteName -IPAddress "*" -Port 443 -Protocol "https"
2022-07-15 12:33:42 -06:00
}
# Assign to IIS Binding
(Get-WebBinding -Name $SiteName -Port 443 -Protocol "https").AddSslCertificate($GeneratedCert.Thumbprint, "my")
2022-07-15 12:33:42 -06:00
}
else {
Write-Warning "IIS not installed so the binding was not configured`n"
}