{"id":68843,"date":"2005-09-30T14:36:00","date_gmt":"2005-09-30T14:36:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/09\/30\/how-can-i-determine-if-a-particular-patch-is-installed\/"},"modified":"2005-09-30T14:36:00","modified_gmt":"2005-09-30T14:36:00","slug":"how-can-i-determine-if-a-particular-patch-is-installed","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-determine-if-a-particular-patch-is-installed\/","title":{"rendered":"How Can I Determine if a Particular Patch is Installed?"},"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 use a script to determine if a particular patch has been installed?<BR><BR>&#8212; GM<\/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, GM. You know, not too long ago this would have been a question we might have \u201caccidentally\u201d dropped in the wastebasket and pretended never to have seen. Why? Well, back in the old days the only way to get information about patches, hot fixes, and other updates was to use the WMI class Win32_QuickFixEngineering. That was OK, but for various reasons Win32_QuickFixEngineering would occasionally miss a patch that really <I>was<\/I> installed; even worse, on Windows 2000 machines Win32_QuickFixEngineering would sometimes hang and not return <I>any<\/I> information. (How do you fix that problem? By installing a patch, of course.) Not a pretty picture by any means.<\/P>\n<P>But those days are gone. Now, thanks to the new and very-much improved Windows Update service, it\u2019s very easy to determine which updates have and have not been installed on a computer. For example, here\u2019s a script that tells us whether the patch <I>Security Update for Windows XP (KB899587) <\/I>has been installed on a computer:<\/P><PRE class=\"codeSample\">Set objSession = CreateObject(&#8220;Microsoft.Update.Session&#8221;)\nSet objSearcher = objSession.CreateUpdateSearcher\nSet objResults = objSearcher.Search(&#8220;Type=&#8217;Software'&#8221;)\nSet colUpdates = objResults.Updates<\/p>\n<p>For i = 0 to colUpdates.Count &#8211; 1\n    If colUpdates.Item(i).Title = _\n        &#8220;Security Update for Windows XP (KB899587)&#8221; Then\n        If colUpdates.Item(i).IsInstalled &lt;&gt; 0 Then\n            Wscript.Echo &#8220;This update is installed.&#8221;\n            Wscript.Quit\n        Else\n            Wscript.Echo &#8220;This update is not installed.&#8221;\n            Wscript.Quit\n        End If\n    End If\nNext<\/p>\n<p>Wscript.Echo &#8220;This update is not installed.&#8221;\n<\/PRE>\n<P>We won\u2019t go through each line of code in detail; explaining the ins and outs of the Windows Update service goes a bit beyond the scope of this column. If you\u2019d like more information about Windows Update (and, in particular, objects like <B>Microsoft.Update.Session<\/B>) please see our <I>Tales from the Script<\/I> column <A href=\"http:\/\/null\/technet\/scriptcenter\/resources\/tales\/sg0705.mspx\"><B>I\u2019ll Get You, My Pretty\u2026And We\u2019ll Manage Windows Update, Too!<\/B><\/A><\/P>\n<P>We will note, however, that despite the presence of the <B>Search<\/B> method we aren\u2019t really <I>searching<\/I> for a particular update. Searching implies going out and, with pinpoint accuracy, locating <I>just<\/I> the item of interest. We can\u2019t really do that. Instead, what we\u2019re doing here is returning a collection of <I>all<\/I> the updates and then sifting through that entire collection, looking for an update with the title <I>Security Update for Windows XP (KB899587)<\/I>. The end result is the same, but the process by which we achieve that end result is a little different.<\/P>\n<P>No, that doesn\u2019t make any difference. Just thought you\u2019d like to know.<\/P>\n<P>So what <I>is<\/I> the process we employ here? Well, we begin by using these four lines of code to retrieve the updates collection for the local computer:<\/P><PRE class=\"codeSample\">Set objSession = CreateObject(&#8220;Microsoft.Update.Session&#8221;)\nSet objSearcher = objSession.CreateUpdateSearcherSet \nobjResults = objSearcher.Search(&#8220;Type=&#8217;Software'&#8221;)\nSet colUpdates = objResults.Updates\n<\/PRE>\n<TABLE id=\"EKE\" 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>. Yes, this script can be run against a remote computer. For more information, see the <A href=\"http:\/\/null\/technet\/scriptcenter\/resources\/tales\/sg0705.mspx\"><B><I>Tales from the Script<\/I><\/B><\/A> column.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After retrieving the collection we set up a For Next loop to walk through all the items. Inside that loop we use this line of code to determine whether the update <B>Title<\/B> is equal to <I>Security Update for Windows XP (KB899587)<\/I>:<\/P><PRE class=\"codeSample\">If colUpdates.Item(i).Title = _\n    &#8220;Security Update for Windows XP (KB899587)&#8221; Then\n<\/PRE>\n<P>Let\u2019s suppose that the Title <I>is<\/I> equal to <I>Security Update for Windows XP (KB899587)<\/I>. In that case, we next check the value of the <B>IsInstalled<\/B> property. If IsInstalled is equal to 0, then the update is not actually installed (installation might have failed, or the update might have been installed but then removed). If IsInstalled does <I>not<\/I> equal 0, then the update is installed. We check the value, and then echo the appropriate message:<\/P><PRE class=\"codeSample\">If colUpdates.Item(i).IsInstalled &lt;&gt; 0 Then\n    Wscript.Echo &#8220;This update is installed.&#8221;\n    Wscript.Quit\nElse\n    Wscript.Echo &#8220;This update is not installed.&#8221;\n    Wscript.Quit\nEnd If\n<\/PRE>\n<P>You might notice that, after echoing our message, we terminate the script. Why? Well, update titles are unique: now that we\u2019ve found the update in question there\u2019s no need to continue walking through the rest of the collection. Therefore, we might as well terminate the script and get on with our lives.<\/P>\n<P>And what if the Title <I>isn\u2019t<\/I> equal to <I>Security Update for Windows XP (KB899587)<\/I>? In that case we simply loop around and check the next item in the collection. If we never <I>do<\/I> find an update with the specified title we\u2019ll eventually exit the loop, and then execute the last line of code, which simply reports that the update is not installed.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I use a script to determine if a particular patch has been installed?&#8212; GM Hey, GM. You know, not too long ago this would have been a question we might have \u201caccidentally\u201d dropped in the wastebasket and pretended never to have seen. Why? Well, back in the old days the [&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-68843","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 use a script to determine if a particular patch has been installed?&#8212; GM Hey, GM. You know, not too long ago this would have been a question we might have \u201caccidentally\u201d dropped in the wastebasket and pretended never to have seen. Why? Well, back in the old days the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68843","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=68843"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68843\/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=68843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=68843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=68843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}