Skip to content

Instantly share code, notes, and snippets.

@kevinblumenfeld
Created February 19, 2021 01:29
Show Gist options
  • Save kevinblumenfeld/0d8cfd610190e78051f82fb7be4776a6 to your computer and use it in GitHub Desktop.
Save kevinblumenfeld/0d8cfd610190e78051f82fb7be4776a6 to your computer and use it in GitHub Desktop.
# BEGIN ROOT CA
# Common name used for the RootCA. example: 'Contoso Root CA'
$CACommonName = 'SE-C-ROOT'
 
# Suffix for the RootCA. Example: 'OU=PKI,O=Contoso,C=US'
$CADistinguishedNameSuffix = 'OU=PKI,O=Contoso,C=US'
 
# Local directory where Root CA stores the CA Database
$DatabaseDirectory = 'C:\CADB\CertDB'
 
# Local directory where Root CA Stores the CA Dabase Logs
$LogDirectory = 'C:\CADB\CertLog'
 
# Base URL where CRL's will be published
$CRLBaseURL = 'http://pki.Contoso.com/repository/crl/'
 
# Base URL where the AIA will be published
$AIABaseURL = 'http://pki.Contoso.com/repository/cacerts/'
 
# The base distinguished name of the Active Directory where the PKI will be issued
$ADBaseDN = 'DC=corp,DC=ad,DC=Contoso,DC=com'
 
# Key length used for issuing CA Certs, recommended 4096
$RenewalKeyLength = 4096
 
# The following 2 Set the Validity period for the Root CA's CA cert
$RenewalValidityPeriod = 'Years'
$RenewalValidityPeriodUnits = 20
 
# The following 2 Set the maximum validity period of Subordinate CA Certs
$ValidityPeriod = “Years”
$ValidityPeriodUnits = 10
 
# The following 2 set the CRL Publication period for the Root CA
$CRLPeriod = 'weeks'
$CRLPeriodUnits = 26
 
# The Following 2 Set the CRL Delta publication period. For offline Root CA's, this should be 0 to disable
$CRLDeltaPeriod = 'Days'
$CRLDeltaPeriodUnits = 0
 
# The Following 2 set the CRL overlap period
$CRLOverlapPeriod = “Days”
$CRLOverlapPeriodUnits = 1
$ExportFolder = 'C:\Export'
 
# CAPolicy.inf Heredoc
$CAPolicy = @"
[Version]
Signature="`$Windows NT$"
[PolicyStatementExtension]
Policies=ContosoPKIRoot, ContosoPKIUS
[ContosoPKIRoot]
OID=1.2.840.113556.1.8000.2554.33272.65162.27929.18993.33873.35631.41284.35623
Notice="Certificate Policy Statement available at http://pki.Contoso.com/repository/cps.html"
URL=http://pki.Contoso.com/repository/cps.html
[ContosoPKIUS]
OID=1.2.840.113556.1.8000.2554.56838.1788.6750.16880.43819.45554.53594.43172
Notice="Certificate Policy Statement available at http://pki.Contoso.com/repository/cps.html"
URL=http://pki.Contoso.com/repository/cps.html
[Certsrv_Server]
RenewalKeyLength=$RenewalKeyLength
RenewalValidityPeriod=$RenewalValidityPeriod
RenewalValidityPeriodUnits=$RenewalValidityPeriodUnits
CRLPeriod=$CRLPeriod
CRLPeriodUnits=$CRLPeriodUnits
CRLDeltaPeriod=$CRLDeltaPeriod
CRLDeltaPeriodUnits=$CRLDeltaPeriodUnits
LoadDefaultTemplates=0
AlternateSignatureAlgorithm=0
[BasicConstraintsExtension]
Pathlength = 1
Critical = true
[CRLDistributionPoint]
Empty=True
[AuthorityInformationAccess]
Empty=True
"@
 
# Write the CAPolicy.inf Heredoc to the CAPolicy.inf file
$CAPolicy | Out-File -Force $env:windir\CAPolicy.inf
 
# Create the Database Folders in case they do not exist.
New-Item -Path $DatabaseDirectory -ItemType Directory
New-Item -Path $LogDirectory -ItemType Directory
New-Item -Path $ExportFolder -ItemType Directory
 
# Add the Active Directory Certificate Services role and management snap-in
Install-WindowsFeature Adcs-cert-Authority -IncludeManagementTools
Install-WindowsFeature RSAT-ADCS-Mgmt
 
# Install and configure the Root CA Certificate Authority
$Params = @{
CAType = 'StandaloneRootCA'
OverwriteExistingKey = $true
CACommonName = $CACommonName
CADistinguishedNameSuffix = $CADistinguishedNameSuffix
KeyLength = $RenewalKeyLength
HashAlgorithmName = 'SHA256'
CryptoProviderName = "RSA#Microsoft Software Key Storage Provider"
DatabaseDirectory = $DatabaseDirectory
LogDirectory = $LogDirectory
ValidityPeriod = $RenewalValidityPeriod
ValidityPeriodUnits = $RenewalValidityPeriodUnits
Force = $true
}
Install-AdcsCertificationAuthority @Params
 
