Skip to content

TheOmnilord/ADCS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ADCS — Active Directory Certificate Services PowerShell Tools

A set of PowerShell scripts for administering Active Directory Certificate Services (AD CS / ADCS) from the command line. Built for Windows PKI administrators who need to manage certificate templates and process certificate requests at scale, without clicking through the Certificate Templates MMC snap-in or the Certification Authority console.

Currently includes:

  • Bulk certificate template validity updates — useful for rolling out the CA/Browser Forum SC-081 validity reductions (200 days from March 2026, 100 days from March 2027, 47 days from March 2029) across many templates at once.
  • Batch CSR submission to an Enterprise CA via certreq.exe, with resume-safe CSV tracking of request IDs and automated retrieval of issued certificates.

No AD PowerShell module dependency. Works on Windows PowerShell 5.1 and PowerShell 7+.

Scripts

Script Description
Set-ADCSTemplateValidity.ps1 Bulk-update the validity period (and optionally the renewal overlap period) on one or more certificate templates, with wildcard name matching.
Submit-CertificateRequests.ps1 Batch-submit .req/.csr/.txt files to an ADCS CA via certreq.exe, track request IDs in a CSV, and later retrieve the issued certificates.

Set-ADCSTemplateValidity.ps1

Modifies the pKIExpirationPeriod (and optionally pKIOverlapPeriod) attribute on ADCS certificate templates in Active Directory. Supports wildcard template name matching so you can update many templates in one go.

Why you need this

The CA/Browser Forum (ballot SC-081, passed April 2025) mandates a phased reduction of the maximum validity period for publicly-trusted TLS server certificates. While ADCS is typically used for internal PKI, many organizations mirror these limits on their internal CAs to keep templates aligned with industry best practice (and to be ready if any templates ever feed into publicly-trusted chains).

Effective date Maximum validity (TLS server certs)
15 March 2026 (current) 200 days
15 March 2027 100 days
15 March 2029 47 days

As the cadence tightens, manually adjusting every template through the Certificate Templates MMC snap-in becomes painful. This script lets you update dozens of templates in seconds:

# March 2026 rollover: drop TLS templates to 200 days
.\Set-ADCSTemplateValidity.ps1 -TemplateName "*Web*","*TLS*" -ValidityPeriod 200 -ValidityPeriodUnit Days -WhatIf

Client authentication, code signing, S/MIME, and other non-TLS templates are not covered by SC-081 and can keep longer validity periods. Use targeted wildcards to avoid changing those.

Features

  • Wildcard matching on template CN (e.g. User*, *Web*, *VPN*)
  • Human-readable durations (Years, Months, Weeks, Days, Hours)
  • -WhatIf / -Confirm support with ConfirmImpact = 'High'
  • No AD PowerShell module required - uses System.DirectoryServices directly
  • Skips templates already set to the requested value (byte-array compare)
  • Auto-increments msPKI-Template-Minor-Revision so CAs detect the change
  • Deduplication when multiple patterns match the same template
  • Summary output with counts of Modified / Already set / Skipped / Errors
  • Pipeline-friendly output as PSCustomObject per template

Requirements

  • Windows PowerShell 5.1 or PowerShell 7+
  • A domain-joined machine (or use -Server to target a specific DC)
  • Permissions to modify certificate templates (typically Enterprise Admin or delegated rights on the CN=Certificate Templates container in the Configuration naming context)

Parameters

Parameter Type Required Description
-TemplateName string[] Yes One or more template CN names. Supports LDAP wildcards (*, ?).
-ValidityPeriod int (1-9999) Yes Numeric value for the new validity period.
-ValidityPeriodUnit Years / Months / Weeks / Days / Hours Yes Unit for -ValidityPeriod. AD uses 365 days/year and 30 days/month.
-OverlapPeriod int (1-9999) No Numeric value for the renewal overlap period.
-OverlapPeriodUnit Years / Months / Weeks / Days / Hours No Unit for -OverlapPeriod. Required if -OverlapPeriod is set.
-Server string No Target a specific domain controller (not a CA server) for the LDAP connection, e.g. dc01.domain.com.
-WhatIf switch No Preview changes without making them.
-Confirm switch No Prompt before each change.

Usage

Preview which templates would be changed (WhatIf):

.\Set-ADCSTemplateValidity.ps1 -TemplateName "Web*" -ValidityPeriod 2 -ValidityPeriodUnit Years -WhatIf

Set validity and overlap on multiple wildcard patterns:

