Skip to content

Instantly share code, notes, and snippets.

@d4rkeagle65
Last active September 14, 2022 16:21
Show Gist options
  • Save d4rkeagle65/d7480d422f3b73f1a2efe3ca0c464a44 to your computer and use it in GitHub Desktop.
Save d4rkeagle65/d7480d422f3b73f1a2efe3ca0c464a44 to your computer and use it in GitHub Desktop.
Quick Setup of a Certificate Authority with a Certificate Template created and published to AD for Server Authentication to enable and allow for LDAPS to be setup.
# Some Sources:
#https://docs.microsoft.com/en-us/powershell/module/pkiclient/export-certificate?view=win10-ps
#https://powershell.org/forums/topic/certificate-templates-add-catemplate-problems/
#Run as Admin
$caName = "LDAPS-Server-Auth"
$cryptoProvider = "RSA#Microsoft Software Key Storage Provider"
$keyLength = 2048
$hashAlgorithm = 'SHA256'
$validityYears = 5
$dbDir = "C:\Windows\System32\certLog"
$logDir = $dbDir
$caCommonName = ($env:computerName + '-Root-CA')
Import-Module ServerManager
Import-Module ActiveDirectory
Do {
$featureInstall = Install-WindowsFeature ADCS-Cert-Authority -IncludeManagementTools
} While ($featureInstall.ExitCode -ne 'NoChangeNeeded')
Install-ADcsCertificationAuthority -CAType EnterpriseRootCA `
-CACommonName $caCommonName `
-CADistinguishedNameSuffix (Get-ADDomain).DistinguishedName `
-CryptoProviderName $cryptoProvider `
-KeyLength $keyLength `
-HashAlgorithmName $hashAlgorithm `
-ValidityPeriod Years `
-ValidityperiodUnits $validityYears `
-DatabaseDirectory $dbDir `
-LogDirectory $logDir `
-AllowAdministratorInteraction `
-Force
$caCert = $false
$caSubject = ("CN=" + ($env:computerName + '-Root-CA,') + (Get-ADDomain).DistinguishedName).Replace(' ','')
Get-ChildItem -Path cert:\LocalMachine\CA | Foreach-Object {
$singleCert = $_
$certSubject = ($singleCert | Select -Expand Subject).Replace(' ','')
If ($certSubject -eq $caSubject) {
$caCert = $singleCert
}
}
$ConfigContext = ([ADSI]"LDAP://RootDSE").ConfigurationNamingContext
$ADSI = [ADSI]"LDAP://CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigContext"
$NewTempl = $ADSI.Create("pKICertificateTemplate", ("CN=" + $caName))
$NewTempl.put("distinguishedName",("CN=" + $caName + ",CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigContext"))
$NewTempl.put("flags","131168")
$NewTempl.put("displayName",$caName)
$NewTempl.put("revision","100")
$NewTempl.put("pKIDefaultKeySpec","1")
$NewTempl.SetInfo()
$NewTempl.put("pKIMaxIssuingDepth","0")
$NewTempl.put("msPKI-RA-Signature","0")
$NewTempl.put("msPKI-Enrollment-Flag","40")
$NewTempl.put("msPKI-Private-Key-Flag","16")
$NewTempl.put("msPKI-Certificate-Name-Flag","415236096")
$NewTempl.put("msPKI-Minimal-Key-Size","2048")
$NewTempl.put("msPKI-Template-Schema-Version","2")
$NewTempl.put("msPKI-Template-Minor-Revision","2")
$NewTempl.put("msPKI-Cert-Template-OID","1.3.6.1.4.1.311.21.8.1888073.13637090.1918131.8213729.6866627.9.6218423.5192306")
$NewTempl.SetInfo()
$WATempl = $ADSI.psbase.children | where {$_.Name -match "KerberosAuthentication"}
$NewTempl.pKIExpirationPeriod = $WATempl.pKIExpirationPeriod
$NewTempl.pKIKeyUsage = $WATempl.pKIKeyUsage
$NewTempl.pKICriticalExtensions = $WATempl.pKICriticalExtensions
$NewTempl.pKIExtendedKeyUsage = $WATempl.pKIExtendedKeyUsage
$NewTempl.pKIDefaultCSPs = $WATempl.pKIDefaultCSPs
$NewTempl.pKIOverlapPeriod = $WATempl.pKIOverlapPeriod
$NewTempl.'msPKI-Certificate-Application-Policy' = $WATempl.'msPKI-Certificate-Application-Policy'
$NewTempl.'msPKI-RA-Application-Policies' = $WATempl.'msPKI-RA-Application-Policies'
$NewTempl.SetInfo()
$CertTemplateParams = @{
LDAPFilter = '(&(objectClass=pKICertificateTemplate))'
SearchBase = 'CN=Certificate Templates,CN=Public Key Services,CN=Services,{0}' -f ([adsi]'LDAP://RootDSE').configurationNamingContext[0]
Properties = 'pKIExpirationPeriod'
}
$krbTemp = (Get-ADObject @CertTemplateParams) | Where-Object { $_.Name -eq $caName }
$NewExpirationPeriod = [System.BitConverter]::GetBytes($([System.BitConverter]::ToInt64($krbTemp.pKIExpirationPeriod, 0)) * 5)
Set-ADObject -Identity $krbTemp.objectGuid -Replace @{pKIExpirationPeriod = $NewExpirationPeriod}
#Set new
$AdObj = New-Object System.Security.Principal.NTAccount("Authenticated Users")
$identity = $AdObj.Translate([System.Security.Principal.SecurityIdentifier])
$adRights = "ReadProperty, ExtendedRight, GenericExecute"
$type = "Allow"
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($identity,$adRights,$type)
$NewTempl.psbase.ObjectSecurity.SetAccessRule($ACE)
$NewTempl.psbase.commitchanges()
Sleep 5
Stop-Service CertSvc
Sleep 5
Start-Service CertSvc
Sleep 5
$templates = $adsi | select -ExpandProperty Children
if ([bool]($templates.distinguishedName -match ("CN=" + $caCommonName + ",CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigContext")) -eq 'True'){
Add-CATemplate -Name $caName -force
}
$Stoploop = $false
[int]$Retrycount = "0"
do {
try {
$templates = $adsi | select -ExpandProperty Children
Add-CATemplate -Name $caName -force
Write-Host "Template Publish Successfully."
$Stoploop = $true
}
catch {
if ($Retrycount -gt 30){
Write-Host "Could not Publish Template after 30 retrys."
$Stoploop = $true
}
else {
Write-Host "Could not Publish Template, retrying in 30 seconds..."
Start-Sleep -Seconds 30
$Retrycount = $Retrycount + 1
}
}
}
While ($Stoploop -eq $false)
gpupdate /force
Get-ChildItem -Path cert:\LocalMachine\CA | Foreach-Object {
$singleCert = $_
$certSubject = ($singleCert | Select -Expand Subject).Replace(' ','')
If ($certSubject -eq $caSubject) {
$caCert = $singleCert
}
}
#Export-Certificate -Cert $caCert -FilePath ("C:\ProgramData\" + $caCommonName + ".cer") -Type CERT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment