{"id":52493,"date":"2009-09-10T03:01:00","date_gmt":"2009-09-10T03:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/09\/10\/hey-scripting-guy-can-i-determine-which-servers-have-specific-hotfixes-installed\/"},"modified":"2009-09-10T03:01:00","modified_gmt":"2009-09-10T03:01:00","slug":"hey-scripting-guy-can-i-determine-which-servers-have-specific-hotfixes-installed","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-can-i-determine-which-servers-have-specific-hotfixes-installed\/","title":{"rendered":"Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?"},"content":{"rendered":"<p><span class=\"sbmLink\">   <\/p>\n<table cellspacing=\"1\" cellpadding=\"1\">\n<tbody>\n<tr>\n<td class=\"sbmText\">Share this post: <\/td>\n<td><a title=\"Post it to Backflip!\" href=\"http:\/\/www.backflip.com\/add_page_pop.ihtml?url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/backflip4.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Buddymark!\" href=\"http:\/\/buddymarks.com\/s_add_bookmark.php?bookmark_url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;bookmark_title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/buddymar4.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Del.icio.us!\" href=\"http:\/\/del.icio.us\/post?url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/deliciou4.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Digg!\" href=\"http:\/\/digg.com\/submit?phase=2&amp;url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/digg14.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Facebook!\" href=\"http:\/\/www.facebook.com\/sharer.php?u=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;t=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/telligent.evolution.components.attachments\/13\/4982\/00\/00\/01\/76\/53\/19\/facebook.JPG\" \/><\/a><\/td>\n<td><a title=\"Post it to Furl!\" href=\"http:\/\/www.furl.net\/store?s=f&amp;to=0&amp;u=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;ti=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/furl4.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Netvouz!\" href=\"http:\/\/netvouz.com\/action\/submitBookmark?url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/netvouz4.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Reddit!\" href=\"http:\/\/reddit.com\/submit?url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/reddit4.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Spurl!\" href=\"http:\/\/www.spurl.net\/spurl.php?v=3&amp;url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/spurl8.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Technorati!\" href=\"http:\/\/technorati.com\/faves\/?add=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/technora4.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Wists!\" href=\"http:\/\/www.wists.com\/?action=add&amp;url=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;title=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/wists9.png\" \/><\/a><\/td>\n<td><a title=\"Post it to Yahoo!\" href=\"http:\/\/myweb.yahoo.com\/myresults\/bookmarklet?u=http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/09\/10\/hey-scripting-guy-september-10-2009.aspx&amp;t=Hey, Scripting Guy! Can I Determine Which Servers Have Specific Hotfixes Installed?\" target=\"_blank\"><img decoding=\"async\" border=\"0\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/yahoo9.png\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p> <\/span>  <\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\"><img decoding=\"async\" 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\" \/><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">Hey, Scripting Guy! I have a text file that contains a number of computer names. I would like to read that text file, query each computer in the list, and find out the status of a particular hotfix. If I could write the information to a text file, it would be even better. Here is the deal; there was a recent security update that was released. My boss came in and asked me if that update had been applied to each of our 200 servers. I told him I was pretty sure it had, but he wanted a report he could turn in.   <\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">I really do not have time to go around to 200 different servers to do this. It would be great if the script was written in such a way that the hotfix could be supplied from the command line. In this way, the script would work kind of like a utility. Do you have time to help me out?   <\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">&#8212; JH   <\/p>\n<p><span><img decoding=\"async\" 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\" \/><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">Hello JH, <\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. This morning, I am feeling kind of mellow. I am listening to <a href=\"http:\/\/en.wikipedia.org\/wiki\/Vanessa-Mae\"><font face=\"Segoe\">Vanessa-Mae<\/font><\/a> on my Zune, sipping a cup of green tea with cinnamon stick and lemon grass, and trolling through the <a href=\"http:\/\/social.technet.microsoft.com\/Forums\/en\/ITCG\/threads\/\">Official Scripting Guys Forum!<\/a> It seems that I answered a question similar to yours recently. In fact, I even <a href=\"http:\/\/gallery.technet.microsoft.com\/ScriptCenter\/en-us\/479d4a4e-b06b-4464-94b2-5a61af14d82b\"><font face=\"Segoe\">wrote a script and posted it<\/font><\/a> on the <a href=\"http:\/\/gallery.technet.microsoft.com\/ScriptCenter\/en-us\">TechNet Script Center Gallery<\/a>. Let me dig it up, and let&#8217;s take a look at it.     <\/p>\n<p style=\"margin: 15pt 12pt 0.25in 0in\" class=\"Readeraidonly\">This week we are looking at questions that have been posted on the <a href=\"http:\/\/bit.ly\/2h50Tk\">Official Scripting Guys Forum<\/a>. This user forum is a great place to ask questions related to VBScript or Windows PowerShell. It is also an excellent resource to learn scripting by either reading answers to others questions or by becoming involved in discussions through posting answers. In addition to being a learning resource, the forum is also a fun place to interact with people from around the world who have an interest in scripting. Bonus: The Official Scripting Guys Forum is free. If you wish to post a question or propose an answer to a question, you will need to log in with your <a href=\"http:\/\/bit.ly\/wI4Nj\">Windows Live ID<\/a>.    <\/p>\n<p style=\"margin: 15pt 12pt 0pt 0in\" class=\"CodeBlockScreenedHead\"><strong>GetHotFixReport.ps1     <\/p>\n<p>   <\/strong><\/p>\n<p style=\"margin: 15pt 17.3pt 0.25in 0in\" class=\"CodeBlockScreened\"><span style=\"font-size: 9.5pt\"><font style=\"background-color: #d9d9d9\"><font face=\"Lucida Sans Typewriter\">Param(         <br \/><span>&#160; <\/span>[String[]]$hotFix = @(&quot;KB973815&quot;, &quot;KB952286&quot;),          <br \/><span>&#160; <\/span>[string[]]$computer = (get-content -path c:\\fso\\servers.txt),          <br \/><span>&#160; <\/span>[string]$filepath = &quot;C:\\fso\\hotfx.txt&quot;,          <br \/><span>&#160; <\/span>[switch]$logToFile          <br \/>) #end Param          <\/p>\n<p>Function Get-HotFixStatus([string]$hotFix, [string]$computer)          <br \/>{          <br \/><span>&#160; <\/span>Get-WmiObject -class<span>&#160; <\/span>win32_QuickFixEngineering `          <br \/><span>&#160; <\/span>-Filter &quot;HotFixID = &#8216;$hotfix&#8217;&quot; -computername $computer          <br \/>} #end function Get-HotFixStatus          <\/p>\n<p>Function Get-HotFixReport([string[]]$hotFix, [string[]]$computer)          <br \/>{          <br \/><span>&#160; <\/span>foreach($c in $computer)          <br \/><span>&#160; <\/span>{          <br \/><span>&#160;&#160;&#160; <\/span>foreach ($h in $hotfix)          <br \/><span>&#160;&#160;&#160; <\/span>{          <br \/><span>&#160;&#160;&#160;&#160; <\/span>$status =<span>&#160; <\/span>$(if(Get-HotFixStatus -hotfix $h -computer $c) {$true} else {$false})          <br \/><span>&#160;&#160;&#160;&#160; <\/span>$object = New-Object -TypeName PSObject          <br \/><span>&#160;&#160;&#160;&#160; <\/span>$object | Add-Member -MemberType NoteProperty -Name Computer `          <br \/><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span>-Value $c          <br \/><span>&#160;&#160;&#160;&#160; <\/span>$object | Add-Member -MemberType NoteProperty<span>&#160; <\/span>-Name HotFix `          <br \/><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span>-Value $h          <br \/><span>&#160;&#160;&#160;&#160; <\/span>$object | Add-Member -MemberType NoteProperty -Name Installed `          <br \/><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span>-Value $status          <br \/><span>&#160;&#160;&#160; <\/span>$object          <br \/><span>&#160; <\/span><span>&#160; <\/span>} #end foreach hotfix          <br \/><span>&#160;&#160; <\/span>} #end foreach computer          <br \/>} #end function Get-FixReport          <\/p>\n<p>Function Out-HotFixLog ([string]$filepath)          <br \/>{          <br \/><span>&#160;<\/span>&quot;Hot Fix Report $(Get-Date)&quot; | Out-File -filepath $filepath -append          <br \/><span>&#160;<\/span>Get-HotFixReport -hotfix $hotfix -computer $computer |           <br \/><span>&#160;<\/span>Sort-object -property hotfix |           <br \/><span>&#160;<\/span>Out-File -filepath $filepath -append          <br \/>} #end function Out-HotFixLog          <\/p>\n<p># *** Entry Point to Script ***          <\/p>\n<p>&quot;Hot Fix Report $(Get-Date)&quot;          <br \/>Get-HotFixReport -hotfix $hotfix -computer $computer |           <br \/>Sort-object -property computer |           <br \/>Format-Table -Property * -autosize          <\/p>\n<p># write to text file          <br \/>if($logToFile) { Out-HotFixLog -filepath $filepath }          <\/p>\n<p>       <\/font><\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The first thing the GetHotFixReport.ps1 script does is create several command-line parameters. The first parameter <b>hotfix<\/b><i> <\/i>accepts an array of hotfix IDs. These hotfix IDs are the ones that will be checked on the different servers. Because it is likely that you would want to check for the presence of more than one hotfix, the <b>hotfix<\/b> parameter is configured to accept an array of strings. The <b>[string]<\/b> symbol is used to cast something to a string. When empty square brackets are added at the end, it becomes an array of strings: <b>[string[]]<\/b>. There are several ways to create an array in Windows PowerShell. The easiest is to just assign multiple values to a variable. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">PS C:\\&gt; $a = 1,2,3       <br \/>PS C:\\&gt; Foreach ($i in $a) {$i }        <br \/>1        <br \/>2        <br \/>3        <br \/>PS C:\\&gt;        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The problem with this approach is that each of the different command-line parameters must be separated by commas. To deal with the problem of the commas, we use the ampersand and a pair of parentheses to create an array:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">PS C:\\&gt; $b = @(1,2,3)       <br \/>PS C:\\&gt; Foreach ($i in $b) {$I }        <br \/>1        <br \/>2        <br \/>3        <br \/>PS C:\\&gt;        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The <b>computer<\/b> parameter is also cast as an array of strings. You can supply the computer names from the command line when calling the script or you can change the path to your text file of computer names. The <b>Get-Content<\/b> cmdlet is used to read the contents of the text file. Each computer name will need to reside on its own line, as seen here:    <\/p>\n<p style=\"margin: 9pt 0in 4pt\" class=\"Fig-Graphic\"><span>&#160;<\/span>    <\/p>\n<p style=\"margin: 4pt 0in 7pt\" class=\"CodeBlock\"><span><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-09-10-09-01_2.jpg\"><img decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" title=\"HSG-09-10-09-01\" border=\"0\" alt=\"HSG-09-10-09-01\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-09-10-09-01_thumb.jpg\" width=\"211\" height=\"230\" \/><\/a>       <\/p>\n<p>   <\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">If you want one, a text file can be created that will produce a status report for the specified hotfixes. The <b>filepath<\/b> parameter points to the location where the report will be stored, and the <b>logToFile<\/b> switched parameter is used to tell the script to generate the log file. The parameter section of the GetHotFixReport.ps1 script is seen here:     <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">Param(       <br \/><span>&#160; <\/span>[String[]]$hotFix = @(&quot;KB973815&quot;, &quot;KB952286&quot;),        <br \/><span>&#160; <\/span>[string[]]$computer = (get-content -path c:\\fso\\servers.txt),        <br \/><span>&#160; <\/span>[string]$filepath = &quot;C:\\fso\\hotfx.txt&quot;,        <br \/><span>&#160; <\/span>[switch]$logToFile        <br \/>) #end Param        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The <b>Get-HotFixStatus<\/b> function is used to determine the status of a hotfix that may or may not be installed on a computer. It accepts two parameters: the first is the <b>hotfix<\/b><i> <\/i>parameter, and the second is the <b>computer<\/b> parameter. The <b>Get-HotFixStatus<\/b> function is used to retrieve the status of a single hotfix from a single computer. To do this, the function uses the <b>Get-WmiObject<\/b> cmdlet to query the <b>Win32_QuickFixEngineering<\/b> WMI class. A filter is used to limit the hotfixes that are returned in response to the query to those whose value of the <b>hotfixid<\/b> property matches the value of the <b>hotfix<\/b><i> <\/i>parameter that is supplied when the <b>Get-HotFixStatus<\/b> function is called. The <b>computername<\/b> parameter of the <b>Get-WmiObject<\/b> cmdlet is used to tell WMI which computer to connect to. This is seen here:     <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">Function Get-HotFixStatus([string]$hotFix, [string]$computer)       <br \/>{        <br \/><span>&#160; <\/span>Get-WmiObject -class<span>&#160; <\/span>win32_QuickFixEngineering `        <br \/><span>&#160; <\/span>-Filter &quot;HotFixID = &#8216;$hotfix&#8217;&quot; -computername $computer        <br \/>} #end function Get-HotFixStatus        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The <b>Get-HotFixReport<\/b> function is used to query each of the computers for each of the hotfixes that are specified from the command line. To do this, two <b>foreach<\/b> statements are used. The first <b>foreach<\/b> statement walks through the array of computers, and the second <b>foreach<\/b> statement walks through the array of hotfixes. If the hotfix is present on the computer, the value of the <b>$status<\/b> variable is set to true. If the hotfix is not present on the computer, the value of the <b>$status<\/b> variable is set to false. This is seen here:     <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">Function Get-HotFixReport([string[]]$hotFix, [string[]]$computer)       <br \/>{        <br \/><span>&#160; <\/span>foreach($c in $computer)        <br \/><span>&#160; <\/span>{        <br \/><span>&#160;&#160;&#160; <\/span>foreach ($h in $hotfix)        <br \/><span>&#160;&#160;&#160; <\/span>{        <br \/><span>&#160;&#160;&#160;&#160; <\/span>$status =<span>&#160; <\/span>$(if(Get-HotFixStatus -hotfix $h -computer $c) {$true} else {$false})        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">A new object is created and stored in the <b>$object<\/b> variable. The object is a <b>PSObject<\/b> and will be used to store information that will be used in the hotfix report. The <b>New-Object<\/b> cmdlet is used to create the custom object as seen here:     <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\"><span>&#160;&#160;&#160;&#160; <\/span>$object = New-Object -TypeName PSObject        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The first property to create on the new custom object is a property named <b>Computer<\/b>. To add the <b>Computer<\/b> property, use the <b>Add-Member<\/b> cmdlet and add a <b>NoteProperty<\/b> to the object that has the name <b>Computer<\/b> and the value that is supplied via the ForEach loop that is contained in the <b>$c<\/b> variable. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\"><span>&#160;&#160;&#160;&#160; <\/span>$object | Add-Member -MemberType NoteProperty -Name Computer `        <br \/><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span>-Value $c        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The other properties are added to the custom <b>PSObject<\/b> in the same manner that the <b>computer<\/b> property was added. You pipe the object to the <b>Add-Member<\/b> cmdlet to specify the <b>MemberType<\/b> (<b>NoteProperty<\/b> in this example), the name of the property, and the value. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\"><span>&#160;&#160;&#160;&#160; <\/span>$object | Add-Member -MemberType NoteProperty<span>&#160; <\/span>-Name HotFix `        <br \/><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span>-Value $h        <br \/><span>&#160;&#160;&#160;&#160; <\/span>$object | Add-Member -MemberType NoteProperty -Name Installed `        <br \/><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span>-Value $status        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">After the custom PSObject has been created, it is returned to the calling code. To do this, place the variable name that contains the object on a line by itself. Because Windows PowerShell functions automatically return objects to the calling code, it is not necessary to use the <b>return<\/b> keyword or some other technique to return the object. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\"><span>&#160;&#160;&#160; <\/span>$object        <br \/><span>&#160;&#160;&#160; <\/span>} #end foreach hotfix        <br \/><span>&#160;&#160; <\/span>} #end foreach computer        <br \/>} #end function Get-FixReport        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The <b>Out-HotFixLog<\/b> function is used to write information to the hotfix log file that is supplied via the <b>$filepath<\/b> variable. The first thing that is done inside the <b>Out-HotFixLog<\/b> function is write a header to the text file that includes the date. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">Function Out-HotFixLog ([string]$filepath)       <br \/>{        <br \/><span>&#160;<\/span>&quot;Hot Fix Report $(Get-Date)&quot; | Out-File -filepath $filepath \u2013append        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">After the report heading has been written, the <b>Get-HotFixReport<\/b> function is called. It is passed the hotfix and the computer name. The resulting object is sorted by hotfix name and appended to the text file. This is seen here:     <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\"><span>&#160;<\/span>Get-HotFixReport -hotfix $hotfix -computer $computer |         <br \/><span>&#160;<\/span>Sort-object -property hotfix |         <br \/><span>&#160;<\/span>Out-File -filepath $filepath -append        <br \/>} #end function Out-HotFixLog        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The entry point to the script writes a string to the Windows PowerShell console that includes the time when the report was run. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">&quot;Hot Fix Report $(Get-Date)&quot;       <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The first function that is called is the <b>Get-HotFixReport<\/b> function. It is passed the array of hotfixes stored in the <b>$hotfix<\/b> variable and the array of computer names contained in the <b>$computer<\/b> variable. This is seen here:<i>     <\/p>\n<p>   <\/i><\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">Get-HotFixReport -hotfix $hotfix -computer $computer |        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">As the objects are returned from the <b>Get-HotFixReport<\/b> function, they are sorted based upon the <b>computer<\/b> name property of the custom object that is returned. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">Sort-object -property computer |        <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The sorted objects are converted into a table and displayed on the Windows PowerShell console. This is seen here:   <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">Format-Table -Property * -autosize       <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The display on the Windows PowerShell console is seen here:   <\/p>\n<p style=\"margin: 4pt 0in 7pt\" class=\"CodeBlock\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-09-10-09-02_2.jpg\"><img decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" title=\"HSG-09-10-09-02\" border=\"0\" alt=\"HSG-09-10-09-02\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-09-10-09-02_thumb.jpg\" width=\"604\" height=\"269\" \/><\/a> <\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">Next, if the <b>logToFile<\/b> switched parameter was specified when the script was called, the <b>Out-HotFixLog<\/b> function is called. This is seen here:    <\/p>\n<p style=\"margin: 4pt 0in 7pt;background: #d9d9d9\" class=\"CodeBlock\"><span style=\"font-size: 9.5pt\"><font face=\"Lucida Sans Typewriter\">if($logToFile) { Out-HotFixLog -filepath $filepath }       <\/p>\n<p>     <\/font><\/span><\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">The <b>Out-HotFixLog<\/b> function is automatically set up to append to the log file that is specified in the <b>$filepath<\/b> variable. When I run the script on my computer, the following report is displayed:    <\/p>\n<p style=\"margin: 4pt 0in 7pt\" class=\"CodeBlock\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-09-10-09-03_2.jpg\"><img decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" title=\"HSG-09-10-09-03\" border=\"0\" alt=\"HSG-09-10-09-03\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-09-10-09-03_thumb.jpg\" width=\"560\" height=\"435\" \/><\/a> <\/p>\n<p style=\"margin: 4pt 0in 7pt\" class=\"CodeBlock\">\n<p><font size=\"1\" face=\"Lucida Sans Typewriter\">&#160;<\/font><\/p>\n<\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">JH, thank you for your question that you sent to <a href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a>. It was a great question, especially because it had already been answered in the Official Scripting Guys Forum. Join us tomorrow for Quick-Hits Friday.     <\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">We welcome you to follow us on <a href=\"http:\/\/www.twitter.com\/scriptingguys\/\"><font face=\"Segoe\">Twitter<\/font><\/a> or <a href=\"http:\/\/www.facebook.com\/group.php?gid=5901799452&amp;ref=ts\"><font face=\"Segoe\">Facebook<\/font><\/a>. If you have any questions, send e-mail to us at <a href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a> or post your questions on the <a href=\"http:\/\/social.technet.microsoft.com\/Forums\/en\/ITCG\/threads\/\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, keep on scripting.     <\/p>\n<p style=\"margin: 0in 0in 8pt\" class=\"MsoNormal\">\n<p>&#160;<\/p>\n<\/p>\n<p style=\"margin-left: 0in\"><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys       <\/p>\n<p>     <\/span><\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Share this post: Hey, Scripting Guy! I have a text file that contains a number of computer names. I would like to read that text file, query each computer in the list, and find out the status of a particular hotfix. If I could write the information to a text file, it would be even [&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":[31,3,203,45],"class_list":["post-52493","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-operating-system","tag-scripting-guy","tag-service-packs-and-hotfixes","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Share this post: Hey, Scripting Guy! I have a text file that contains a number of computer names. I would like to read that text file, query each computer in the list, and find out the status of a particular hotfix. If I could write the information to a text file, it would be even [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/52493","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=52493"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/52493\/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=52493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=52493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=52493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}