PowerShell
Edit|Remove
<# 
 
.SYNOPSIS 
Script to ease the pain of creating/submitting/automating the process of creating a certificate for on-prem CA 
 
.DESCRIPTION 
Required Variables: Subject, Exportable, SAN1, Template. Up to 5 SANs can be included in this script. More can be added if desired. User must have privileges to submit / create certificate template.  
 
.EXAMPLE 
./get-certificate-inf.ps1 -Subject contoso.com -Exportable $false -Template Server -SAN1 contoso.com -SAN2 www.contoso.com -SAN3 devsite.constoso.com 
 
.NOTES 
Variables that Require user modification to the script: See "Subject Variables" Section. 
 
#> 
 
 
[CmdletBinding()] 
Param( 
[Parameter(Mandatory=$True)] 
[string]$Subject, 
 
[Parameter(Mandatory=$True)] 
[string]$Exportable, 
 
[Parameter(Mandatory=$True)] 
[string]$SAN1, 
 
[Parameter(Mandatory=$False)] 
[string]$SAN2, 
 
[Parameter(Mandatory=$False)] 
[string]$SAN3, 
 
[Parameter(Mandatory=$False)] 
[string]$SAN4, 
 
[Parameter(Mandatory=$False)] 
[string]$SAN5, 
 
[Parameter(Mandatory=$True)] 
[string]$Template 
 
) 
$ErrorActionPreference = 'Inquire' 
 
## Gathering Logic for SAN 
$SAN = '' 
if ($SAN2) 
{ 
    $SAN +="&dns=$SAN2" 
} 
else{} 
 
if ($SAN3) 
{ 
    $SAN +="&dns=$SAN3" 
} 
else{} 
 
if ($SAN4) 
{ 
    $SAN +="&dns=$SAN4" 
} 
else{} 
 
if ($SAN5) 
{ 
    $SAN +="&dns=$SAN5" 
} 
else{} 
 
$FullSAN ="{text}dns=$SAN1$SAN" 
 
## Required Because Powershell interprets $Windows as a variable not a string 
$Windows = '$Windows' 
 
$inputfiletemplate = @" 
[Version]  
Signature="$Windows NT$" 
 
##Enter Subject Variables Here and uncomment: 
# $O = [organization] 
# $OU = [Organizational Unit] 
# $E = [email] 
# $L = [locality] 
# $ST = [state] 
# $C = [country] 
 
[NewRequest]  
Subject = "CN=$Subject, O=$O, OU=$OU, E=$E, L=$L, ST=$ST, C=$C"   ; For a wildcard use "CN=*.CONTOSO.COM" for example 
Exportable = $Exportable                  ; Private key is not exportable  
KeyLength = 2048                    ; Common key sizes: 512, 1024, 2048, 4096, 8192, 16384  
KeySpec = 1                         ; AT_KEYEXCHANGE  
KeyUsage = 0xA0                     ; Digital Signature, Key Encipherment  
MachineKeySet = True                ; The key belongs to the local computer account  
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"  
ProviderType = 12  
SMIME = FALSE  
RequestType = CMC 
 
; At least certreq.exe shipping with Windows Vista/Server 2008 is required to interpret the [Strings] and [Extensions] sections below 
 
[Strings]  
szOID_SUBJECT_ALT_NAME2 = "2.5.29.17"  
szOID_ENHANCED_KEY_USAGE = "2.5.29.37"  
szOID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"  
szOID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2" 
 
[Extensions]  
%szOID_SUBJECT_ALT_NAME2% = "$FullSAN"  
%szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_PKIX_KP_SERVER_AUTH%,%szOID_PKIX_KP_CLIENT_AUTH%" 
 
[RequestAttributes]  
CertificateTemplate=$Template 
"@ 
 
### Gathering Certificate information ### 
 
$filename = $Subject.Substring(0,3) 
 
### Make allowance for wildcard CNs 
 
    if ($filename -like "*") 
        { 
            Write-Host "Hang on...have to create a new filename..." 
            $filename = (-join ((65..90) + (97..122) | Get-Random -Count 5 | % {[char]$_})) 
        } 
        else  
        { 
        #Do Nothing     
        } 
 
$inputfiletemplate | Out-File "$filename.inf" 
 
Write-Host "Generating request" 
 
### End of Gathering Certificate information ### 
 
# Using Certreq to request a new certificate with information file and request 
& "C:\Windows\System32\certreq.exe" "-new" "$filename.inf" "$filename.req" 
 
# Submitting Request to CA with request and saving file as a .cer 
Write-Host "Submitting request to CA" 
& "C:\Windows\System32\certreq.exe" "-submit" "$filename.req" "$filename.cer" 
 
# Accepting the certificate from SubCA 
& "C:\Windows\System32\certreq.exe" "-accept" "$filename.cer" 
Write-Host "Certificate Imported Successfully" 
 
# File cleanup 
Write-Host "Cleaning up files generated" 
Remove-Item "$filename.*" -Force 
 
# Asking if you would like to export the certificate  
if ($Exportable -eq $TRUE) 
{ 
    if((Read-Host -Prompt "Do you want to export the certificate? Y\N"-eq "y"){ 
#Show certifiate store  
Write-Host "Fetching Certificates in store for you..." 
get-childitem -Path Cert:\LocalMachine\my | Format-list subject,thumbprint 
 
#Ask user to copy thumbprint to console 
Write-Host "Please copy the thumbprint to export" 
$thumbprint = Read-Host -Prompt "Please paste the desired thumbprint here" 
 
#Export certificate with password 
get-childitem -Path Cert:\LocalMachine\my\$thumbprint | Export-PfxCertificate -Password (read-host -Prompt "Please type your password" -AsSecureString) -ChainOption EndEntityCertOnly -NoClobber -FilePath (read-host -Prompt "Give the PFX a filename with .pfx""`nExport Successful... 'till next time." 
    } 
} 
else 
{ 
    "Mission Complete!" 
} 
 

"There's got to be a better way..."

 

 

What it does: This script uses powershell to create a certificate with SAN (Subject Alternative Names), submit the request to the CA with specific template and issue to a server/ workstation accordingly.

What it doesn't do: It does not allow for IP addresses to be added to the template as well, althought that might work in the DNS submission.