.\Set-ADCSTemplateValidity.ps1 `
    -TemplateName "User*","Computer*" `
    -ValidityPeriod 1 -ValidityPeriodUnit Years `
    -OverlapPeriod 6 -OverlapPeriodUnit Weeks

Set validity on a single exact template, target a specific DC, skip confirmation:

.\Set-ADCSTemplateValidity.ps1 `
    -TemplateName "WebServer" `
    -ValidityPeriod 365 -ValidityPeriodUnit Days `
    -Server dc01.domain.com `
    -Confirm:$false

Preview all templates matching a pattern and capture the output:

$report = .\Set-ADCSTemplateValidity.ps1 -TemplateName "*" -ValidityPeriod 1 -ValidityPeriodUnit Years -WhatIf
$report | Format-Table -AutoSize

Output

Each matched template produces a PSCustomObject with:

Property Description
TemplateName Template CN
DisplayName Template display name
PreviousValidity Current validity period (human-readable)
NewValidity Requested new validity period
PreviousOverlap Current overlap period (human-readable)
NewOverlap Requested new overlap period, or (unchanged)
Status Modified, Already set, Skipped, or Error: <message>

A color-coded summary is printed at the end:

--- Summary ---
  Total matched : 12
  Modified      : 7
  Already set   : 3
  Skipped       : 2
  Errors        : 0
  Run 'certutil -pulse' on CA server(s) to refresh.

Notes

  • After modifying templates, run certutil -pulse on each CA server for changes to be picked up immediately. Otherwise AD replication + CA cache refresh will eventually apply them.
  • The -Server parameter is for a domain controller, not the CA server. Certificate templates are AD objects stored in the forest's Configuration naming context.
  • Changes replicate forest-wide from the Configuration NC. Allow normal AD replication time.
  • The script increments msPKI-Template-Minor-Revision on each change so issuing CAs detect the update.
  • -WhatIf templates show as Skipped in the output (they would have been modified but weren't due to the WhatIf flag).

How It Works

  1. Connects to RootDSE to resolve the Configuration naming context.
  2. Searches CN=Certificate Templates,CN=Public Key Services,CN=Services,<ConfigNC> for templates matching the pattern(s) using an LDAP filter.
  3. For each match, decodes the current pKIExpirationPeriod / pKIOverlapPeriod (8-byte little-endian negative FILETIME ticks).
  4. Compares against the requested value; skips if already equal.
  5. Writes the new byte array via DirectoryEntry.InvokeSet() and calls SetInfo() to commit.

Submit-CertificateRequests.ps1

Batch-submits certificate signing requests (.req / .csr / .txt) from a folder to an ADCS CA using certreq.exe, tracks each submission's request ID in a CSV file, and can later retrieve the issued certificates.

Features

  • Batch submit all request files in a folder in one run
  • CSV tracking file records request ID, submit time, status, error messages per file
  • Resume-safe - files already present in the tracking CSV are skipped on re-run
  • Retrieve mode picks up previously-submitted Pending requests and pulls issued .cer files
  • Both mode submits then retrieves in a single invocation
  • Connectivity pre-check via certutil -ping before any submissions
  • Per-run timestamped log file (CertBatch_yyyyMMdd_HHmmss.log)
  • -WhatIf / -Confirm support
  • Handles empty files, missing request IDs, denied requests gracefully

Requirements

  • Windows with certreq.exe and certutil.exe available (standard on Windows)
  • Windows PowerShell 5.1 or PowerShell 7+
  • Permissions to submit to the target CA and template
  • Network connectivity to the CA

Parameters

Parameter Type Required Default Description
-InputPath string Yes Folder containing .req / .csr / .txt request files.
-CAConfig string Yes CA configuration string, e.g. CA01.domain.com\Contoso Issuing CA 1.
-CertificateTemplate string Yes Certificate template name (the CN, not the display name).
-TrackingFile string No .\CertTracking.csv CSV file used to track request IDs and statuses across runs.
-OutputFolder string No .\Certificates Folder where issued .cer files are saved (one per request, named after the request file).
-Mode Submit / Retrieve / Both No Submit Submit = submit new requests only; Retrieve = pull certs for previously-pending requests; Both = do both.
-WhatIf switch No Preview without submitting/retrieving.
-Confirm switch No Prompt before each action.

Usage

Submit all CSRs in a folder:

.\Submit-CertificateRequests.ps1 `
    -InputPath "C:\CSRs" `
    -CAConfig "CA01.domain.com\Contoso Issuing CA 1" `
    -CertificateTemplate "WebServer" `
    -Mode Submit

Retrieve any issued certificates for previously-pending requests:

.\Submit-CertificateRequests.ps1 `
    -InputPath "C:\CSRs" `
    -CAConfig "CA01.domain.com\Contoso Issuing CA 1" `
    -CertificateTemplate "WebServer" `
    -Mode Retrieve

Submit and retrieve in one go:

.\Submit-CertificateRequests.ps1 `
    -InputPath "C:\CSRs" `
    -CAConfig "CA01.domain.com\Contoso Issuing CA 1" `
    -CertificateTemplate "WebServer" `
    -Mode Both

Preview what would be submitted:

.\Submit-CertificateRequests.ps1 `
    -InputPath "C:\CSRs" `
    -CAConfig "CA01.domain.com\Contoso Issuing CA 1" `
    -CertificateTemplate "WebServer" `
    -Mode Submit -WhatIf

Tracking CSV Schema

Column Description
RequestFile Full path of the source .req/.csr/.txt file
RequestID Numeric request ID assigned by the CA
SubmitTime ISO-8601 submission timestamp
Status Issued, Pending, Denied, Error, or Unknown
OutputCertFile Full path where the issued .cer is saved
LastCheckTime ISO-8601 timestamp of last status check
ErrorMessage Error output from certreq if the submission or retrieval failed

Notes

  • The tracking CSV is the source of truth for resume behavior. Deleting it will cause the script to re-submit all files (and the CA may issue duplicates).
  • Pending typically means the CA requires manager approval. Re-run in Retrieve mode after approval to pull the issued cert.
  • Issued .cer files are named after the source request file (e.g. server1.req -> server1.cer).
  • Empty request files are skipped with a warning.
  • A timestamped log file is created in the working directory for each run.

License

MIT

Contributing

Issues and pull requests welcome.

About

PowerShell scripts for managing Active Directory Certificate Services (ADCS / AD CS) — bulk-update certificate template validity periods for SC-081 compliance, and batch-submit CSRs to an Enterprise CA with resume-safe tracking.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors