- Allow non-admins to access Remote Desktop - Thu, Sep 28 2023
- Which WSUS products to select for Windows 11? - Tue, Sep 26 2023
- Activate BitLocker with manage-bde, PowerShell, or WMI - Wed, Sep 20 2023
For web servers that are accessible via the public Internet, there are numerous online services that can check at regular intervals when certificates expire and then notify the webmaster in good time. In the company network, many monitoring tools can take over this task.
If you are limited to the onboard tools for this purpose, you can use PowerShell. With the help of a relatively simple script, all servers can be scanned for certificates that will soon reach their expiration date.
Retrieving all servers from the AD
The following example reads all computers running Windows Server from Active Directory and remotely accesses their certificate store under LocalMachinemy. It displays all certificates that expire in less than 14 days or that have already expired.
To prevent the script from hanging when a server is not reachable, the Test-Connection cmdlet checks whether the target host is online.
$cred = Get-Credential $c = 0 $servers = Get-ADComputer -Filter "OperatingSystem -like 'Windows Server*'" $servers | foreach{ $p = ($c++/$servers.count) * 100 Write-Progress -Activity "Checking $_" -Status "$p % completed" -PercentComplete $p; if(Test-Connection -ComputerName $_.DNSHostName -Count 2 -Quiet){ Invoke-Command -ComputerName $_.DNSHostName -Credential $cred ` {dir Cert:\LocalMachine\my | ? NotAfter -lt (Get-Date).AddDays(14)} } }
If necessary, you could restrict the list of servers by specifying certain OUs with the SearchBase parameter; alternatively, you could read them from a text file.
Subscribe to 4sysops newsletter!
Conclusion
The script is intended for interactive execution and shows the progress of the operation with Write-Progress. You could, of course, also customize it to run as a Scheduled Task and be notified by email if a certificate is about to expire.
This is great!
BTW Script fails with errors looking for
Cert:LocalMachinemy
Your screenshot is slightly different from the script you posted
Cert:LocalMachine\my
Fred, thanks for the hint! We fixed this now.
Do we have to run the above script on AD server or we have to run this Script on all the servers individually ?
You can run the script from any workstation with the PowerShell AD module installed.
Hi Wolfgang,
any chance to get the certs FriendlyName instead of the ThumbPrint?
Thanks
Hi Wolfgang
Thanks for the script. It's awesome!
Thanks
B.R
Ziv
Hi Wolfgang
As always interresting post, some comments that i would like to be constructive
Why these proposal ? your readers are not all powershell experts, but a wider audience. Aliases are fine when passing a command line, but it is not recommended to use them in scripts. Naming parameter is recommended by the best practices. One-liner code is not always appropriate to debug. Correct formating makes the code more readable and understandable.
then the code should be :
Get-ChildItem -Path Cert:\LocalMachine\my |
Select-Object -Property friendlyName, Thumbprint, Subject, NotAfter |
Where-Object -Property NotAfter -LT (get-date).AddDays(-14)
@Florian Brune : to meet your need, I've added the property FriendlyName to the output. Feel free to add/remove the properties you would like or not.
regards
Olivier
This is a great script, but how can I get this to output all the expired or expiring certs to a text file or something like that?
Hi Tony,
Look the line $servers| foreach …
Just before this add $Output =
By this way the output of the foreach loop, will be store in the var $Output
After that just call $output and use the pipeline to export in a file with the file type you would like.
i.e. : $Output | Out-File -FilePath or better (for a later use) Export-Csv -Path
Of course you could also export in another type of files (.json, .html. .xml, .xlsx, .docx, .pdf and event more). Some file types with native cmdlets and some toher with additional Powershell modules.
Hope this help you.
Regards
Very useful!
I am creating a script to generate the expiring certificates and email them to our it department.
I am creating a new user for this however, I have not figured out how to set the user up to run this script without making them a domain administrator.
Any suggestions?
This works great for Personal certs on local computer.
Is there a way to modify this script or a different method (Via a tool or PowerShell) to list all certificates (Personal, trusted root ca,…. ) that are expiring on the local computer?
Thanks,
George
Hi Gene;
Sure there is a way to do that.
$AllCertContainers = Get-ChildItem -Path Cert:\LocalMachine
$ExpiringCerts = foreach ($item in $AllCertContainers)
{
Get-ChildItem -Path Cert:\LocalMachine\$($item.Name) |
Select-Object -Property friendlyName, Thumbprint, Subject, NotAfter |
Where-Object -Property NotAfter -LT (Get-date).AddDays(-14)
}
$ExpiringCerts | Out-GridView
$ExpiringCerts | Format-List
$ExpiringCerts | Format-Table # or whatever
Regards