<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://powershell.com/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results for 'app:weblogs' matching tags 'Scripting Guy!', 'WSUS', and 'Boe Prox'</title><link>http://powershell.com/cs/search/SearchResults.aspx?q=app:weblogs&amp;tag=Scripting+Guy!,WSUS,Boe+Prox&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tags 'Scripting Guy!', 'WSUS', and 'Boe Prox'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Installing WSUS on Windows Server 2012  </title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/15/installing-wsus-on-windows-server-2012.aspx</link><pubDate>Mon, 15 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22789</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong style="font-size:12px;"&gt;Summary&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;: Honorary Scripting Guy, Boe Prox, talks about installing WSUS on Windows Server 2012 via Windows PowerShell.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Welcome back today to Honorary Scripting Guy, &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/tags/boe+prox/" target="_blank"&gt;Boe Prox&lt;/a&gt;. Without further ado, here is Boe&amp;hellip;&lt;/p&gt;
&lt;p&gt;In a previous Hey, Scripting Guy! Blog post, &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/16/introduction-to-wsus-and-powershell.aspx" target="_blank"&gt;Introduction to WSUS and PowerShell&lt;/a&gt;, I demonstrated how you can download the Windows Server Update Services (WSUS) installation file and use various parameters to customize a WSUS installation on a local or remote system. With Windows Server 2012, we get a new version of WSUS that can be installed through Server Manager and also by&amp;hellip;you guessed it&amp;hellip;Windows PowerShell!&lt;/p&gt;
&lt;p&gt;We can do the installation by using the &lt;strong&gt;Install-WindowsFeature&lt;/strong&gt; cmdlet and specifying the proper feature names that you would like to have installed. In the case of WSUS, we are looking only at the update services feature. I will also take a look at some of the new cmdlets that are available in the UpdateServices module, which is available in Windows Server 2012 to help configure the WSUS server.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at the possible subfeatures that are available by using the &lt;strong&gt;Get-WindowsFeature&lt;/strong&gt; cmdlet and specifying &lt;strong&gt;UpdateServices*&lt;/strong&gt; for the &lt;strong&gt;Name&lt;/strong&gt; parameter.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WindowsFeature &amp;ndash;Name UpdateServices*&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6012.hsg_2D00_4_2D00_15_2D00_13_2D00_1.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6012.hsg_2D00_4_2D00_15_2D00_13_2D00_1.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You could try to install everything, but that will end badly for you because there will be a conflict between using the Windows Internal Database (WID) and using another SQL Server database (local or remote) to store the SUSDB database on.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4188.hsg_2D00_4_2D00_15_2D00_13_2D00_2.png"&gt;&lt;img style="border:0px currentColor;" title="Image of error message" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4188.hsg_2D00_4_2D00_15_2D00_13_2D00_2.png" alt="Image of error message" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So which one should I choose? That depends on your environment and what your requirements are to support patching in your enterprise. Luckily for you, I will show examples of using the WID database or using another SQL Server database as part of the WSUS installation. After the installation, I will show one last thing you can do as a post installation that will allow you to specify a new location for the software update files and where the database is located.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with the easiest, which is the WID database. I say easiest because it really comes down to just running a single line of code to get everything installed. Just to see what might be installed, I can use the &lt;strong&gt;WhatIf&lt;/strong&gt; switch first.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Install-WindowsFeature -Name UpdateServices -IncludeManagementTools &amp;ndash;WhatIf&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4812.hsg_2D00_4_2D00_15_2D00_13_2D00_3.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4812.hsg_2D00_4_2D00_15_2D00_13_2D00_3.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From the looks of it, not only will WSUS be installed, but we also will be installing the WID database and some IIS components that are used for client check-ins and other things. I am confident that this is what I need, so let&amp;rsquo;s remove &lt;strong&gt;WhatIf&lt;/strong&gt; and let it run again.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0743.hsg_2D00_4_2D00_15_2D00_13_2D00_4.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0743.hsg_2D00_4_2D00_15_2D00_13_2D00_4.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wait for a bit&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8306.hsg_2D00_4_2D00_15_2D00_13_2D00_5.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8306.hsg_2D00_4_2D00_15_2D00_13_2D00_5.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And we are now finished with the installation. As you can see, we have a message stating some additional configuration may be required before our WSUS server can be up and running. In this case, we still need to configure a location for the update files to be stored.&lt;/p&gt;
&lt;p&gt;This is where wsusutil.exe will come into play. This executable is located at C:\Program Files\Update Services\Tools. Besides the usual parameters that you can use with this utility, there is another set of parameters that become available when you use the &lt;strong&gt;PostInstall&lt;/strong&gt; argument.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;.\wsusutil.exe postinstall /?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6864.hsg_2D00_4_2D00_15_2D00_13_2D00_6.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6864.hsg_2D00_4_2D00_15_2D00_13_2D00_6.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We have parameters for specifying where to store the content and for where to build the database, if needed. Note that this can be used to specify a database that is local or remote (you will see this used on a remote system later).&lt;/p&gt;
&lt;p&gt;Before I say where I want the content, I had better create a folder to store it. I don&amp;rsquo;t want all of this on my system drive, so I will create the folder on my D: drive.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-Item -Path D: -Name WSUS -ItemType Directory&lt;/p&gt;
&lt;p&gt;Now I can run the following command to configure my content directory to download and save all of the update files to D:\WSUS.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;.\wsusutil.exe postinstall CONTENT_DIR=D:\WSUS&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8304.hsg_2D00_4_2D00_15_2D00_13_2D00_7.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8304.hsg_2D00_4_2D00_15_2D00_13_2D00_7.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And with that, we have now configured the content directory on another drive to save the update files. Very simple&amp;hellip;and a big recommendation to do it regardless!&lt;/p&gt;
&lt;h2&gt;Specify an alternate SQL Server&lt;/h2&gt;
&lt;p&gt;What if I want to specify a different SQL Server for saving the data instead of relying on a WID instance locally? Fortunately for us (and as you saw previously), this is an available option by using WSUSUtil.exe PostInstall. Going back to the beginning, I will perform a different installation of WSUS, this time specifying that I want a different SQL Server database.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Install-WindowsFeature -Name UpdateServices-Services,UpdateServices-DB -IncludeManagementTools&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8508.hsg_2D00_4_2D00_15_2D00_13_2D00_8.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8508.hsg_2D00_4_2D00_15_2D00_13_2D00_8.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now we need to use WSUSUtil again to not only specify the Content directory, but also to specify the SQL Server database that I want to use for my WSUS server. The WSUS server must be on a domain for the remote SQL Server database build to work. If it isn&amp;rsquo;t, you will get a message that states the host is unknown.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;.\wsusutil.exe postinstall SQL_INSTANCE_NAME=&amp;quot;DC1\SQL2008&amp;quot; CONTENT_DIR=D:\WSUS&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2870.hsg_2D00_4_2D00_15_2D00_13_2D00_9.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2870.hsg_2D00_4_2D00_15_2D00_13_2D00_9.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And after a few minutes, the configuration has completed with the Content directory on D:\WSUS and the SUSDB database configured on my remote SQL Server.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5076.hsg_2D00_4_2D00_15_2D00_13_2D00_10.png"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5076.hsg_2D00_4_2D00_15_2D00_13_2D00_10.png" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Inspect the WSUS Installation State&lt;/h2&gt;
&lt;p&gt;By using my current installation of WSUS and the remote SQL Server database, we can now check the Best Practices Analyzer to see if anything else is required before we configure the WSUS server and kick off synchronization get all of the update metadata.&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Invoke-BpaModel -ModelId Microsoft/Windows/UpdateServices&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3733.hsg_2D00_4_2D00_15_2D00_13_2D00_11.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3733.hsg_2D00_4_2D00_15_2D00_13_2D00_11.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s see the results of our scan&amp;hellip;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-BpaResult -ModelId Microsoft/Windows/UpdateServices |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select Title,Severity,Compliance | Format-List&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3582.hsg_2D00_4_2D00_15_2D00_13_2D00_12.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3582.hsg_2D00_4_2D00_15_2D00_13_2D00_12.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With the exception that I haven&amp;rsquo;t configured the WSUS server to use a required language pack (English in my case), everything else is compliant. Now it is time to finish configuring the WSUS server and get this synchronization kicked off.&lt;/p&gt;
&lt;p&gt;First I&amp;rsquo;ll configure the languages and tell my server where I want to synchronize. In this case I want to sync up with Microsoft Updates. After I do that, I will perform an initial synchronization to pull down all of the available categories, classifications, and possible updates that can be approved.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;For more information about some of the configuration properties that are set in the following code, see &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.updateservices.administration.iupdateserverconfiguration_properties(v=vs.85).aspx" target="_blank"&gt;IUpdateServerConfiguration Properties&lt;/a&gt; &amp;nbsp;on MSDN.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Get WSUS Server Object&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus = Get-WSUSServer&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Connect to WSUS server configuration&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsusConfig = $wsus.GetConfiguration()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Set to download updates from Microsoft Updates&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-WsusServerSynchronization &amp;ndash;SyncFromMU&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Set Update Languages to English and save configuration settings&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsusConfig.AllUpdateLanguagesEnabled = $false&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsusConfig.SetEnabledUpdateLanguages(&amp;quot;en&amp;quot;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsusConfig.Save()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Get WSUS Subscription and perform initial synchronization to get latest categories&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription = $wsus.GetSubscription()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.StartSynchronizationForCategoryOnly()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;While ($subscription.GetSynchronizationStatus() -ne &amp;#39;NotProcessing&amp;#39;) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write-Host &amp;quot;.&amp;quot; -NoNewline&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Start-Sleep -Seconds 5&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Write-Host &amp;quot;Sync is done.&amp;quot;&lt;/p&gt;
&lt;p&gt;You may have noticed that I didn&amp;rsquo;t have to run &lt;strong&gt;Import-Module&lt;/strong&gt; before using the UpdateServices module cmdlets. This is because Windows PowerShell&amp;nbsp;3.0 supports automatic loading of the modules when a specific cmdlet from a module is used.&lt;/p&gt;
&lt;p&gt;Now that we have pulled down the classifications and platforms, it is time to filter the platforms for which I want updates and the classifications I want. Your preference for platforms and classifications will vary based on your environment and requirements.&lt;/p&gt;
&lt;p&gt;When that is done, we will configure WSUS to synchronize once a day automatically at midnight, and kick off another synchronization to pull down the update metadata (not the actual update files) from the Microsoft Update server.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Configure the Platforms that we want WSUS to receive updates&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WsusProduct | where-Object {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $_.Product.Title -in (&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;CAPICOM&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Silverlight&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;SQL Server 2008 R2&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;SQL Server 2005&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;SQL Server 2008&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Exchange Server 2010&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Windows Server 2003&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Windows Server 2008&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Windows Server 2008 R2&amp;#39;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;} | Set-WsusProduct&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Configure the Classifications&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WsusClassification | Where-Object {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $_.Classification.Title -in (&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Update Rollups&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Security Updates&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Critical Updates&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Service Packs&amp;#39;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;Updates&amp;#39;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;} | Set-WsusClassification&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Configure Synchronizations&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.SynchronizeAutomatically=$true&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Set synchronization scheduled for midnight each night&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.SynchronizeAutomaticallyTimeOfDay= (New-TimeSpan -Hours 0)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.NumberOfSynchronizationsPerDay=1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.Save()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Kick off a synchronization&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.StartSynchronization()&lt;/p&gt;
&lt;p&gt;It may take a while to complete the synchronization. When it has completed, you can begin reviewing the available updates that your systems require. Whether you want to keep everything installed and configured on a single server or you want to keep your SUSDB database on a remote SQL Server, you will find that it is easily accomplished by using Windows PowerShell.&lt;/p&gt;
&lt;p&gt;That is all for today&amp;rsquo;s blog about working with WSUS on Windows Server&amp;nbsp;2012. The next blog I have lined up will deal with using the UpdateServices module to configure the clients and approve or decline updates. In addition, we will dip our toes into WSUS API to set up Computer Groups for the clients and to remove clients from WSUS.&lt;/p&gt;
&lt;p&gt;~Boe&lt;/p&gt;
&lt;p&gt;Thank you, Boe, for a great blog post. Join us tomorrow for a guest blog by Honorary Scripting Guy and Windows PowerShell MVP, Don Jones.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3564383" width="1" height="1" alt="" /&gt;</description></item><item><title>Use the Free PoshWSUS PowerShell Module for WSUS Administrative Work</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/01/22/use-the-free-poshwsus-powershell-module-for-wsus-administrative-work.aspx</link><pubDate>Sun, 22 Jan 2012 06:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:14144</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Learn how to use the free PoshWSUS Windows PowerShell module to administer your WSUS server.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. We wrap up the weekend and the week with guest blogger, Boe Prox. In case you missed them, here are links for Boe&amp;rsquo;s blogs:&lt;/p&gt;
&lt;p&gt;Day 1: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/16/introduction-to-wsus-and-powershell.aspx" target="_blank"&gt;Introduction to WSUS and PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 2: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/17/use-powershell-to-perform-basic-administrative-tasks-on-wsus.aspx" target="_blank"&gt;Use PowerShell to Perform Basic Administrative Tasks on WSUS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 3: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/18/approve-or-decline-wsus-updates-by-using-powershell.aspx" target="_blank"&gt;Approve or Decline WSUS Updates by Using PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 4: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/19/use-powershell-to-find-missing-updates-on-wsus-client-computers.aspx" target="_blank"&gt;Use PowerShell to Find Missing Updates on WSUS Client Computers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 5: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/20/get-windows-update-status-information-by-using-powershell.aspx" target="_blank"&gt;Get Windows Update Status Information by Using PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 6: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/21/introduction-to-poshwsus-a-free-powershell-module-to-manage-wsus.aspx" target="_blank"&gt;Introduction to PoshWSUS, a Free PowerShell Module to Manage WSUS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take it away, Boe&amp;hellip;&lt;/p&gt;
&lt;p&gt;We are at the final stopping point in our week of WSUS and this final blog is all about WSUS administration using my PoshWSUS module. The past week has seen us create a WSUS server and managing the server by using Windows PowerShell and the WSUS assemblies, but now we are going to look at this using fewer commands by using the PoshWSUS module. I will now show some examples that use the module to perform some of the exact commands that were done earlier in the week.&lt;/p&gt;
&lt;h3&gt;Initial use of PoshWSUS&lt;/h3&gt;
&lt;p&gt;To download the module, see &lt;a href="http://poshwsus.codeplex.com/" target="_blank"&gt;PoshWSUS&lt;/a&gt; in CodePlex. Unzip the files to your Modules directory&amp;mdash;in my case for Windows&amp;nbsp;7, it is C:\Users\Boe\Documents\WindowsPowerShell\Modules. I saved the modules to a folder named PoshWSUS. This location is shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0676.wes_2D00_1_2D00_22_2D00_12_2D00_1.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0676.wes_2D00_1_2D00_22_2D00_12_2D00_1.jpg" alt="Image of menu" title="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Load the module by using the &lt;b&gt;Import-Module&lt;/b&gt; cmdlet. This command is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Import-Module PoshWSUS&lt;/p&gt;
&lt;p&gt;The following image shows me using the &lt;b&gt;Get-Module&lt;/b&gt; cmdlet to view the available cmdlets and using the &lt;b&gt;Import-Module&lt;/b&gt; cmdlet to import the module.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6102.wes_2D00_1_2D00_22_2D00_12_2D00_2.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6102.wes_2D00_1_2D00_22_2D00_12_2D00_2.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Make your initial connection to the WSUS server. To do this, use the &lt;b&gt;Connect-WSUSServer&lt;/b&gt; cmdlet as shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Connect-WSUSServer -WsusServer DC1&lt;/p&gt;
&lt;p&gt;The following image shows the connection to the WSUS server named DC1.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5518.wes_2D00_1_2D00_22_2D00_12_2D00_3.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5518.wes_2D00_1_2D00_22_2D00_12_2D00_3.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now you are set to go!&lt;/p&gt;
&lt;h3&gt;Client and group management&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s start by looking at some basic client and group administration commands that you may find yourself using when you administer the server. The following example lists all clients that are registered in the WSUS Server.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSClient&lt;/p&gt;
&lt;p&gt;The output from the Get-WSUSClient cmdlet is shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3323.wes_2D00_1_2D00_22_2D00_12_2D00_4.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3323.wes_2D00_1_2D00_22_2D00_12_2D00_4.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you only want to list a specific client that is registered on the WSUS server, you can run the following command to get the data.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSClient -Computer boe-pc&lt;/p&gt;
&lt;p&gt;The following image shows the result of running the Get-WSUSClient cmdlet. Note that it provides lots of good information about the client computer.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4478.wes_2D00_1_2D00_22_2D00_12_2D00_5.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4478.wes_2D00_1_2D00_22_2D00_12_2D00_5.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For some extra fun, you can even use the &lt;b&gt;Group-Object&lt;/b&gt; cmdlet to group all of your clients by operating system. A command to do this is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSClient | Group OSDescription | Select Count,Name&lt;/p&gt;
&lt;p&gt;The command and associated output are shown in the image that follows.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8688.wes_2D00_1_2D00_22_2D00_12_2D00_6.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8688.wes_2D00_1_2D00_22_2D00_12_2D00_6.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to display all of the target groups that are in the WSUS server, you can run use the &lt;b&gt;Get-WSUSGroup&lt;/b&gt; command.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSGroup&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6303.wes_2D00_1_2D00_22_2D00_12_2D00_7.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6303.wes_2D00_1_2D00_22_2D00_12_2D00_7.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to add a client into a specific group, you can run this one-liner:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSClient boe-pc | Add-WSUSClientToGroup -Group TESTGROUP&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s verify that my client is actually in that group by using &lt;b&gt;Get-WSUSClientGroupMembership&lt;/b&gt;.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSClientGroupMembership -Computer boe-pc&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6266.wes_2D00_1_2D00_22_2D00_12_2D00_8.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6266.wes_2D00_1_2D00_22_2D00_12_2D00_8.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Looking at the returned data, it would appear that the client is in the TESTGROUP group.&lt;/p&gt;
&lt;p&gt;Removing a WSUS client from a group is just as simple as using &lt;b&gt;Remove-WSUSClientFromGroup&lt;/b&gt;. This command is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Remove-WSUSClientFromGroup -Computer boe-pc -Group TESTGROUP&lt;/p&gt;
&lt;p&gt;One more check to see if my client is no longer in TESTGROUP. The results are shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3386.wes_2D00_1_2D00_22_2D00_12_2D00_9.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3386.wes_2D00_1_2D00_22_2D00_12_2D00_9.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, my client is now a member of &lt;b&gt;Unassigned Computers&lt;/b&gt;, meaning that it is not a member of any group in WSUS other than the default &lt;b&gt;All Computers&lt;/b&gt; group.&lt;/p&gt;
&lt;p&gt;Creating a new group on WSUS is made simple by using &lt;b&gt;New-WSUSGroup&lt;/b&gt;. Here, I create a new group named &lt;b&gt;MyGroup&lt;/b&gt;&lt;i&gt;. &lt;/i&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-WSUSGroup &amp;ldquo;MYGROUP&amp;rdquo; &amp;ndash;PassThru&lt;/p&gt;
&lt;p&gt;The results of creating the new &lt;b&gt;MyGroup&lt;/b&gt;&lt;i&gt; &lt;/i&gt;group are shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0044.wes_2D00_1_2D00_22_2D00_12_2D00_10.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0044.wes_2D00_1_2D00_22_2D00_12_2D00_10.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In addition to creating new groups, I can remove a WSUS group. It is just as easy to remove a group, as it is to create a group. I use the &lt;b&gt;Remove-WSUSGroup&lt;/b&gt; cmdlet. An example of doing this is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSGroup -Name MYGROUP | Remove-WSUSGroup&lt;/p&gt;
&lt;h3&gt;Update administration&lt;/h3&gt;
&lt;p&gt;Now for some more fun stuff: using PoshWSUS to work with Update administration. I have two commands (&lt;b&gt;Approve-WSUSUpdate&lt;/b&gt; and &lt;b&gt;Deny-WSUSUpdate&lt;/b&gt;) that make approving and declining updates easy to do. Besides that, you can use &lt;b&gt;Get-WSUSUpdate&lt;/b&gt; to look for updates on the WSUS server.&amp;nbsp; Unfortunately, &amp;ldquo;Decline&amp;rdquo; is not an approved verb in Windows PowerShell, so I went with &amp;ldquo;Deny&amp;rdquo; instead.&lt;/p&gt;
&lt;p&gt;Using &lt;b&gt;Get-WSUSUpdate&lt;/b&gt; without any parameters will return every single update on the WSUS server. In this case, I want to see all of the Windows&amp;nbsp;7 updates.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates = Get-WSUSUpdate &amp;#39;Windows 7&amp;#39;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates.count&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates | Select -first 10&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8611.wes_2D00_1_2D00_22_2D00_12_2D00_11.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8611.wes_2D00_1_2D00_22_2D00_12_2D00_11.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Approve-WSUSUpdate&lt;/b&gt; does take pipeline input from the Update object, so if you wanted to approve some updates that you queried, you could do the following:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates[1..10] | Approve-WSUSUpdate -Action Install -Group &amp;#39;All Computers&amp;#39; &amp;ndash;PassThru&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7536.wes_2D00_1_2D00_22_2D00_12_2D00_12.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7536.wes_2D00_1_2D00_22_2D00_12_2D00_12.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the same way, you can decline updates by piping the updates into &lt;b&gt;Deny-WSUSUpdate&lt;/b&gt;. This command is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates[1..10] | Deny-WSUSUpdate&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1663.wes_2D00_1_2D00_22_2D00_12_2D00_13.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1663.wes_2D00_1_2D00_22_2D00_12_2D00_13.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is a fun one! You can use &lt;b&gt;Get-WSUSUpdate &lt;/b&gt;and&lt;b&gt; New-WSUSUpdateScope&lt;/b&gt; to list all the updates that have been released on the last Patch Tuesday and are required by the clients, as shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSUpdate -UpdateScope (New-WSUSUpdateScope -IncludedInstallationStates NotInstalled -FromArrivalDate &amp;quot;12/13/2011&amp;quot;)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7711.wes_2D00_1_2D00_22_2D00_12_2D00_14.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7711.wes_2D00_1_2D00_22_2D00_12_2D00_14.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can then pipe this output into &lt;b&gt;Approve-WSUSUpdate&lt;/b&gt;:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSUpdate -UpdateScope (New-WSUSUpdateScope -IncludedInstallationStates NotInstalled -FromArrivalDate &amp;quot;12/13/2011&amp;quot;) | Approve-WSUSUpdate -Action Install -Group &amp;#39;All Computers&amp;#39; &amp;ndash;PassThru&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4111.wes_2D00_1_2D00_22_2D00_12_2D00_15.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4111.wes_2D00_1_2D00_22_2D00_12_2D00_15.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is always a good idea to review each update to make sure that you want to approve it in your environment.&lt;/p&gt;
&lt;h3&gt;Reporting&lt;/h3&gt;
&lt;p&gt;So I have covered some administration examples that use this module, but what about some type of reporting capability? Well, I will show you some different types of reports that you can do with this module.&lt;/p&gt;
&lt;p&gt;I can look for updates that have failed to install by using the following command:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSUpdatePerClient -UpdateScope (New-WSUSUpdateScope -IncludedInstallationStates Failed)&lt;/p&gt;
&lt;p&gt;Fortunately for me (but unfortunate for this example), I do not have any updates that reported failures in the installation.&lt;/p&gt;
&lt;p&gt;I can mimic what is shown in the following example of the Administration Console by using &lt;b&gt;Get-WSUSUpdateSummaryPerClient&lt;/b&gt;.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8270.wes_2D00_1_2D00_22_2D00_12_2D00_16.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8270.wes_2D00_1_2D00_22_2D00_12_2D00_16.jpg" alt="Image of menu" title="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSUpdateSummaryPerClient -ComputerScope (New-WSUSComputerScope) -UpdateScope (New-WSUSUpdateScope)&lt;/p&gt;
&lt;p&gt;The output is shown here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2860.wes_2D00_1_2D00_22_2D00_12_2D00_17.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2860.wes_2D00_1_2D00_22_2D00_12_2D00_17.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can even generate a report of update approvals by using &lt;b&gt;Get-WSUSUpdateApproval&lt;/b&gt; if you want to go back to see what has been approved and/or who approved a specific update. In this case, let&amp;rsquo;s go back and look at my update approvals for all of the updates from this Patch Tuesday.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope = New-WSUSUpdateScope -FromArrivalDate &amp;quot;12/13/2011&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSUpdateApproval -UpdateScope $updatescope&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3124.wes_2D00_1_2D00_22_2D00_12_2D00_18.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3124.wes_2D00_1_2D00_22_2D00_12_2D00_18.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you wanted to get a report of patches that are needed by clients in a specific group, you can give this command a run:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSUpdateSummaryForGroup -GroupName &amp;#39;All Computers&amp;#39; -UpdateObject $updates[200..300]&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3073.wes_2D00_1_2D00_22_2D00_12_2D00_19.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3073.wes_2D00_1_2D00_22_2D00_12_2D00_19.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Other commands to use&lt;/h3&gt;
&lt;p&gt;Besides the commands that I have shown in this blog post, there are other commands that you may find useful during your administration of a WSUS server. So, without further ado, here are some command examples:&lt;/p&gt;
&lt;p&gt;Show the current synchronization schedule by using &lt;b&gt;Get-WSUSSubscription&lt;/b&gt;:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSSubscription&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8875.wes_2D00_1_2D00_22_2D00_12_2D00_20.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8875.wes_2D00_1_2D00_22_2D00_12_2D00_20.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Listing all Install Approval rules on your WSUS server is also easy by using &lt;b&gt;Get-WSUSInstallApprovalRule&lt;/b&gt;. For those of you who are not familiar with Install Approval, basically it allow you set up automatic approvals of specific products for specific computer target groups. Pretty nice if you know that you want to approve critical security updates for all of your clients every month.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WSUSInstallApprovalRule&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0876.wes_2D00_1_2D00_22_2D00_12_2D00_21.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0876.wes_2D00_1_2D00_22_2D00_12_2D00_21.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the same way, you can configure a new Install Approval rule by using &lt;b&gt;New-WSUSApprovalRule&lt;/b&gt; and &lt;b&gt;Set-WSUSApprovalRule&lt;/b&gt;.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$group = Get-WSUSGroup -Name &amp;#39;All Computers&amp;#39;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$class = Get-WSUSUpdateClassification | Where {$_.Title -eq &amp;quot;Updates&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-WSUSInstallApprovalRule -Name &amp;quot;Rule1&amp;quot; -Category $cat -Classification $class -Group $group &amp;ndash;Enable &amp;ndash;PassThru&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3343.wes_2D00_1_2D00_22_2D00_12_2D00_22.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3343.wes_2D00_1_2D00_22_2D00_12_2D00_22.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can even run the Install Approval rules by using &lt;b&gt;Start-WSUSInstallApprovalRule&lt;/b&gt;.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Start-WSUSInstallApprovalRule -Name &amp;quot;Rule1&amp;quot;&lt;/p&gt;
&lt;p&gt;If you wanted to locate the files for each update and their location on the server, you can run the &lt;b&gt;Get-WSUSInstallableItem&lt;/b&gt; command.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates[0] | Get-WSUSInstallableItem&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1715.wes_2D00_1_2D00_22_2D00_12_2D00_23.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1715.wes_2D00_1_2D00_22_2D00_12_2D00_23.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can dig into the files a little deeper to see how many files and where exactly they are located:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates[0] | Get-WSUSInstallableItem | Select &amp;ndash;Expand Files&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6014.wes_2D00_1_2D00_22_2D00_12_2D00_24.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6014.wes_2D00_1_2D00_22_2D00_12_2D00_24.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That wraps it up for my week with WSUS and Windows PowerShell and also talking about my PoshWSUS module. I have more updates planned, including adding more commands (such as publishing non-Microsoft updates to WSUS) and updating existing commands. Remember that if you see something that you would like to see added to the module or you find a bug in it, please log your issues and ideas in the &lt;a href="http://poshwsus.codeplex.com/workitem/list/basic" target="_blank"&gt;CodePlex Issue Tracker&lt;/a&gt;. Thank you everyone for checking out my blogs and thanks to Ed for allowing me to take over a week of Hey, Scripting Guy! to talk WSUS and Windows PowerShell!&lt;/p&gt;
&lt;p&gt;~Boe&lt;/p&gt;
&lt;p&gt;Thanks, Boe, for an awesome week of Windows PowerShell goodness. Join us tomorrow for a new week on the Hey, Scripting Guy! blog.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3475015" width="1" height="1" alt="" /&gt;</description></item><item><title>Introduction to PoshWSUS, a Free PowerShell Module to Manage WSUS</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/01/21/introduction-to-poshwsus-a-free-powershell-module-to-manage-wsus.aspx</link><pubDate>Sat, 21 Jan 2012 06:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:14136</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Guest blogger, Boe Prox, discusses the development of the free Windows PowerShell module that he wrote to manage WSUS.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Today we are celebrating our 2000&lt;sup&gt;th&lt;/sup&gt; Hey, Scripting Guy! blog. I think that in the spirit of community, it is appropriate that today we also have a guest blogger, Boe Prox, who is talking about a project that he developed and shared on CodePlex.&lt;/p&gt;
&lt;p&gt;I will let him speak for himself&amp;mdash;take it away Boe&amp;hellip;&lt;/p&gt;
&lt;p&gt;After a week of working with Windows PowerShell and WSUS and showing you some pretty cool things that you can do with the two, I am going to talk about a project that I have been working on that will make administering a WSUS server easier with Windows PowerShell.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here are the blogs from the past week if you would like to catch up:&lt;/p&gt;
&lt;p&gt;Day 1: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/16/introduction-to-wsus-and-powershell.aspx" target="_blank"&gt;Introduction to WSUS and PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 2: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/17/use-powershell-to-perform-basic-administrative-tasks-on-wsus.aspx" target="_blank"&gt;Use PowerShell to Perform Basic Administrative Tasks on WSUS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 3: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/18/approve-or-decline-wsus-updates-by-using-powershell.aspx" target="_blank"&gt;Approve or Decline WSUS Updates by Using PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 4: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/19/use-powershell-to-find-missing-updates-on-wsus-client-computers.aspx" target="_blank"&gt;Use PowerShell to Find Missing Updates on WSUS Client Computers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 5: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/20/get-windows-update-status-information-by-using-powershell.aspx" target="_blank"&gt;Get Windows Update Status Information by Using PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My plan today is to give an overview of what PoshWSUS is and why I built it the way I did, plus show a couple of small examples. Tomorrow I will show you more examples of using PoshWSUS to accomplish some of the same tasks that I have been showing earlier in the week in addition to a few new things.&lt;/p&gt;
&lt;h3&gt;What is PoshWSUS?&lt;/h3&gt;
&lt;p&gt;PoshWSUS is a module that I designed and built to help a system administrator manage a WSUS server easily by using Windows PowerShell. To download the module, see &lt;a href="http://poshwsus.codeplex.com/" target="_blank"&gt;PoshWSUS&lt;/a&gt; in CodePlex.&lt;/p&gt;
&lt;p&gt;Currently, there are 60 commands that are available in version 2.0, which was recently released on Dec. 18, 2011. There are various commands that one can use with this module. Although a majority of commands are query-type commands, there are other commands that allow you to approve or decline updates, create groups, add clients to groups, and work with synchronizations (to name a few). Here is a full list of the commands available:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2625.wes_2D00_1_2D00_21_2D00_12_2D00_1.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2625.wes_2D00_1_2D00_21_2D00_12_2D00_1.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PoshWSUS originally started as one module file (.psm1) that contained approximately 45 commands. This file was over 2000 lines long, which made it extremely difficult to work with, especially when it came time to troubleshoot one of the commands.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When it came time to work on version 2.0 of PoshWSUS, I made the decision to separate each of the commands into its own file to make it much easier to work with. I can then use the module file to go through each of the files and dot source the functions from those files.&lt;/p&gt;
&lt;h3&gt;Why PoshWSUS?&lt;/h3&gt;
&lt;p&gt;I work with WSUS almost daily, and wanted a way to quickly perform a query or quick update approval against WSUS without having to jump onto the Administration Console and click, click, click my way to victory. Another piece of motivation that I used in writing this module is that there was no module for WSUS at all. Sure, there are various scripts available that perform various queries, approvals, and so on&amp;mdash;but never a module that really tied everything together and covered a wide threshold of things to do in WSUS. Thus, PoshWSUS comes into play to fill in that gap and allow people to manage their WSUS server from the command line.&lt;/p&gt;
&lt;p&gt;So with that, I will talk a little about some of the new things that my latest version brings into play.&lt;/p&gt;
&lt;h3&gt;Working with custom types&lt;/h3&gt;
&lt;p&gt;One of the things that I was determined to change was the way that the output from any command would be displayed in the console. By default, if you run a command that would list a client or update, you would be crushed by a sea of data for each client and update that was returned unless you used &lt;b&gt;Select-Object&lt;/b&gt; or &lt;b&gt;Format-Table&lt;/b&gt; and listed only the properties that you wanted to see. Obviously, I couldn&amp;rsquo;t add this into my commands because I would lose the object type and also limit the amount of data that was available to a user.&lt;/p&gt;
&lt;p&gt;Here is an example of such output from an update query:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Pretty wild, isn&amp;rsquo;t it?&amp;nbsp; Well, thanks to custom-type formatting, I can dictate what is displayed by each output while still preserving the object type.&amp;nbsp; Now, I won&amp;rsquo;t go into detail about how this works because that would be a blog (or two) in itself. But as you can see in the following example, it greatly simplifies the display of the output while still retaining the object&amp;rsquo;s type.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5824.wes_2D00_1_2D00_21_2D00_12_2D00_3.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5824.wes_2D00_1_2D00_21_2D00_12_2D00_3.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So it looks better AND retains the object type.&lt;/p&gt;
&lt;p&gt;Even if you use &lt;b&gt;Format-List&lt;/b&gt;, it will not show every property unless you specify by using the &amp;ldquo;&lt;b&gt;*&lt;/b&gt;&amp;rdquo;. This is shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8461.wes_2D00_1_2D00_21_2D00_12_2D00_4.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8461.wes_2D00_1_2D00_21_2D00_12_2D00_4.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Adding properties to an existing type&lt;/h3&gt;
&lt;p&gt;While most of the data that is returned by a query is useful, sometimes you get some properties that aren&amp;rsquo;t as helpful in their current state. For instance, let&amp;rsquo;s look at the following output:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3731.wes_2D00_1_2D00_21_2D00_12_2D00_5.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3731.wes_2D00_1_2D00_21_2D00_12_2D00_5.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Updated is not exactly something that we can use because we have no idea what update it is referring to. By adding some extra properties for this type (Microsoft.UpdateServices.Internal.BaseApi.UpdateSummary), we can translate that ID into the following:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4861.wes_2D00_1_2D00_21_2D00_12_2D00_6.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4861.wes_2D00_1_2D00_21_2D00_12_2D00_6.jpg" border="0" alt="" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1200.wes_2D00_1_2D00_21_2D00_12_2D00_7.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1200.wes_2D00_1_2D00_21_2D00_12_2D00_7.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can tell, there are a couple of properties that are null, and this is by design for this object. How this query is performed will determine which of the &lt;b&gt;UpdateTitle&lt;/b&gt;, &lt;b&gt;ComputerGroup&lt;/b&gt;, and &lt;b&gt;Computer&lt;/b&gt; properties would be populated. This technique is used with several types to provide clearer data that is returned on various queries.&lt;/p&gt;
&lt;p&gt;Most of the information about working with type formatting was via Jeffery Hicks and my time at the PowerShell Deep Dive where he presented on the subject. Here is some information about Jeff:&lt;br /&gt; Blog: &lt;a href="http://jdhitsolutions.com/blog/" target="_blank"&gt;The Lonely Administrator&lt;/a&gt;&lt;br /&gt; Twitter: &lt;a href="https://twitter.com/JeffHicks" target="_blank"&gt;https://twitter.com/JeffHicks&lt;/a&gt;&lt;br /&gt; YouTube video of Deep Dive session: &lt;a href="http://www.youtube.com/watch?v=dZsRc7EHIbc" target="_blank"&gt;Mastering Format and Type Extensions&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Removing plural nouns&lt;/h3&gt;
&lt;p&gt;Another thing that I changed was some of the names of the commands in the module. Originally, I had several modules that were named with a plural noun and another that was singular, such as &lt;b&gt;Get-WSUSClient&lt;/b&gt; and &lt;b&gt;Get-WSUSClients&lt;/b&gt;. It is poor practice in Windows PowerShell to have a plural-named noun for a command, so I made sure to merge those commands into one that used a singular noun.&lt;/p&gt;
&lt;h3&gt;Providing feedback&lt;/h3&gt;
&lt;p&gt;Feedback from the community drives any project, and this module is no different. I encourage anyone who uses this module to please let me know what they like and don&amp;rsquo;t like about it. Any bugs that you find or anything that you feel would make a good feature is always helpful to the growth of PoshWSUS. You can log issues and ideas in the &lt;a href="http://poshwsus.codeplex.com/workitem/list/basic" target="_blank"&gt;CodePlex Issue Tracker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That pretty much sums up my module, PoshWSUS and gives you a little more information about its beginnings and some of the new things I did with version 2.0. Tomorrow I will go into how to use PoshWSUS, explore some of the commands, show you how to achieve some of the same results from some of the commands we have been using during the past week, and show you a few new things. See you tomorrow!&lt;/p&gt;
&lt;p&gt;~Boe&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3475009" width="1" height="1" alt="" /&gt;</description></item><item><title>Get Windows Update Status Information by Using PowerShell</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/01/20/get-windows-update-status-information-by-using-powershell.aspx</link><pubDate>Fri, 20 Jan 2012 06:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:14113</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: Learn how to use the WSUS Update Scope with Windows PowerShell to get update status information for client computers.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. What a week. Boe Prox has certainly been sharing quite a bit of Windows PowerShell goodness. In case you have missed them, here are links to the blog series thus far. You can also see Boe&amp;rsquo;s biography in the Day&amp;nbsp;1 blog.&lt;/p&gt;
&lt;p&gt;Day 1: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/16/introduction-to-wsus-and-powershell.aspx" target="_blank"&gt;Introduction to WSUS and PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 2: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/17/use-powershell-to-perform-basic-administrative-tasks-on-wsus.aspx" target="_blank"&gt;Use PowerShell to Perform Basic Administrative Tasks on WSUS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 3: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/18/approve-or-decline-wsus-updates-by-using-powershell.aspx" target="_blank"&gt;Approve or Decline WSUS Updates by Using PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 4: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/19/use-powershell-to-find-missing-updates-on-wsus-client-computers.aspx" target="_blank"&gt;Use PowerShell to Find Missing Updates on WSUS Client Computers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Today we are moving from working with the Computer Target Scope and generating some cool reports to working with the Update Scope on the WSUS server. Much like yesterday, I will dive into some of the objects that we have worked with throughout the week and make use of some of the methods that require the Update Scope object to work properly.&lt;/p&gt;
&lt;p&gt;If you are asking, &amp;ldquo;What is the Update Scope?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;hellip;As the name implies, this is a scope that can be used to filter a list of updates on the WSUS server.&lt;/p&gt;
&lt;h3&gt;Creating the Update Scope object&lt;/h3&gt;
&lt;p&gt;Much as we did with the Computer Target Scope object, we need first to create the Update Scope object so we can then look at its properties and make adjustments, if needed. To create this object, we need to use the &lt;b&gt;Microsoft.UpdateServices.Administration.UpdateScope&lt;/b&gt; class. For more information about this class, see &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.updateservices.administration.updatescope%28v=VS.85%29.aspx" target="_blank"&gt;UpdateScope Class&lt;/a&gt; on MSDN. The code that follows creates an instance of the &lt;b&gt;UpdateScope&lt;/b&gt;&lt;i&gt;.&lt;/i&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope&lt;/p&gt;
&lt;p&gt;OK, let&amp;rsquo;s take a look at these properties. The image that follows displays this information.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5001.hsg_2D00_1_2D00_20_2D00_12_2D00_1.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5001.hsg_2D00_1_2D00_20_2D00_12_2D00_1.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is a list of the editable properties for the Update Scope object:&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ApprovedStates&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the approval states to search for. An update will be included only if it matches at least one of the specified states. This value may be a combination of any number of values from ApprovedStates. Defaults to Any.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ExcludedInstallationStates&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the installation states to exclude. An update will be included only if it does not have any computers in any of the specified states. This value may be a combination of any number of values from UpdateInstallationStates. Defaults to 0.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ExcludeOptionalUpdates&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets whether to exclude optional updates from the list.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;FromArrivalDate&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the minimum arrival date to search for. An update will be included only if its arrival date is greater than or equal to this value.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;FromCreationDate&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the minimum creation date to search for. An update will be included only if its creation date is greater than or equal to this value.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;IncludedInstallationStates&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the installation states to search for. An update will be included only if it has at least one computer in one of the specified states. This value may be a combination of any number of values from &lt;b&gt;UpdateInstallationStates&lt;/b&gt;.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;IsWsusInfrastructureUpdate&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets whether or not to filter for WSUS infrastructure updates. If set to &lt;b&gt;true&lt;/b&gt;, only WSUS infrastructure updates will be included. If set to &lt;b&gt;false&lt;/b&gt;, all updates are included. Defaults to false.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;TextIncludes&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the string to search for. An update will be included only if its Title, Description, Knowledge Base articles, or security bulletins contains this string.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;TextNotIncludes&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the string to exclude. An update will be not be included if its Title, Description, Knowledge Base articles, or security bulletins contains this string.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ToArrivalDate&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the maximum arrival date to search for. An update will be included only if its arrival date is less than or equal to this value.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ToCreationDate&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the maximum creation date to search for. An update will be included only if its creation date is less than or equal to this value.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;UpdateApprovalActions&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the update approval actions to search for. An update will be included only if it is approved to at least one computer target group for one of the specified approval actions. This value may be a combination of any number of values from UpdateApprovalActions. Defaults to All.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;UpdateApprovalScope&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the UpdateApprovalScope object that can be used to filter updates based on their approval properties.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;UpdateSources&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the update sources to search for. An update will be included only if its update source is included in this value. This value may be a combination of any number of values from UpdateSources.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;UpdateTypes&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the update types to search for. An update will be included only if its update type is included in this value.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Yes, that is a fairly large list of properties that we can modify to suit our filtering needs. For the sake of simplicity, I am only going to update &lt;b&gt;ApprovedStates, IncludedInstallationStates&lt;/b&gt;,&lt;b&gt; &lt;/b&gt;and&lt;b&gt; FromArrivalTime&lt;/b&gt; to show how you can see all of the updates that are needed by all of the clients since the last patch Tuesday. The code that follows updates these three properties.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::NotApproved&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::NotInstalled&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.FromArrivalDate = [datetime]&amp;quot;12/13/2011&amp;quot;&lt;/p&gt;
&lt;p&gt;Note: For the purposes of this blog, the last patch Tuesday was December 13. I set the &lt;b&gt;ApprovedStates&lt;/b&gt; property to &lt;b&gt;NotApproved&lt;/b&gt; because I only want to see updates that are required by the clients that are not already approved for installation. I set the &lt;b&gt;IncludedInstallationStates&lt;/b&gt; to &lt;b&gt;NotInstalled&lt;/b&gt;. This will tell the filter to look for only updates that are required by the clients, but have not been installed yet. This works fine for us because these updates are new to us and because we only want those for the most recent patch Tuesday.&lt;/p&gt;
&lt;p&gt;First, I am going to show you the Administration Console and look at all updates that are required by the clients on the network since patch Tuesday. This is shown in the image that follows.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1537.hsg_2D00_1_2D00_20_2D00_12_2D00_2.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1537.hsg_2D00_1_2D00_20_2D00_12_2D00_2.jpg" alt="Image of menu" title="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note the number of updates (30) and some of the titles listed here. Although not all of the updates are listed in the image, I will show you a couple of methods that we can use to pull the exact same information by using Windows PowerShell!&lt;/p&gt;
&lt;p&gt;&lt;b&gt;GetUpdateCount()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This method, as you can probably tell, will allow us to view the number of updates that are returned by using the previously configured Update Scope.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetUpdateCount($updatescope)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0066.hsg_2D00_1_2D00_20_2D00_12_2D00_3.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0066.hsg_2D00_1_2D00_20_2D00_12_2D00_3.jpg" alt="Image of computer output" title="Image of computer output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Look at that, 30 updates&amp;mdash;just as if it showed on the console.&lt;/p&gt;
&lt;p&gt;I am going to expand on this slightly by using another method similar to one I showed you yesterday for the Computer Target Scope.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;GetUpdateStatus()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This will return a little more information about the updates, as you will see. Besides supplying the Update Scope object, I need to supply a Boolean value for whether to include DownStream Computers.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetUpdateStatue($updatescope,$False)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0508.hsg_2D00_1_2D00_20_2D00_12_2D00_4.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0508.hsg_2D00_1_2D00_20_2D00_12_2D00_4.jpg" alt="Image of computer output" title="Image of computer output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That is pretty cool, but we want to see those updates as well. Sure enough, we can use the &lt;b&gt;GetUpdates()&lt;/b&gt; method and supply our Update Scope object to pull this information.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetUpdates($updatescope) | Select Title&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4380.hsg_2D00_1_2D00_20_2D00_12_2D00_5.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4380.hsg_2D00_1_2D00_20_2D00_12_2D00_5.jpg" alt="Image of computer output" title="Image of computer output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And there you have it! You can compare the screenshots and you will see that the titles in the console match the titles from our query.&lt;/p&gt;
&lt;p&gt;Now I will show you how to view the update approvals by using the Update Scope object and the &lt;b&gt;GetUpdateApprovals()&lt;/b&gt; method. To make this work and to provide some useful information, I will make a couple of adjustments to the existing Update Scope. This revision is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.FromArrivalDate = [datetime]&amp;quot;10/01/2011&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::LatestRevisionApproved&lt;/p&gt;
&lt;p&gt;Now we can use this scope in the method and pull some information. To do this, I use the &lt;b&gt;GetUpdateApprovals &lt;/b&gt;method, and pass it the Update Scope. This technique is shown in the code that follows.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetUpdateApprovals($updatescope)&lt;/p&gt;
&lt;p&gt;The result from the previous command is shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8078.hsg_2D00_1_2D00_20_2D00_12_2D00_6.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8078.hsg_2D00_1_2D00_20_2D00_12_2D00_6.jpg" alt="Image of computer output" title="Image of computer output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let us clean this up a little so it is more readable and not just a bunch of GUIDs. The code that follows produces an easier to read output.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetUpdateApprovals($updatescope) | Select @{L=&amp;#39;ComputerTargetGroup&amp;#39;;E={$_.GetComputerTargetGroup().Name}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;@{L=&amp;#39;UpdateTitle&amp;#39;;E={($wsus.GetUpdate([guid]$_.UpdateId.UpdateId.Guid)).Title}},GoLiveTime,AdministratorName,Deadline&lt;/p&gt;
&lt;p&gt;The result of the previous code is shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8561.hsg_2D00_1_2D00_20_2D00_12_2D00_7.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8561.hsg_2D00_1_2D00_20_2D00_12_2D00_7.jpg" alt="Image of computer output" title="Image of computer output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The last two things I will show you in this blog are a couple of methods that require the Update Scope object and the Computer Target Scope object to work properly. They provide some nice reporting features similar to what you would see in the Administration Console.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;GetSummariesPerComputerTarget()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This method gets per-computer summaries for each of the specified computers, summed across all of the specified updates.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see this in action, where I use the following code to gather this information.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetSummariesPerComputerTarget($updatescope,$computerscope) |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Format-Table @{L=&amp;#39;ComputerTarget&amp;#39;;E={($wsus.GetComputerTarget([guid]$_.ComputerTargetId)).FullDomainName}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @{L=&amp;#39;NeededCount&amp;#39;;E={($_.DownloadedCount + $_.NotInstalledCount)}},DownloadedCount,NotApplicableCount,NotInstalledCount,InstalledCount,FailedCount&lt;/p&gt;
&lt;p&gt;The output from the previous code produces a nice table, as shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5811.hsg_2D00_1_2D00_20_2D00_12_2D00_8.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5811.hsg_2D00_1_2D00_20_2D00_12_2D00_8.jpg" alt="Image of computer output" title="Image of computer output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how this compares to what you would see in the console. One thing you do not have available in the console is the &lt;b&gt;DownloadedCount&lt;/b&gt;, which our previous code nicely displayed.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7462.hsg_2D00_1_2D00_20_2D00_12_2D00_9.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7462.hsg_2D00_1_2D00_20_2D00_12_2D00_9.jpg" alt="Image of menu" title="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Lastly, let&amp;rsquo;s look at the &lt;b&gt;GetSummariesPerUpdate()&lt;/b&gt; method to get per-update summaries for each of the specified updates, summed across all of the specified computers. The following code uses this method.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::NotApproved&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::NotInstalled&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updatescope.FromArrivalDate = [datetime]&amp;quot;12/13/2011&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetSummariesPerUpdate($updatescope,$computerscope) |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Format-Table @{L=&amp;#39;UpdateTitle&amp;#39;;E={($wsus.GetUpdate([guid]$_.UpdateId)).Title}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @{L=&amp;#39;NeededCount&amp;#39;;E={($_.DownloadedCount + $_.NotInstalledCount)}},DownloadedCount,NotApplicableCount,NotInstalledCount,InstalledCount,FailedCount&lt;/p&gt;
&lt;p&gt;Note: I changed the Update Scope to what I had at the beginning of this blog. This is so I can more accurately compare the output here with what is in the Administration Console.&lt;/p&gt;
&lt;p&gt;The output from the previous code is shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3201.hsg_2D00_1_2D00_20_2D00_12_2D00_10.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3201.hsg_2D00_1_2D00_20_2D00_12_2D00_10.jpg" alt="Image of computer output" title="Image of computer output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now compare the previous image, with the console (shown here), and you will see that they match up as planned.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7848.hsg_2D00_1_2D00_20_2D00_12_2D00_11.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7848.hsg_2D00_1_2D00_20_2D00_12_2D00_11.jpg" alt="Image of menu" title="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So there you have it. We spent the week starting out with a WSUS server installation, then doing some basic administration, and we finished by providing some reports using Windows PowerShell&amp;mdash;and we haven&amp;rsquo;t even begun to scratch the surface of what we can do. But working with WSUS doesn&amp;rsquo;t end here! This weekend I will talk about update&amp;nbsp;2.0 to my WSUS module, &lt;a href="http://poshwsus.codeplex.com/" target="_blank"&gt;PoshWSUS&lt;/a&gt;, which you can use to more easily manage and maintain a WSUS server.&lt;/p&gt;
&lt;p&gt;~Boe&lt;/p&gt;
&lt;p&gt;Boe, this is great stuff. Thank you for sharing with us. WSUS Week will continue tomorrow.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3474980" width="1" height="1" alt="" /&gt;</description></item><item><title>Use PowerShell to Find Missing Updates on WSUS Client Computers</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/01/19/use-powershell-to-find-missing-updates-on-wsus-client-computers.aspx</link><pubDate>Thu, 19 Jan 2012 06:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:14086</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;b&gt;ummary&lt;/b&gt;: Learn how to use the computer target scope with Windows PowerShell to find WSUS client computers that are missing updates.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. We are halfway through WSUS Week and some really good stuff from Boe Prox. You can see Boe&amp;rsquo;s biography in the Day 1 blog. In case you need to catch up with the series on Windows Software Update Services (WSUS), the following blogs will get you up to speed:&lt;/p&gt;
&lt;p&gt;Day 1: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/16/introduction-to-wsus-and-powershell.aspx" target="_blank"&gt;Introduction to WSUS and PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 2: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/17/use-powershell-to-perform-basic-administrative-tasks-on-wsus.aspx" target="_blank"&gt;Use PowerShell to Perform Basic Administrative Tasks on WSUS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Day 3: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/18/approve-or-decline-wsus-updates-by-using-powershell.aspx" target="_blank"&gt;Approve or Decline WSUS Updates by Using PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, here is Boe&amp;hellip;&lt;/p&gt;
&lt;p&gt;Over the past few days, I have been showing you some basic administration examples of what you can do by using Windows PowerShell to manage a WSUS server. During the course of some of these examples, I alluded to some methods that required a Computer Target Scope object. Well, today is the day that I get to show you how you can build a Computer Target Scope object and use that with some of the existing objects we have already created.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;What is the Computer Target Scope?&amp;rdquo; you ask? The Computer Target Scope is, as the name implies, a scope that that can be used to filter a list of clients. For more information about this class, see &lt;a href="http://msdn.microsoft.com/en-us/library/aa354282%28v=VS.85%29.aspx" target="_blank"&gt;ComputerTargetScope Class&lt;/a&gt; on MSDN.&lt;/p&gt;
&lt;h3&gt;Creating the Computer Target Scope object&lt;/h3&gt;
&lt;p&gt;The first thing we need to do is create the scope object, which we can then use in some of the methods we have seen. To do this will require us to create the new object from the &lt;b&gt;Microsoft.UpdateServices.Administration.ComputerTargetScope &lt;/b&gt;class.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope&lt;/p&gt;
&lt;p&gt;Simple enough to do, and we can choose to leave the default properties that are already set for this object if we want to.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8244.hsg_2D00_1_2D00_19_2D00_12_2D00_1.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8244.hsg_2D00_1_2D00_19_2D00_12_2D00_1.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So as a default object, this will reference all clients on the WSUS server. Fortunately, you can edit most of these properties to narrow down the clients that you want to use. Here is a list of the editable properties:&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ExcludedInstallationStates&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the installation states to exclude.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;FromLastReportedStatusTime&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the earliest reported status time.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;FromLastSyncTime&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the earliest last synchronization time to search for.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;IncludedInstallationStates&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the update installation states to search for.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;IncludeDownstreamComputerTargets&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets whether or not clients of a downstream server, not clients of this server, should be included.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;IncludeSubgroups&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets whether the ComputerTargetGroups property should include descendant groups.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;NameIncludes&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets a name to search for.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;OSFamily&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the operating system family for which to search.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ToLastReportedStatusTime&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the latest last reported status time to search for.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;ToLastSyncTime&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Gets or sets the latest last synchronization time to search for.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Working with the Computer Target Scope&lt;/h3&gt;
&lt;p&gt;Now, if you remember from the previous posts, there are some methods from the &lt;b&gt;Update&lt;/b&gt; object (&lt;b&gt;Microsoft.UpdateServices.Internal.BaseApi.Update&lt;/b&gt;) and from the WSUS object (&lt;b&gt;Microsoft.UpdateServices.Internal.BaseApi.UpdateServer&lt;/b&gt;) that require a computer scope object to work.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at some of these methods from the respective objects and see what we are able to pull.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[void][reflection.assembly]::LoadWithPartialName(&amp;quot;Microsoft.UpdateServices.Administration&amp;quot;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Connect to the WSUS Server and create the wsus object&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer(&amp;#39;dc1&amp;#39;,$False)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Create a computer scope object&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#Find all clients using the computer target scope&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetComputerTargets($computerscope)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8371.hsg_2D00_1_2D00_19_2D00_12_2D00_2.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8371.hsg_2D00_1_2D00_19_2D00_12_2D00_2.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By leaving the default properties, we will pull every client from the WSUS server.&lt;/p&gt;
&lt;p&gt;Another method that we can use, which provides a report on the computers that match the scope filter is &lt;b&gt;GetComputerStatus()&lt;/b&gt;. This method requires that you have a computer scope object and that you define a &lt;b&gt;Microsoft.UpdateServices.Administration.UpdateSources&lt;/b&gt; object, which consists of &lt;b&gt;All&lt;/b&gt;, &lt;b&gt;Microsoft Update&lt;/b&gt;, or &lt;b&gt;Other&lt;/b&gt;. Let&amp;rsquo;s give it a look.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$Wsus.GetComputerStatus($computerscope,[&lt;b&gt; &lt;/b&gt;Microsoft.UpdateServices.Administration.UpdateSources]::All)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1732.hsg_2D00_1_2D00_19_2D00_12_2D00_3.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1732.hsg_2D00_1_2D00_19_2D00_12_2D00_3.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You might be wondering why we are seeing mostly &lt;b&gt;0&lt;/b&gt;s here. If you look closely, you can see that only the areas where it mentions the computer targets are populated. This is by design for this object&amp;rsquo;s method because we only specified to get the status of the computers that match the scope filter.&lt;/p&gt;
&lt;p&gt;Now, looking at the update object&amp;rsquo;s method, I can see a couple of methods that are available and require the computer scope.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;GetSummary()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This will give us a summary of whether the clients that are specified in the scope require the update.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates = $wsus.SearchUpdates(&amp;#39;Update for Windows Server 2003 (KB938759)&amp;#39;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update = $updates[0]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update.GetSummary($computerscope)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;UnknownCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;NotApplicableCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;NotInstalledCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;DownloadedCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;InstalledCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;InstalledPendingRebootCount : 0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;FailedCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;IsSummedAcrossAllUpdates&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;UpdateId&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : c2cdd066-7a03-4e7f-976c-139b5de943ed&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;ComputerTargetGroupId&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 00000000-0000-0000-0000-000000000000&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;ComputerTargetId&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;LastUpdated&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: 12/10/2011 7:08:29 AM&lt;/p&gt;
&lt;p&gt;By looking at the data provided, I can see that only 1 client out of the 3 require this update and that it has already been downloaded to that client. This is a nice way of providing a report of a specific update&amp;rsquo;s status for clients. But the problem is&amp;hellip;which client requires the update? I will show you how to use the &lt;b&gt;GetUpdateInstallationInfoPerComputerTarget()&lt;/b&gt; method on the Update object.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update.GetUpdateInstallationInfoPerComputerTarget($ComputerScope)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3652.hsg_2D00_1_2D00_19_2D00_12_2D00_4.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3652.hsg_2D00_1_2D00_19_2D00_12_2D00_4.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Although it &lt;b&gt;does&lt;/b&gt; tell you which client ID requires the update, it&amp;rsquo;s not what I would call &amp;ldquo;humanly readable&amp;rdquo; by any means. But this is Windows PowerShell, after all, and we can certainly make this better for us to read.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update.GetUpdateInstallationInfoPerComputerTarget($ComputerScope) |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Select @{L=&amp;#39;Client&amp;#39;;E={$wsus.GetComputerTarget(([guid]$_.ComputerTargetId)).FulldomainName}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;@{L=&amp;#39;TargetGroup&amp;#39;;E={$wsus.GetComputerTargetGroup(([guid]$_.UpdateApprovalTargetGroupId)).Name}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;@{L=&amp;#39;Update&amp;#39;;E={$wsus.GetUpdate(([guid]$_.UpdateId)).Title}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;UpdateInstallationState,UpdateApprovalAction&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0486.hsg_2D00_1_2D00_19_2D00_12_2D00_5.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0486.hsg_2D00_1_2D00_19_2D00_12_2D00_5.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Much better! Now we have something that not only tells us which client, but actually gives us the name of the client without giving us a GUID to try to guess with. I also translated the Target Group ID and the Update ID so that everything is much easier to read.&lt;/p&gt;
&lt;p&gt;Well, that wraps it up for today. Tomorrow I will jump into working with the Update&amp;nbsp;Scope object and performing queries that use that object.&lt;/p&gt;
&lt;p&gt;~Boe&lt;/p&gt;
&lt;p&gt;Boe, thank you for another great blog about using the WSUS object model. WSUS Week will continue tomorrow.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3474944" width="1" height="1" alt="" /&gt;</description></item><item><title>Approve or Decline WSUS Updates by Using PowerShell</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/01/18/approve-or-decline-wsus-updates-by-using-powershell.aspx</link><pubDate>Wed, 18 Jan 2012 06:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:14060</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Guest blogger, Boe Prox, shows how to use Windows PowerShell to approve or to decline updates for WSUS.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Welcome to the third day of Boe Prox as our guest blogger talking about using Windows PowerShell with WSUS.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Day 1: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/16/introduction-to-wsus-and-powershell.aspx" target="_blank"&gt;Introduction to WSUS and PowerShell&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Day 2: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/01/17/use-powershell-to-perform-basic-administrative-tasks-on-wsus.aspx" target="_blank"&gt;Use PowerShell to Perform Basic Administrative Tasks on WSUS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s Boe&amp;hellip;&lt;/p&gt;
&lt;p&gt;Continuing on from yesterday&amp;rsquo;s post where we looked at managing clients and groups, it is time to look at that one thing that really defines the WSUS server. I am talking about updates, of course! We will start by performing a basic query to locate updates and explore the update object to see what methods we have available, and then we will go into approving and declining updates.&lt;/p&gt;
&lt;h3&gt;Update queries&lt;/h3&gt;
&lt;p&gt;Using our existing connection from the previous day&amp;rsquo;s examples, let&amp;rsquo;s look at the possible methods related to locating updates on the WSUS server.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;GetUpdates()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This method will give you back EVERY SINGLE UPDATE on your WSUS server. (This is assuming that you have completed a successful synchronization&amp;mdash;if not, synchronize your WSUS server now.) This method is painfully slow to run and it is not a recommended method to gather information about updates.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetUpdates()&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0005.hsg_2D00_1_2D00_18_2D00_12_2D00_1.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/450x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0005.hsg_2D00_1_2D00_18_2D00_12_2D00_1.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip;Well, this is awkward. Oh wait, since I just installed this WSUS server, I have not performed a critical task that will allow me to start viewing updates. I need to synchronize this WSUS server with the Microsoft upstream server and get all of my update data.&lt;/p&gt;
&lt;h3&gt;WSUS synchronization&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s take a detour on our little trip through working with updates to get this server synced up and ready to go. To get this going, we need to look at the &lt;b&gt;GetSubscription() &lt;/b&gt;method to see when the last synchronization was and also to use that object&amp;rsquo;s method to work with the synchronization. The object that is returned when you use this method is &lt;b&gt;Microsoft.UpdateServices.Internal.BaseApi.Subscription&lt;/b&gt;.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetSubscription()&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7345.hsg_2D00_1_2D00_18_2D00_12_2D00_2.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7345.hsg_2D00_1_2D00_18_2D00_12_2D00_2.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take a look at LastSynchronizationTime, and you will see that this WSUS server has not been synced yet. Synching this server is pretty simple. We will use this object&amp;rsquo;s method, which is conveniently named &lt;b&gt;StartSynchronization(). &lt;/b&gt;Let&amp;rsquo;s go ahead and kick this off.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription = $wsus.GetSubscription()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.StartSynchronization()&lt;/p&gt;
&lt;p&gt;Nothing is returned when you kick this off, so we need a way to track this process and find out when it is finished. Enter the &lt;b&gt;GetSynchronizationProgress()&lt;/b&gt; method, which will tell us exactly where we are with the sync process.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$subscription.GetSynchronizationProgress()&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5488.hsg_2D00_1_2D00_18_2D00_12_2D00_3.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5488.hsg_2D00_1_2D00_18_2D00_12_2D00_3.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is slowly getting there. I will check back shortly and see if it has completed yet.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0508.hsg_2D00_1_2D00_18_2D00_12_2D00_4.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0508.hsg_2D00_1_2D00_18_2D00_12_2D00_4.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There we go. Now we are ready to jump back into working with updates.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s try this again&amp;hellip;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$updates = $wsus.GetUpdates()&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6763.hsg_2D00_1_2D00_18_2D00_12_2D00_5.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6763.hsg_2D00_1_2D00_18_2D00_12_2D00_5.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s more like it. Now I have over 5500 updates to work with.&lt;/p&gt;
&lt;p&gt;As you can see, calling &lt;b&gt;GetUpdates()&lt;/b&gt; will get every single update on the server. But, what if we only want to get a specific update or updates? Instead of getting all of the updates and using &lt;b&gt;Where-Object&lt;/b&gt; to filter them, you can use one of the following methods to accomplish that goal. (By the way, there is one more thing that we can use with &lt;b&gt;GetUpdates()&lt;/b&gt; to get specific updates, but I am leaving that piece out until later in the week.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;$wsus.GetUpdate()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This method is quick to get the update that you are looking for. The only issue is that this method requires you to know the update ID, which is a GUID. Not exactly something a person will know off of the top of one&amp;rsquo;s head, but it is an option regardless.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus.GetUpdate([guid]&amp;rdquo; fc08b450-6bdd-400e-9a1a-2f86e23ce462&amp;rdquo;)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0412.hsg_2D00_1_2D00_18_2D00_12_2D00_6.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0412.hsg_2D00_1_2D00_18_2D00_12_2D00_6.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, on to the last way to get more specific updates&amp;mdash;this time using the following method:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;SearchUpdates()&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;This method is very flexible to use because it only requires a string for input. This string can be anything from the KB number for the patch, the actual patch name, or even something as simple as the type of system that the patch would be installed on (such as Exchange Server). Let&amp;rsquo;s look at a few examples of performing some searches:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$SQL = $wsus.SearchUpdates(&amp;lsquo;SQL&amp;rsquo;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$SQL.count&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$SQL | Select Title&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0508.hsg_2D00_1_2D00_18_2D00_12_2D00_7.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0508.hsg_2D00_1_2D00_18_2D00_12_2D00_7.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update = $wsus.SearchUpdates(&amp;#39;943485&amp;#39;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update.count&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update | Select Title&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7457.hsg_2D00_1_2D00_18_2D00_12_2D00_8.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7457.hsg_2D00_1_2D00_18_2D00_12_2D00_8.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$patches = $wsus.SearchUpdates(&amp;lsquo;Windows 7&amp;rsquo;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$patches.count&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$patches | Select Title&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6330.hsg_2D00_1_2D00_18_2D00_12_2D00_9.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6330.hsg_2D00_1_2D00_18_2D00_12_2D00_9.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now that we know how to find updates on the WSUS server, we can start to explore the update object (&lt;b&gt;Microsoft.UpdateServices.Internal.BaseApi.Update&lt;/b&gt;).&lt;/p&gt;
&lt;p&gt;There quite a few methods that are available for the update object, so we will focus on three methods that are pretty useful for administering updates on the server.&lt;/p&gt;
&lt;h3&gt;Accepting license agreements&lt;/h3&gt;
&lt;p&gt;You might be asking me why accepting license agreements would be one of the three things that I would want to focus on. Well, this is not an issue&amp;hellip;until it becomes an issue when you are trying to approve an update. There is a property that has a Boolean value called &lt;b&gt;RequireLicenseAgreementAcceptance&lt;/b&gt; that we can use in our filtering to locate any updates that require a license acceptance before you can approve the updates.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$license = $updates | Where {$_.RequiresLicenseAgreementAcceptance}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$license | Select Title&lt;/p&gt;
&lt;p&gt;We can use the method &lt;b&gt;AcceptLicenseAgreement()&lt;/b&gt; to accept the agreement for the update.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$license | ForEach {$_.AcceptLicenseAgreement()}&lt;/p&gt;
&lt;p&gt;With that, all of the updates that had a requirement to accept a license agreement have been taken care of, allowing us to start approving some updates!&lt;/p&gt;
&lt;h3&gt;Approving updates&lt;/h3&gt;
&lt;p&gt;There are three ways that you can approve updates on the WSUS server by using PowerShell&amp;mdash;one by using &lt;b&gt;ApproveForOptionalInstall()&lt;/b&gt; and two by using &lt;b&gt;Approve()&lt;/b&gt;. They require that we use the TargetGroup object to tell the server what group we will approve each update for. Yesterday, I talked about how to get a target group; now we can easily grab a group to use for each type of approval. The &lt;b&gt;Approve&lt;/b&gt; method also requires that you pick an installation action (I will go into more detail when we get to that method).&lt;/p&gt;
&lt;p&gt;The main difference between &lt;b&gt;ApproveForOptionalInstall&lt;/b&gt; and &lt;b&gt;Approve&lt;/b&gt; is that &lt;b&gt;ApproveForOptionalInstall&lt;/b&gt; will approve the update for the target group, but the update will not actually install. However, it is made available to the user for installation via &lt;b&gt;Add/Remove Programs&lt;/b&gt;. &lt;b&gt;Approve&lt;/b&gt; will approve the update with or without a deadline (your choice&amp;mdash;I will explain later how to do this).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with the optional installation first&amp;hellip;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update = $wsus.SearchUpdates(&amp;#39;Windows 7 for x64-based Systems (KB2639417)&amp;#39;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$group = $wsus.GetComputerTargetGroups() | where {$_.Name -eq &amp;#39;TESTGROUP&amp;#39;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update[0].ApproveForOptionalInstall($Group)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2626.hsg_2D00_1_2D00_18_2D00_12_2D00_10.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2626.hsg_2D00_1_2D00_18_2D00_12_2D00_10.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here I approved a Windows&amp;nbsp;7 update for my TESTGROUP in which my laptop is currently a member. Notice that it returns another object called &lt;b&gt;Microsoft.UpdateServices.Internal.BaseApi.UpdateApproval&lt;/b&gt;. This object tells you when it was approved, the time that the update will &amp;ldquo;go live,&amp;rdquo; and who approved the update. It is important to note that the update object you get is a collection, even if you only get one item back. Therefore, I had to be sure to use the first index of the collection to use this method for approval.&lt;/p&gt;
&lt;p&gt;By using &lt;b&gt;Approve()&lt;/b&gt; method, we have two ways in which to approve the updates. Both require that you have the target group object, but one also has the requirement of setting a deadline by using the &lt;b&gt;[datetime]&lt;/b&gt; object.&lt;/p&gt;
&lt;p&gt;Do you remember when I mentioned using an installation action for the approval? Well, now it is time to use one of those actions for this approval. But how do we know what installation actions we can use? We will find out what our options are by using&lt;b&gt; Microsoft.UpdateServices.Administration.UpdateApprovalAction&lt;/b&gt;.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[Microsoft.UpdateServices.Administration.UpdateApprovalAction] | gm -static -Type Property | Select &amp;ndash;expand Name&lt;/p&gt;
&lt;p&gt;The installation actions that are returned are:&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;b&gt;All&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;b&gt;Install&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;b&gt;NotApproved&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;b&gt;Uninstall&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Now that we know what kinds of actions we can use, let&amp;rsquo;s make an approval without using a deadline.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update = $wsus.SearchUpdates(&amp;lsquo;Update for 2007 Microsoft Office System (KB932080)&amp;#39;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$group = $wsus.GetComputerTargetGroups() | where {$_.Name -eq &amp;#39;TESTGROUP&amp;#39;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update[0].Approve(&amp;ldquo;Install&amp;rdquo;,$Group)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6170.hsg_2D00_1_2D00_18_2D00_12_2D00_11.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6170.hsg_2D00_1_2D00_18_2D00_12_2D00_11.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Again, the same object type is returned with the same data that we would expect.&lt;/p&gt;
&lt;p&gt;We can set a deadline on our next update for approval. Basically, setting a deadline on a patch will force that update to be installed at that specific time. For instance, I will approve an update that will get installed on Dec. 15 at 11:00 PM.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update = $wsus.SearchUpdates(&amp;lsquo;932080&amp;rsquo;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$group = $wsus.GetComputerTargetGroups() | where {$_.Name -eq &amp;#39;TESTGROUP&amp;#39;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update[0].Approve(&amp;ldquo;Install&amp;rdquo;,$Group,[datetime]&amp;rdquo;12/15/2011 11:00PM&amp;rdquo;)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6735.hsg_2D00_1_2D00_18_2D00_12_2D00_12.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6735.hsg_2D00_1_2D00_18_2D00_12_2D00_12.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice that the &lt;b&gt;Deadline&lt;/b&gt; is set to the time that I specified instead of it being way out in the year 9999. Now the update will install on the server at that specific time without manual intervention.&lt;/p&gt;
&lt;p&gt;You might be asking, &amp;ldquo;How were you able to determine what updates were required by your systems?&amp;rdquo; Well, besides jumping into the WSUS Administration Console to view those updates, there is another way that I can locate updates, but that will have to wait until later this week when I introduce another object and way to search for updates.&lt;/p&gt;
&lt;h3&gt;Declining an update&lt;/h3&gt;
&lt;p&gt;So we have approved updates, but we also need to know how to decline updates that are not needed by any system or are deemed unneeded by us for various reasons. Luckily, declining an update is as simple as using the &lt;b&gt;Decline() &lt;/b&gt;method.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update = $wsus.SearchUpdates(&amp;lsquo;932080&amp;rsquo;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$update[0].Decline()&lt;/p&gt;
&lt;p&gt;Unlike the approvals, no object is returned when you decline an update. Regardless, this is a simple and effective way to decline updates that you do not need.&lt;/p&gt;
&lt;p&gt;That wraps it up for today&amp;rsquo;s blog focusing on update management by using Windows PowerShell. Although I really only scratched the surface of working with updates, I hope I was able to give you enough information to make the leap into patch management using Windows PowerShell. Tomorrow I will dive into working with the computer scope object and how you can use that object with some of the objects we have seen this week and some of their associated methods that only accept the computer scope object.&lt;/p&gt;
&lt;p&gt;~Boe&lt;/p&gt;
&lt;p&gt;Boe, thank you once again for a very useful and informative blog about using Windows PowerShell and WSUS. WSUS Week will continue tomorrow.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3474817" width="1" height="1" alt="" /&gt;</description></item><item><title>Introduction to WSUS and PowerShell</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/01/16/introduction-to-wsus-and-powershell.aspx</link><pubDate>Mon, 16 Jan 2012 06:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:14032</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Guest blogger, Boe Prox, shows how to use Windows PowerShell to install WSUS and conimage clients for updates.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. You are in for a treat this week. Boe Prox has written a week&amp;rsquo;s worth of goodies, and we will share them here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7558.HSG_2D00_1_2D00_16_2D00_12_2D00_1.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/150x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7558.HSG_2D00_1_2D00_16_2D00_12_2D00_1.jpg" alt="Photo of Boe Prox" title="Photo of Boe Prox" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Boe Prox is currently a senior systems administrator with BAE Systems. He has been in the IT industry since 2003, and he has been working with &lt;a href="http://technet.microsoft.com/en-us/scriptcenter/powershell.aspx" target="_blank"&gt;Windows PowerShell&lt;/a&gt; since 2009. Boe looks to script whatever he can, whenever he can. He is also a moderator on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Hey, Scripting Guy! Forum&lt;/a&gt;. Check out his current projects published on CodePlex: &lt;a href="http://poshwsus.codeplex.com/" target="_blank"&gt;PoshWSUS&lt;/a&gt; and &lt;a href="http://poshpaig.codeplex.com/" target="_blank"&gt;PoshPAIG&lt;/a&gt;.&lt;br /&gt; Boe&amp;rsquo;s blog: &lt;a href="http://learn-powershell.net/" target="_blank"&gt;Learn PowerShell | Achieve More&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, without further ado, here is Boe!&lt;/p&gt;
&lt;p&gt;For those of you who are unfamiliar with Windows Software Update Services (WSUS), I am going to start with a brief description of what WSUS is and how it is used to manage patching in an environment. Then I will dive into installing the server by using Windows PowerShell, configuring clients via GPO or the registry to report to the WSUS server and to receive the updates from the server. Lastly, I will discuss how to use Windows PowerShell with the associated assemblies for the WSUS Administrator Console to connect to the WSUS Server.&lt;/p&gt;
&lt;h3&gt;What is WSUS?&lt;/h3&gt;
&lt;p&gt;Windows Software Update Services (WSUS) is used by system administrators to manage the distribution of updates and hotfixes that are released by Microsoft for an environment. Currently, the most recent version is WSUS&amp;nbsp;3.0 with Service Pack&amp;nbsp;2, and it is available &lt;a href="http://go.microsoft.com/fwlink/?LinkId=161140" target="_blank"&gt;to download&lt;/a&gt;. This installation allows you to install the full server installation option or only the console installation (which can be installed on any client or server). It also has the assemblies required to use Windows PowerShell to manage the WSUS server. To determine the version of WSUS, refer to &lt;a href="http://technet.microsoft.com/en-us/library/cc720492(WS.10).aspx" target="_blank"&gt;Appendix G: Detect the Version of WSUS&lt;/a&gt; on Microsoft TechNet.&lt;/p&gt;
&lt;h3&gt;Installing a WSUS Server&lt;/h3&gt;
&lt;p&gt;Before you begin the installation of WSUS, make sure you install the following on the selected server:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Internet Information Services (IIS)&lt;/li&gt;
&lt;li&gt;At a minimum, .NET Framework&amp;nbsp;2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You could install WSUS&amp;nbsp;3.0&amp;nbsp;with SP2 on your server by using the file specified in the previous download link and running through the UI installation. But c&amp;rsquo;mon, this is a scripting blog, so surely we can script something out&amp;hellip;right? Right!&lt;/p&gt;
&lt;p&gt;Because there are several switches available with the executable file, we can easily script an unattended installation of the WSUS server along with specific configurations that meet our requirements. For more information about those switches, see &lt;a href="http://technet.microsoft.com/en-us/library/cc708476%28WS.10%29.aspx" target="_blank"&gt;Appendix A: Unattended Installations&lt;/a&gt;. The script I wrote that will allow a local or remote installation of a WSUS server or to install only the WSUS Administration Console is called &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Install-WSUSServerps1-40a8169b" target="_blank"&gt;Install-WSUSServer.ps1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note: I chose to require a dependency for PSExec.exe to complete the remote installation requirements. There were a number of reasons why I chose to do this, but the main reason is that I wanted to make sure that if an issue occurs that cancels the installation, an error would returned in the script that lets you know something happened.&lt;/p&gt;
&lt;p&gt;You can run this script against only one computer at a time. This is because only one SUSDB database can be used for each SQL Server instance (unless you are setting up a WSUS server as a front-end server). You can specify whether to install a console or a server core installation, and it allows for using the internal database installation or a local/remote SQL Server instance to write data to. Lastly, if the required installation file (WSUS30-KB972455-x86.exe or WSUS30-KB972455-x64.exe) is not in the same directory as the script, you will be given a prompt to download the required file to use for installation. I also wrote an &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Uninstall-WSUSServer-218ce694" target="_blank"&gt;Uninstall-WSUSServer.ps1&lt;/a&gt; script that performs exactly like the Install-WSUSServer.ps1 script.&lt;/p&gt;
&lt;p&gt;So enough talking about this script and let&amp;rsquo;s see it in action. First, let&amp;rsquo;s install our WSUS server and make sure that we save the content locally and save that content on the D drive. I am also going to make sure that I &lt;b&gt;do not&lt;/b&gt; have the updates made available so it asks me to download the update prior to the installation.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;. .\Install-WSUSServer.ps1 -Computername DC1 -StoreUpdatesLocally -ContentDirectory &amp;quot;D:\WSUS&amp;quot; -InternalDatabasePath &amp;quot;D:\&amp;quot; &amp;ndash;CreateDatabase &amp;ndash;Verbose&lt;/p&gt;
&lt;p&gt;The command and the associated output are shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6318.hsg_2D00_1_2D00_16_2D00_12_2D00_2.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6318.hsg_2D00_1_2D00_16_2D00_12_2D00_2.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following image shows the newly created folders.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2046.hsg_2D00_1_2D00_16_2D00_12_2D00_3.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2046.hsg_2D00_1_2D00_16_2D00_12_2D00_3.jpg" alt="Image of folders" title="Image of folders" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s fire up the console. To do this, I make an RDP connection to my DC1 server as shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2555.hsg_2D00_1_2D00_16_2D00_12_2D00_4.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2555.hsg_2D00_1_2D00_16_2D00_12_2D00_4.jpg" alt="Image of menu" title="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yep, it&amp;rsquo;s all there! OK, now let&amp;rsquo;s install the Administration Console on my laptop so I can make use of the assemblies for Windows PowerShell integration. Here is the command line that I use to install only the console.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;. .\Install-WSUSServer.ps1 &amp;ndash;ConsoleOnly -verbose&lt;/p&gt;
&lt;p&gt;The following image shows the command that I use to install the console, and the output from the Install-WSUSServer.ps1 script.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1067.hsg_2D00_1_2D00_16_2D00_12_2D00_5.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1067.hsg_2D00_1_2D00_16_2D00_12_2D00_5.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was a little simpler because I already had the installation file that I needed to complete the Administration Console installation.&lt;/p&gt;
&lt;h3&gt;Conimage clients to use WSUS&lt;/h3&gt;
&lt;p&gt;OK, we have our WSUS server installed and running, and we have our Administration Console installed on the laptop. The next step is to conimage my laptop and the server to communicate to the WSUS application so we can image the patches that are required for each client. There are a couple of ways to accomplish this task. If the client is in an Active Directory environment, all you have to is use Group Policy to make the configuration changes.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note: For non-domain systems, you can make this change by using gpedit.msc.&lt;/p&gt;
&lt;p&gt;For the sake of simplicity, I am just going to conimage the GPO to point my client to the WSUS server (&lt;b&gt;Specify intranet Microsoft update service location&lt;/b&gt;), set the update client to only download (&lt;b&gt;Conimage Automatic Updates&lt;/b&gt;) the approved updates, and change the detection to every four hours (&lt;b&gt;Automatic Updates detection frequency&lt;/b&gt;). The changes are reflected in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0312.hsg_2D00_1_2D00_16_2D00_12_2D00_6.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0312.hsg_2D00_1_2D00_16_2D00_12_2D00_6.jpg" alt="Image of menu" title="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another way is to do some registry hacking to make the changes, which leads me to my next set of Windows PowerShell scripts that accomplish this task. The first script allows you to view the settings in the registry and the other script allows you to change the registry settings to conimage the client. You can find these scripts in the Script Center Repository:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To view the registry settings: &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Get-WSUSClientSetting-e52e4260" target="_blank"&gt;Get-WSUSClientSetting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;To set the registry settings: &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Set-ClientWSUSSetting-2e84b805" target="_blank"&gt;Set-ClientWSUSSetting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information about the registry information that I used in these scripts, see &lt;a href="http://technet.microsoft.com/en-us/library/cc708449(WS.10).aspx" target="_blank"&gt;Configure Automatic Updates in a Non&amp;ndash;Active Directory Environment&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s see the settings that we will be changing to talk to our WSUS server on DC1. To do this, I use the &lt;b&gt;Get-ClientWSUSSetting&lt;/b&gt; command as shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-ClientWSUSSetting | Select WUServer,WUStatusServer,DetectionFrequency,AUOptions&lt;/p&gt;
&lt;p&gt;The following image shows the output from this command.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2728.hsg_2D00_1_2D00_16_2D00_12_2D00_7.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2728.hsg_2D00_1_2D00_16_2D00_12_2D00_7.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s change these to reflect the same GPO we conimaged for the domain. Here is the command that does that.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-ClientWSUSSetting -Options DownloadOnly -DetectionFrequency 4 -UpdateServer &amp;#39;http://DC1&amp;#39; -Verbose&lt;/p&gt;
&lt;p&gt;The image shown here illustrates the output from the command.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2235.hsg_2D00_1_2D00_16_2D00_12_2D00_8.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2235.hsg_2D00_1_2D00_16_2D00_12_2D00_8.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, I use the &lt;b&gt;Get-ClientWSUSSetting&lt;/b&gt; command to verify that the changes worked properly. As shown in the following image, it worked just fine.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6431.hsg_2D00_1_2D00_16_2D00_12_2D00_9.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6431.hsg_2D00_1_2D00_16_2D00_12_2D00_9.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Perfect. Now our clients are talking to the WSUS server, and they will begin reporting what patches are needed to be compliant.&lt;/p&gt;
&lt;h3&gt;WSUS and Windows PowerShell&lt;/h3&gt;
&lt;p&gt;Now we are at the point where we can begin working with the assemblies by using Windows PowerShell, and make our initial connection to the WSUS server. We want to use the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.updateservices.administration%28v=VS.85%29.aspx" target="_blank"&gt;Microsoft.UpdateServices.Administration&lt;/a&gt; assembly. Here is the command that I use to load that assembly.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[reflection.assembly]::LoadWithPartialName(&amp;quot;Microsoft.UpdateServices.Administration&amp;quot;) | Out-Null&lt;/p&gt;
&lt;p&gt;Now it is time to make the initial WSUS connection by using the .NET accelerator [Microsoft.UpdateServices.Administration.AdminProxy] and the static method &lt;b&gt;getUpdateServer()&lt;/b&gt;, which requires two values: the WSUS server name and a Boolean value for a secure connection. Because I am not using a secure connection for the WSUS server, we will set it for False. Here is the command.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer(&amp;lsquo;DC1&amp;rsquo;,$False)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wsus&lt;/p&gt;
&lt;p&gt;The output from the command is shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4532.hsg_2D00_1_2D00_16_2D00_12_2D00_10.jpg"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4532.hsg_2D00_1_2D00_16_2D00_12_2D00_10.jpg" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here you can see some information regarding the remote WSUS server, such as the port number that is being used and the version of the WSUS server.&lt;/p&gt;
&lt;p&gt;That is all for today with WSUS. I have shown the beginnings of using Windows PowerShell to make the initial connection to the WSUS server. Tomorrow I will expand on this by showing how you can use Windows PowerShell to perform some basic administration for your WSUS server.&lt;/p&gt;
&lt;p&gt;~Boe&lt;/p&gt;
&lt;p&gt;Thanks Boe, that is a great introduction to WSUS. WSUS Week will continue tomorrow.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3474766" width="1" height="1" alt="" /&gt;</description></item></channel></rss>