{"id":4067,"date":"2013-03-05T00:01:00","date_gmt":"2013-03-05T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/03\/05\/use-powershell-to-find-certificates-that-are-about-to-expire\/"},"modified":"2013-03-05T00:01:00","modified_gmt":"2013-03-05T00:01:00","slug":"use-powershell-to-find-certificates-that-are-about-to-expire","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-find-certificates-that-are-about-to-expire\/","title":{"rendered":"Use PowerShell to Find Certificates that are About to Expire"},"content":{"rendered":"<p><strong>Summary<\/strong>: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to find certificates that are about to expire.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>&nbsp;Hey, Scripting Guy! We recently implemented an internal certification authority that we use for various scenarios, such as issuing code-signing certificates for our developers and certain admins as well as for user authentication scenarios. Now, of course, we have a problem. My pointy headed boss is worried that people with certificates will not renew them properly, so he wants me to write a script that can find out when scripts are about to expire. Is this something that I can do easily?<\/p>\n<p>&mdash;AR<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>&nbsp;Hello AR,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Today is Tuesday, and the Scripting Wife and I are on the road for a bit. Luckily, Windows 8 phone easily sets up as a modem, and I can connect to the Internet with my laptop and check my email at scripter@microsoft.com. It is cool. The bad thing about a road trip is that it is nearly impossible to get a decent cup of tea. I made a pot before we left, so I have some decent tea&mdash;at least for a little while.<\/p>\n<p>AR, dude, this is so easy&hellip;<\/p>\n<p>The reason it is so easy to find certificates that are about to expire in Windows PowerShell 3.0 is because we add a dynamic parameter to the <strong>Get-ChildItem<\/strong> cmdlet when the cmdlet targets the Cert: PSDrive. The dynamic parameter is called <strong>&ndash;ExpiringInDays<\/strong><em> <\/em>and it does exactly what you might think it would do&mdash; it reports certificates that are going to expire within a certain time frame. To find certificates that will expire within 75 days, use the command shown here.<\/p>\n<p style=\"padding-left: 30px\">Get-ChildItem -Path cert: -Recurse -ExpiringInDays 75<\/p>\n<p>The command and the output associated with the command to find certificates that expire in 75 days are shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5164.HSG-3-5-13-01.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5164.HSG-3-5-13-01.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>I do not have to set my working location to the Cert: PSDrive, because I can specify it as the path of the <strong>Get-ChildItem<\/strong> cmdlet. If I need to perform more than one or two operations, I will change my working location to the Cert: PSDrive to simplify some of the typing requirements. To change to the Cert: PSDrive, I use the <strong>Set-Location<\/strong> cmdlet (<strong>SL<\/strong> is an alias, as is <strong>CS<\/strong>). This technique is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; sl cert:<\/p>\n<p>After I have changed my working location to the Cert: PSDrive, the Windows PowerShell prompt (by default) changes to include the Cert: drive location as shown here.<\/p>\n<p style=\"padding-left: 30px\">PS Cert:\\&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<h2>Finding about to expire certificates the PowerShell 2.0 way<\/h2>\n<p>If you are using Windows PowerShell 2.0 (or if you just like to type), you can still find certificates that are about to expire by using the <strong>Get-ChildItem<\/strong> cmdlet on your Cert: PSDrive, and then piping the results to the <strong>Where-Object<\/strong>. You need to filter on the <strong>NotAfter <\/strong>property of the returned certificate object. The great thing is that Windows PowerShell makes it easy to work with dates. I use the <strong>AddDays<\/strong> method from the <strong>DateTime <\/strong>object that is returned by the <strong>Get-Date<\/strong> cmdlet.<\/p>\n<p>To gain access to the <strong>AddDays<\/strong> method, I group the <strong>Get-Date<\/strong> cmdlet first. Each certificate object crosses the pipeline to the <strong>Where-Object<\/strong> cmdlet. Inside the script block for the <strong>Where-Object<\/strong>, I look at the <strong>NotAfter <\/strong>property, and I check to see if it is less than a date that is 75 days in the future. Upon finding the certificates that have an expiration date of less than 75 days in the future, I send the results to the <strong>Select-Object<\/strong> cmdlet, where I choose the thumbprint and the subject. The following command returns certificates that have an expiration date that is before 75 days in the future.<\/p>\n<p style=\"padding-left: 30px\">Get-ChildItem -Recurse | where { $_.notafter -le (get-date).AddDays(75) } | select thumbprint, subject<\/p>\n<p>When I run the command, the results do not compare very well with those from the previous command. The command and its resulting output are shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1018.HSG-3-5-13-02.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1018.HSG-3-5-13-02.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>The reason the output is different is because the new <strong>ExpiringInDays<\/strong><em> <\/em>parameter for Windows PowerShell 3.0 does not include already expired certificates. Windows ships with expired certificates because certain executables that have been signed with a certificate, but have not been resigned with a new certificate, need the old certificate to ensure the validity of the certificate.<\/p>\n<p>By modifying the command so it also filters out expired certificates, the results on my computer become the same. Here is the revised command.<\/p>\n<p style=\"padding-left: 30px\">Get-ChildItem -Recurse | where { $_.notafter -le (get-date).AddDays(75) -AND $_.notafter -gt (get-date)} | select thumbprint, subject<\/p>\n<p>The command and the output associated with the command are shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0160.HSG-3-5-13-03.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0160.HSG-3-5-13-03.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>AR, that is all there is to using the certificate provider in Windows PowerShell to find certificates that will expire in a certain time frame. Join me tomorrow when I will talk about more cool stuff.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to find certificates that are about to expire. &nbsp;Hey, Scripting Guy! We recently implemented an internal certification authority that we use for various scenarios, such as issuing code-signing certificates for our developers and certain admins as well as for user authentication scenarios. Now, of [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[217,3,63,45],"class_list":["post-4067","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-certificates","tag-scripting-guy","tag-security","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to find certificates that are about to expire. &nbsp;Hey, Scripting Guy! We recently implemented an internal certification authority that we use for various scenarios, such as issuing code-signing certificates for our developers and certain admins as well as for user authentication scenarios. Now, of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4067","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=4067"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4067\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=4067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=4067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=4067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}