# Remove the default CRL distribution points
Get-CACrlDistributionPoint | ForEach-Object {
Remove-CACrlDistributionPoint $_.uri -Force
}
 
# Set the CRL Distribution points
Add-CACRLDistributionPoint -Uri "$($env:windir)\System32\CertSrv\CertEnroll\%3%8%9.crl" -PublishToServer -Force
Add-CACRLDistributionPoint -Uri "$($CRLBaseURL)%3%8%9.crl" -AddToCertificateCDP -Force
Get-CAAuthorityInformationAccess | ForEach-Object {
Remove-CAAuthorityInformationAccess $_.uri -Force
}
Add-CAAuthorityInformationAccess -AddToCertificateAia "$($AIABaseURL)%3%4.crt" -Force
 
# Configure the CA
certutil.exe –setreg CA\CACertPublicationURLs “1:%WINDIR%\system32\CertSrv\CertEnroll\%3%4.crt\n2:$($AIABaseURL)%3%4.crt”
certutil.exe –setreg CA\CRLPeriodUnits $CRLPeriodUnits
certutil.exe –setreg CA\CRLPeriod $CRLPeriod
certutil.exe –setreg CA\CRLDeltaPeriodUnits $CRLDeltaPeriodUnits
certutil.exe –setreg CA\CRLDeltaPeriod $CRLDeltaPeriod
certutil.exe –setreg CA\CRLOverlapPeriodUnits $CRLOverlapPeriodUnits
certutil.exe –setreg CA\CRLOverlapPeriod $CRLOverlapPeriod
certutil.exe –setreg CA\ValidityPeriodUnits $ValidityPeriodUnits
certutil.exe –setreg CA\ValidityPeriod $ValidityPeriod
certutil.exe –setreg CA\DSConfigDN “CN=Configuration,$ADBaseDN”
certutil.exe -setreg CA\AuditFilter 127
certutil.exe –setreg Policy\CAPathLength 1
 
# Restart the certificate services so the changes can take affect
Restart-Service certsvc
sleep 30
 
# Publish the CRL
certutil.exe -crl
$DefaultCert = Get-ChildItem -Path $env:windir\System32\CertSrv\CertEnroll -Filter '*.crt'
$NewName = Join-Path $ExportFolder ($DefaultCert.Name -replace '^[^_]*_', '')
Copy-Item -Path $DefaultCert.FullName -Destination $NewName
Get-ChildItem -Path $env:windir\System32\CertSrv\CertEnroll -Filter '*.crl' | Copy-Item -Destination $ExportFolder
explorer.exe $ExportFolder
 
# END ROOT CA
 
 
# BEGIN SUB CA
# Common name used for the Sub CA. example: 'Contoso Root CA'
$CACommonName = 'SE-C-CA01'
 
# Suffix for the RootCA. Example: 'OU=PKI,O=Contoso,C=US'
$CADistinguishedNameSuffix = 'OU=PKI,O=Contoso,C=US'
 
# Local directory where Sub CA stores the CA Database
$DatabaseDirectory = 'C:\CADB\CertDB'
 
# Local directory where Sub CA Stores the CA Dabase Logs
$LogDirectory = 'C:\CADB\CertLog'
 
# Base URL where CRL's will be published
$CRLBaseURL = 'http://pki.Contoso.com/repository/crl/'
 
# Base URL where the AIA will be published
$AIABaseURL = 'http://pki.Contoso.com/repository/cacerts/'
 
# The base distinguished name of the Active Directory where the PKI will be issued
$ADBaseDN = 'DC=corp,DC=ad,DC=Contoso,DC=com'
 
# Internal OID used for the CA Policies. OID should be IANA assigned
# $InternalPolicyOID = '1.2.840.113556.1.8000.2554.26391.41112.40880.18184.45934.5730727.13822302.509'
 
$InternalPolicyOID = '1.2.840.113556.1.8000.2554.56838.1788.6750.16880.43819.45554.53594.43172'
 
# Text to display in the policy notice. Shout be single line. Do not include any double quotes.
$InternalPolicyNotice = 'Certificate Policy Statement available at http://pki.Contoso.com/repository/cps.html'
 
# URL to the published RFC 3647 Certificate Practice Statement
$InternalPolicyURL = 'http://pki.Contoso.com/repository/cps.html'
 
# Key length used for issuing CA Certs, recommended 4096
$RenewalKeyLength = 4096
 
# The following 2 Set the maximum validity period of Issued Certs
$ValidityPeriod = “Years”
$ValidityPeriodUnits = 5
 
# The following 2 set the CRL Publication period for the Sub CA
$CRLPeriod = 'weeks'
$CRLPeriodUnits = 4
 
# The Following 2 Set the CRL Delta publication period.
$CRLDeltaPeriod = 'Days'
$CRLDeltaPeriodUnits = 1
 
# The Following 2 set the CRL overlap period
$CRLOverlapPeriod = 'Days'
$CRLOverlapPeriodUnits = 1
 
# Request File
$CRQFile = "C:\Certs\SUBCA.req"
 
