How to determine all certificates that will expire within 30 days

Woudn't it be interesting for the CA admin to know which certificates are expiring in the near future? If autoenrollment is not eanbled, certificate users should be informed in advance before they actually loose functionality.

A simple certutil command enables the CA admin to generate a list with all expiring certificates:

certutil –view –restrict "NotAfter<=May 5,2008 08:00AM,NotAfter>=April 24,2008 08:00AM" –out "RequestID,RequesterName"

Since I mentioned autoenrollment above, here is a trick how to determine if a certificate was enrolled manually or with autoenrollment.

certutil –view -v -out rawrequest | findstr Process

The above command can certainly be extended with the -restrict parameter to reduce the amount of output producted by the query.

The name of the task performing autoenrollment differs for different OS releases and possible for machine and user contexts. Manually requested certificates may show a process name like certreq or cscript.

To learn more how to notify users of certificate expiration, see

Comments (9)
  1. Dukkse says:

    If you want to get all expiring certificates for 2 different templates, can you ask that in the same question?

    I dont get it to work.

    certutil -config – -view -restrict "NotAfter<=07/30/2012 08:00AM,NotAfter>=07/18/2012 08:00AM,CertificateTemplate = WebServer,CertificateTemplate = Machine" -out "RequesterName,CommonName,NotAfter,Email"

    Or do I have to seperate them into 2 different queries?

  2. Anonymous says:

    I had a need, as a Windows domain System’s Administrator, to determine when the many certificates my users use would expire.

    All those certificates are stored in a secured location as password-less PFX files and also include the certificate private key. We have something like 800 active different PFX files at any given time.

    I decided the best way would be to make sure the expiration date was part of the file name, so I wrote this hack of a script which I share just in case anyone has the same needs I had:


    @echo off


    REM Note: you need to get the "Cview.vbs" script from the "Microsoft CAPICOM SDK" to

    REM be able to use this script. Put it in the same directory as this script. You also have to

    REM register (regsvr32.exe) the "capicom.dll" included in that SDK for this script to work.


    REM Note 2: you also need a basic installation of Cygwin, or otherwise access to Windows builds

    REM of the UNIX commands "grep" and "awk".

    *********************** Start of user configurable variables ****************************

    set certs-dir=c:my-secure-PFX-location


    REM In case we are in a x64 system, we must provide the location of the 32 bits version of "cscript.exe"

    REM (In Windows x86 that is "c:WINDOWSsystem32", while in Windows x64 that is "c:WINDOWSSysWOW64".)

    set path32=c:WINDOWSSystem32


    REM The path to "grep" and "awk" for Windows:

    set cygwin-path=c:usrcygwinbin


    REM We must here inform with wich character are the elements of the Windows "short day format" separated,

    REM usually it’s either "/" or "-". You can check it issuing the command "date /t" in CMD.EXE.

    set separator=/


    REM ************************ End of user configurable variables *****************

    echo ————————————————-


    REM Here we check if a path was passed as parameter to our script. If that is the case, we work with

    REM the PFX files contained there, instead of whatever had been set in the "certs-dir" variable above.

    set non-default=no

    if "%1" == "" (echo Working on the default directory: "%certs-dir%" ) else (

    set certs-dir=%1

    set non-default=yes)

    if not exist %certs-dir% goto _error-directory

    if %non-default% == yes (echo Working on the manually specified directory: "%certs-dir%")

    echo ————————————————-

    REM Let’s go! We avoid processing PFX files whose name already begins with "20*" as those probably are already proccessed.

    for /f "usebackq delims=:" %%i in (`"dir /b "%certs-dir%*.pfx" | %cygwin-path%grep -v "^^20*""`) do ( echo Now processing: "%%i"

    for /f "usebackq delims=:" %%z in (`"%path32%cscript Cview.vbs "%certs-dir%%%i" | %cygwin-path%grep "Not After:" | %cygwin-path%gawk-3.1.5 ‘{print $3}’ | %cygwin-path%gawk-3.1.5 –field-separator ‘%separator%’ ‘{print $3 "-" $2 "-" $1}’"`) do (

    echo Expiration date of "%%i" is "%%z"

    move "%certs-dir%%%i" "%certs-dir%%%z_%%i"

    echo New certificate name: "%%z_%%i"

    echo ————————————————-



    goto _end


    echo The working directory does not exist. Aborting script…

    goto _end


    echo END OF SCRIPT.


  3. Anonymous says:

    A while ago I explained how to determine all certificates that will expire within a given period. Now

  4. Anonymous says:

    Pingback from certificate – Certutil -restrict Error The component can’t find a record specified | Zap Video

  5. jim says:

    The parameter is incorrect

  6. jim says:

    The certutil command does not work

  7. Jason says:

    Jim, I hit the same snag. Use this date format 5/5/2015

  8. Danish says:

    Does this works fine on server 2012 R2?

Comments are closed.

Skip to main content