Sent to Jim who kindly tested. Quick PS Stdout query to access certficates with future expiration date.  Default prompt is for 360 days from current date. If you enter 0 it will show all previous expired certificates. It queries the entire store, not just the \my user certs. Very fast and pulls up results as .csv
;Display Expiring Certificates
;save as ..\Certs.wbt
;Stan Littlefield 7/25/2025
;==========================================================
Gosub udfs
default = 360
expires = AskLine("Certificates", "Enter Number of days before Certificates may expires", default, 0)
Now=TimeYmdHms( )
AddTime = "0000:00:":expires:":00:00:00" 
Later=TimeAdd(Now, AddTime)
expdate = TimeFormat(Later,"yyyyMMdd")
certs = Dirscript():"\CertificatesExpiringBY_":expdate:".csv"
;==========================================================
If FileExist(certs) Then FileDelete(certs)
args = $"
dir Cert:: -Recurse -ExpiringInDays [exp] | sort NotAfter | 
Select-Object @{Name='Expires';Expression = {$_.NotAfter}},
@{Name='Subject';Expression = {$_.SubjectName}},
@{Name='Path';Expression={Join-Path -Path "Cert::" -childPath (Convert-Path $_.PSPath)}},
@{Name='Computername';Expression = {$Env::COMPUTERNAME}} |
ConvertTo-Csv -NoTypeInformation 
$"
args = StrReplace(args,"[exp]",expires)
args = StrReplace(args,"[file]",certs)
cmd="Powershell"
msg='Expiring Certificates'
BoxOpen("Running...",msg:" ":args:@LF:"PLEASE WAIT...MAY TAKE SOME TIME")
TimeDelay(2)
vals = Get_stdout() 
vals = strreplace(vals,'"','')                         
fileput(certs,vals)
Display(2,msg,"Script Completed")  
If FileExist(certs) Then Run("notepad.exe",certs)
Exit
;==========================================================
:udfs
#DefineSubroutine Get_stdout()
ObjectClrOption("useany","System")
objInfo = ObjectClrNew("System.Diagnostics.ProcessStartInfo")
Output=""
timeOut = ObjectType("I2",5000)
objInfo.FileName = cmd
objInfo.RedirectStandardError = ObjectType("BOOL",@TRUE)
objInfo.RedirectStandardOutput = ObjectType("BOOL",@TRUE)
objInfo.UseShellExecute = ObjectType("BOOL",@FALSE)
objInfo.CreateNoWindow = ObjectType("BOOL",@TRUE)
objInfo.Arguments = args
oProcess = ObjectClrNew("System.Diagnostics.Process")
oProcess.StartInfo = objInfo
BoxShut()
oProcess.Start()
oProcess.WaitForExit(timeout)
STDOUT = oProcess.StandardOutput.ReadToEnd()
STDERR = oProcess.StandardError.ReadToEnd()
Output = Output:STDOUT:@CRLF
If STDERR<>""
   Output = Output:"STDERR:":STDERR:@CRLF
Endif
oProcess = 0
objInfo = 0
Return (Output)
#EndSubroutine
Return
;==========================================================
			
			
			
				Here is a snippet from a simple script I use to check personal certificates. It is not nearly as complete as the script above, but it does serve my needs.
objStore = CreateObject("CAPICOM.Store")
objStore.Open(2, "my", 0)
ForEach objCert In objStore.Certificates
    If objCert.ValidToDate < TimeAdd(TimeYmdHms( ), '0000:00:30:00:00:00')
        Message( "Certificate " : objCert.SubjectName , " expires on " : objCert.ValidToDate )
    EndIf
Next
objStore.Close
exit
			
			
			
				Nice
[EDIT] I may be wrong but Capicom is 32-bit, and although it will run on 64-bit machines, there are more robust 64-bit alternatives.
			
			
			
				and for the nth time, my intention with scripts referencing PS is not a PS vs. WB mantra, but to illustrate how WB might use PS as a pseudo-extender. I think the StdOut function is quite versatile. Take the script I posted, change certs = Dirscript():"\CertificatesExpiringBY_":expdate:".csv" from csv to txt, and in the args scriptblock replace 
ConvertTo-Csv -NoTypeInformation   with Format-List and you have perhaps a more readable output.
One could easily create a StdOut utility for WB with a script that accesses a small recordset of directions for arguments, replacements and output... executed from a simple AskItemList
			
			
			
				Whatever.