# CAPolicy.inf Heredoc
$CAPolicy = @"
[Version]
Signature="`$Windows NT$"
[PolicyStatementExtension]
Policies=ContosoPKIUS
[ContosoPKIUS]
OID=$InternalPolicyOID
Notice="$InternalPolicyNotice"
URL=$InternalPolicyURL
[Certsrv_Server]
RenewalKeyLength=$RenewalKeyLength
RenewalValidityPeriod=$RenewalValidityPeriod
RenewalValidityPeriodUnits=$RenewalValidityPeriodUnits
CRLPeriod=$CRLPeriod
CRLPeriodUnits=$CRLPeriodUnits
CRLDeltaPeriod=$CRLDeltaPeriod
CRLDeltaPeriodUnits=$CRLDeltaPeriodUnits
LoadDefaultTemplates=0
AlternateSignatureAlgorithm=0
"@
 
# Write the CAPolicy.inf Heredoc to the CAPolicy.inf file (install PS5 for -NoNewline)
# $CAPolicy | Out-File -Force -NoNewline $env:windir\CAPolicy.inf
$CAPolicy | Out-File -Force $env:windir\CAPolicy.inf
 
# Create the Folders in case they do not exist.
New-Item -Path $DatabaseDirectory -ItemType Directory -ErrorAction SilentlyContinue
New-Item -Path $LogDirectory -ItemType Directory -ErrorAction SilentlyContinue
New-Item -Path $(Split-Path -Parent -Path $CRQFile ) -ItemType Directory -ErrorAction SilentlyContinue
 
# Add the Active Directory Certificate Services role and management snapin
Install-WindowsFeature Adcs-cert-Authority -IncludeManagementTools
Install-WindowsFeature RSAT-ADCS-Mgmt
 
# Install and configure the Sub CA Certificate Authority
$Result = Install-AdcsCertificationAuthority -CAType EnterpriseSubordinateCA `
-CACommonName $CACommonName `
-CADistinguishedNameSuffix $CADistinguishedNameSuffix `
-KeyLength $RenewalKeyLength `
-HashAlgorithmName SHA256 `
-CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
-DatabaseDirectory $DatabaseDirectory `
-LogDirectory $LogDirectory `
-OverwriteExistingKey `
-OutputCertRequestFile $CRQFile `
-Force
explorer.exe $(Split-Path -Parent -Path $CRQFile )
$CertFilePath = $null
while (!$CertFilePath) {
$ProvidedPath = Read-Host -Prompt "Please enter the full file path of the response CRQ (*.cer or *.crt)"
if ($ProvidedPath -match '.(cer|crt)$' -and (Test-Path $ProvidedPath)) {
$CertFilePath = $ProvidedPath
}
}
 
# Install IIS and create repository/crl directories and copy .crl file to it
# Export and Copy RootCA’s Root Certificate to $CertFilePath
certutil.exe –installcert $CertFilePath
Start-Service certsvc
 
# Remove the default CRL distribution points
Get-CACrlDistributionPoint | ForEach-Object {
Remove-CACrlDistributionPoint $_.uri -Force
}
 
# Set the CRL Distribution points
Add-CACRLDistributionPoint -Uri "$($env:windir)\System32\CertSrv\CertEnroll\%3%8%9.crl" -PublishToServer -PublishDeltaToServer -Force
Add-CACRLDistributionPoint -Uri "$($CRLBaseURL)%3%8%9.crl" -AddToCertificateCDP -Force
Get-CAAuthorityInformationAccess | ForEach-Object {
Remove-CAAuthorityInformationAccess $_.uri -Force
}
Add-CAAuthorityInformationAccess -AddToCertificateAia "$($AIABaseURL)%3%4.crt" -Force
# Add-CAAuthorityInformationAccess -AddToCertificateOcsp $OCSPBaseURL -Force
 
# Configure the CA
certutil.exe –setreg CA\CACertPublicationURLs “1:%WINDIR%\system32\CertSrv\CertEnroll\%3%4.crt\n2:$($AIABaseURL)%3%4.crt”
certutil.exe –setreg CA\CRLPeriodUnits $CRLPeriodUnits
certutil.exe –setreg CA\CRLPeriod $CRLPeriod
certutil.exe –setreg CA\CRLDeltaPeriodUnits $CRLDeltaPeriodUnits
certutil.exe –setreg CA\CRLDeltaPeriod $CRLDeltaPeriod
certutil.exe –setreg CA\CRLOverlapPeriodUnits $CRLOverlapPeriodUnits
certutil.exe –setreg CA\CRLOverlapPeriod $CRLOverlapPeriod
certutil.exe –setreg CA\ValidityPeriodUnits $ValidityPeriodUnits
certutil.exe –setreg CA\ValidityPeriod $ValidityPeriod
certutil.exe –setreg CA\DSConfigDN “CN=Configuration,$ADBaseDN”
certutil.exe -setreg CA\AuditFilter 127
 
# Restart the certificate services so the changes can take affect
Restart-Service certsvc
sleep 30
 
# Publish the CRL
certutil.exe -crl
explorer.exe $env:windir\System32\CertSrv\CertEnroll
 
# END SUB CA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment