{"id":69103,"date":"2005-08-24T16:57:00","date_gmt":"2005-08-24T16:57:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/08\/24\/how-can-i-determine-when-the-last-patch-from-windows-update-was-applied\/"},"modified":"2005-08-24T16:57:00","modified_gmt":"2005-08-24T16:57:00","slug":"how-can-i-determine-when-the-last-patch-from-windows-update-was-applied","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-determine-when-the-last-patch-from-windows-update-was-applied\/","title":{"rendered":"How Can I Determine When the Last Patch From Windows Update was Applied?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I determine when the last patch from Windows Update was applied?<BR><BR>&#8212; JP<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, JP. You know, you picked a good time to ask this question; that\u2019s because we just published a <A href=\"http:\/\/technet.microsoft.com\/en-us\/library\/ee692834.aspx\"><B>Tales from the Script<\/B><\/A> column that introduces scripters to the Windows Update object model, and provides a number of sample scripts for managing Automatic Updates. And while the article doesn\u2019t have a script that returns information for just the last update applied to a computer, well, it was easy enough to come up with one:<\/P><PRE class=\"codeSample\">Set objSession = CreateObject(&#8220;Microsoft.Update.Session&#8221;)\nSet objSearcher = objSession.CreateUpdateSearcher<\/p>\n<p>Set colHistory = objSearcher.QueryHistory(0, 1)<\/p>\n<p>For Each objEntry in colHistory\n    Wscript.Echo &#8220;Title: &#8221; &amp; objEntry.Title\n    Wscript.Echo &#8220;Update application date: &#8221; &amp; objEntry.Date\nNext\n<\/PRE>\n<P>What\u2019s going on in this little script? Funny you should ask: we were just about to explain that. We begin by creating an instance of the <B>Microsoft.Update.Session<\/B> object. Once we have that object in hand we can call the <B>CreateUpdateSearcher <\/B>method. This gives us an instance of the Searcher object, an object that enables us to search through all the updates that have been applied to a computer. Which is exactly the thing we want to do.<\/P>\n<P>Next we use the <B>QueryHistory<\/B> method to retrieve the desired updates:<\/P><PRE class=\"codeSample\">Set colHistory = objSearcher.QueryHistory(0, 1)\n<\/PRE>\n<P>As you can see, in this script we pass QueryHistory two parameters:&nbsp;0 and 1. The&nbsp;0 tells the script to begin its search with record&nbsp;0 in the update history; the 1 tells the script to stop its search after record 1. (That is, before it gets to record 2.) Why do we do that? Well, updates are stored in reverse chronological order, with the most recent update being record 0 and the very first update ever applied being the last record in the collection. Because we want information about only the most recent update, we can make the script run a tad bit faster by limiting the returned data to just that one record. <\/P>\n<TABLE id=\"EPD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. We should point out that it\u2019s very easy to retrieve the complete update history for a computer; in fact, the <A href=\"http:\/\/technet.microsoft.com\/en-us\/library\/ee692834.aspx\"><B>Tales from the Script<\/B><\/A> column includes a script that does just that.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After calling the QueryHistory method we\u2019ll get back a collection (named colHistory) consisting of a single item, an item which just happens to represent the last update that was applied to the computer. All that\u2019s left now is to walk through that collection (and, yes, technically it\u2019s still a collection even though it contains just one item) and echo the title of the update and the date the update was applied:<\/P><PRE class=\"codeSample\">For Each objEntry in colHistory\n    Wscript.Echo &#8220;Title: &#8221; &amp; objEntry.Title\n    Wscript.Echo &#8220;Update application date: &#8221; &amp; objEntry.Date\nNext\n<\/PRE>\n<P>In other words, tell us the last time Windows Update did something to this particular computer.<\/P>\n<P>Incidentally, the Windows Update object model is a mixed-bag: some of the objects can be created on &#8211; and thus used against &#8211; remote computers while others can\u2019t. Fortunately, this happens to be a script that <I>will<\/I> run against a remote machine. To do that you simply need to add the remote computer name as the second parameter to CreateObject. For example, this line of code causes the script to run against the remote computer atl-dc-01:<\/P><PRE class=\"codeSample\">Set objSession = CreateObject(&#8220;Microsoft.Update.Session&#8221;, &#8220;atl-dc-01&#8221;)\n<\/PRE>\n<P>And the complete script for retrieving the last update from atl-dc-01 would thus look like this:<\/P><PRE class=\"codeSample\">Set objSession = CreateObject(&#8220;Microsoft.Update.Session&#8221;, &#8220;atl-dc-01&#8221;)\nSet objSearcher = objSession.CreateUpdateSearcher<\/p>\n<p>Set colHistory = objSearcher.QueryHistory(1, 1)<\/p>\n<p>For Each objEntry in colHistory\n    Wscript.Echo &#8220;Title: &#8221; &amp; objEntry.Title\n    Wscript.Echo &#8220;Update application date: &#8221; &amp; objEntry.Date\nNext\n<\/PRE>\n<P>And people think that patch management is hard. Not anymore! <\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I determine when the last patch from Windows Update was applied?&#8212; JP Hey, JP. You know, you picked a good time to ask this question; that\u2019s because we just published a Tales from the Script column that introduces scripters to the Windows Update object model, and provides a number of [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[36,3,5,380],"class_list":["post-69103","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-client-side-management","tag-scripting-guy","tag-vbscript","tag-windows-update"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I determine when the last patch from Windows Update was applied?&#8212; JP Hey, JP. You know, you picked a good time to ask this question; that\u2019s because we just published a Tales from the Script column that introduces scripters to the Windows Update object model, and provides a number of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/69103","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=69103"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/69103\/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=69103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=69103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=69103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}