<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeff Huston</title>
	<atom:link href="http://jeff.squarecontrol.com/feed" rel="self" type="application/rss+xml" />
	<link>http://jeff.squarecontrol.com</link>
	<description>Things I know (or think I know)</description>
	<lastBuildDate>Fri, 20 Jan 2012 17:55:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>SCCM File Extensions</title>
		<link>http://jeff.squarecontrol.com/archives/83</link>
		<comments>http://jeff.squarecontrol.com/archives/83#comments</comments>
		<pubDate>Fri, 20 Jan 2012 17:55:29 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[ConfigMgr]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=83</guid>
		<description><![CDATA[SCCM makes use of several files on the file system (usually in the INBOXES tree) to actually trigger various actions within the system. Many of these extensions are highlighted in the registry under the HKLM\SOFTWARE\Microsoft\SMS\Triggers\key. For reference purposes, I&#8217;ve pulled out several here. Extension Key name Target Service Action(s) Table   AttrMap_Add_SMSProv SMS Provider Insert [...]]]></description>
			<content:encoded><![CDATA[<p>SCCM makes use of several files on the file system (usually in the INBOXES tree) to actually trigger various actions within the system. Many of these extensions are highlighted in the registry under the HKLM\SOFTWARE\Microsoft\SMS\Triggers\key.</p>
<p>For reference purposes, I&#8217;ve pulled out several here.<br />
<span id="more-83"></span></p>
<table>
<tbody>
<tr>
<th>Extension</th>
<th>Key name</th>
<th>Target Service</th>
<th>Action(s)</th>
<th>Table</th>
</tr>
<tr>
<td> </td>
<td>AttrMap_Add_SMSProv</td>
<td>SMS Provider</td>
<td>Insert</td>
<td>AttributeMap</td>
</tr>
<tr>
<td> </td>
<td>DiscProps_Add_SMSProv</td>
<td>SMS Provider</td>
<td>Insert</td>
<td>DiscPropertyDefs</td>
</tr>
<tr>
<td> </td>
<td>GroupMap_Add_SMSProv</td>
<td>SMS Provider</td>
<td>Insert</td>
<td>GroupMap</td>
</tr>
<tr>
<td>ADC</td>
<td>Coll_Add</td>
<td>Collection Evaluator</td>
<td>Insert</td>
<td>Collection_Maint</td>
</tr>
<tr>
<td>AHC</td>
<td>AIHinvClass_Upd_Dataldr</td>
<td>Client Data Files Source Directory</td>
<td>Update</td>
<td>AIHinvClass</td>
</tr>
<tr>
<td>CAD</td>
<td>CIAssignmentNotify_d</td>
<td>CI Assignment Manager</td>
<td>Delete</td>
<td>CI_CIAssignments</td>
</tr>
<tr>
<td>CCN</td>
<td>PolicyTargetEvalNotify_iud</td>
<td>Policy Targeting Evaluator</td>
<td>Insert, Update</td>
<td>Collections</td>
</tr>
<tr>
<td>CEP</td>
<td>CEP_ADD_Upd</td>
<td>Collection Evaluator</td>
<td>Insert, Update</td>
<td>CEP_CollectionExtendedProperties</td>
</tr>
<tr>
<td>CIA</td>
<td>CIAssignmentNotify_iu</td>
<td>CI Assignment Manager</td>
<td>Insert, Update</td>
<td>CI_CIAssignments</td>
</tr>
<tr>
<td>CIN</td>
<td>CINotify_iud</td>
<td>Object Replication Manager</td>
<td>Insert, Update</td>
<td>CI_ConfigurationItems</td>
</tr>
<tr>
<td>CMN</td>
<td>Coll_Add_OFFERMGR</td>
<td>Offer Manager</td>
<td>Insert</td>
<td>Collection_MemberChg_Notif</td>
</tr>
<tr>
<td>CMN</td>
<td>Collection_Del</td>
<td>Offer Manager</td>
<td>Delete</td>
<td>Collections</td>
</tr>
<tr>
<td>CSB</td>
<td>SubNotify_d_WCM</td>
<td>WSUS Configuration Manager</td>
<td>Delete</td>
<td>CI_UpdateCategorySubscription</td>
</tr>
<tr>
<td>CSB</td>
<td>SubNotify_iu_WCM</td>
<td>WSUS Configuration Manager</td>
<td>Insert, Update</td>
<td>CI_UpdateCategorySubscription</td>
</tr>
<tr>
<td>CTN</td>
<td>CategoryNotify_iud</td>
<td>Object Replication Manager</td>
<td>Insert, Update</td>
<td>CI_CategoryInstances</td>
</tr>
<tr>
<td>DC</td>
<td>Coll_Del</td>
<td>Collection Evaluator</td>
<td>Delete</td>
<td>Collection_Maint</td>
</tr>
<tr>
<td>DEL</td>
<td>Offer_Del</td>
<td>Offer Manager</td>
<td>Delete</td>
<td>ProgramOffers</td>
</tr>
<tr>
<td>DPN</td>
<td>DPNotify_ADD</td>
<td>Distribution Manager</td>
<td>Insert</td>
<td>DPNotification</td>
</tr>
<tr>
<td>DPN</td>
<td>PeerDPResMap_d</td>
<td>Policy Provider</td>
<td>Delete, NonZeroByteFile</td>
<td>PeerDPResMap</td>
</tr>
<tr>
<td>DPN</td>
<td>PeerDPResMap_iu</td>
<td>Policy Provider</td>
<td>Insert, Update, NonZeroByteFile</td>
<td>PeerDPResMap</td>
</tr>
<tr>
<td>DSN</td>
<td>DeviceSettingsItemNotify_iud</td>
<td>Object Replication Manager</td>
<td>Insert, Update</td>
<td>DeviceSettingItems</td>
</tr>
<tr>
<td>EUN</td>
<td>EULANotify_iud</td>
<td>Object Replication Manager</td>
<td>Insert, Update</td>
<td>EULA_Content</td>
</tr>
<tr>
<td>FLN</td>
<td>Tuple$Folders$_i</td>
<td>Object Replication Manager</td>
<td>Insert</td>
<td>Folders</td>
</tr>
<tr>
<td>FLN</td>
<td>Tuple$Folders$_ud</td>
<td>Object Replication Manager</td>
<td>Udpate</td>
<td>Folders</td>
</tr>
<tr>
<td>IAC</td>
<td>InventoryAction_Chg</td>
<td>Policy Provider</td>
<td>Insert, Update, NonZeroByteFile</td>
<td>InventoryAction</td>
</tr>
<tr>
<td>MEN</td>
<td>Tuple$FolderMembers$_i</td>
<td>Object Replication Manager</td>
<td>Insert</td>
<td>FolderMembers</td>
</tr>
<tr>
<td>MEN</td>
<td>Tuple$FolderMembers$_ud</td>
<td>Object Replication Manager</td>
<td>Update</td>
<td>FolderMembers</td>
</tr>
<tr>
<td>MEP</td>
<td>MEP_ADD_Upd</td>
<td>Policy Provider</td>
<td>Insert, Update, NonZeroByteFile</td>
<td>MEP_MachineExtendedProperties</td>
</tr>
<tr>
<td>MRN</td>
<td>MtrRule_Chg</td>
<td>Policy Provider</td>
<td>Insert, NonZeroByteFile</td>
<td>MeterRuleChanges</td>
</tr>
<tr>
<td>OFN</td>
<td>OfferNotify_Add</td>
<td>Offer Manager</td>
<td>Insert</td>
<td>OfferNotification</td>
</tr>
<tr>
<td>OTP</td>
<td>AMT_Add_OTP</td>
<td>SMS_AMT_PROXY_PROV</td>
<td>Insert, Update, NonZeroByteFile</td>
<td>AMT_OTPs</td>
</tr>
<tr>
<td>PKN</td>
<td>PkgNotify_Add</td>
<td>Distribution Manager</td>
<td>Insert</td>
<td>PkgNotification</td>
</tr>
<tr>
<td>RCH</td>
<td>MeterRuleChanges_Ins_SWMPROC</td>
<td>Software Metering Processor (Site)</td>
<td>Insert</td>
<td>MeterRuleChanges</td>
</tr>
<tr>
<td>RUN</td>
<td>SR_SummaryTasks_upd</td>
<td>State System</td>
<td>Update</td>
<td>SR_SummaryTasks</td>
</tr>
<tr>
<td>SCA</td>
<td>SiteCtrlNot_Add_DDM</td>
<td>Discovery Data Manager (Notification)</td>
<td>Insert, Update</td>
<td>SiteControlNotification</td>
</tr>
<tr>
<td>SCD</td>
<td>SiteCtrlNot_Del_DDM</td>
<p><TD>Discovery Data Manager (Notification)</td>
<td>Delete</td>
<td>SiteControlNotification</td>
</tr>
<tr>
<td>SCN</td>
<td>SiteControl_AddUpd_HMAN</td>
<td>Hierarchy Manager</td>
<td>Insert</td>
<td>SiteControl</td>
</tr>
<tr>
<td>SCN</td>
<td>UpdSrcNotify_iud</td>
<td>Object Replication Manager</td>
<td>Insert, Update</td>
<td>CI_UpdateSources</td>
</tr>
<tr>
<td>SDN</td>
<td>SDMNotify_iud</td>
<td>Object Replication Manager</td>
<td>Insert, Update</td>
<td>CI_SDMPackages</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_AIKbMgr</td>
<td>Asset Intelligence KB Manager</td>
<td>Insert, Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_CIA_CIAMgr</td>
<td>CI Assignment Manager</td>
<td>Insert, Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_iu_WCM</td>
<td>WSUS Configuration Manager</td>
<td>Insert, Update</td>
<td>Sites</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_OBJ_ObjReplMgr</td>
<td>Object Replication Manager</td>
<td>Insert, Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_Upd_CE</td>
<td>Collection Evaluator</td>
<td>Insert, Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_Upd_DDM</td>
<td>Discovery Data Manager</td>
<td>Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_Upd_DistMgr</td>
<td>Distribution Manager</td>
<td>Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_Upd_OfferMgr</td>
<td>Offer Manager</td>
<td>Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_Upd_SWMPROC</td>
<td>Software Metering Processor (Site)</td>
<td>Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHA</td>
<td>SiteNotif_WSyncMgr</td>
<td>WSUS Sync Manager</td>
<td>Insert, Update</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SHD</td>
<td>SiteNotif_Del_SWMPROC</td>
<td>Software Metering Processor (Site)</td>
<td>Delete</td>
<td>SiteNotification</td>
</tr>
<tr>
<td>SSD</td>
<td>Sites_Del_HMAN</td>
<td>Hierarchy Manager</td>
<td>Delete</td>
<td>Sites</td>
</tr>
<tr>
<td>SSU</td>
<td>Sites_AddUpd_HMAN</td>
<td>Hierarchy Manager</td>
<td>Insert, Update</td>
<td>Sites</td>
</tr>
<tr>
<td>STN</td>
<td>UpdSyncStatus_iu</td>
<td>Policy Provider</td>
<td>Insert, Update, NonZeroByteFile</td>
<td>Update_SyncStatus</td>
</tr>
<tr>
<td>UDC</td>
<td>Coll_Upd</td>
<td>Collection Evaluator</td>
<td>Update</td>
<td>Collection_Maint</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/83/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best Idea for Christmas Shopping</title>
		<link>http://jeff.squarecontrol.com/archives/68</link>
		<comments>http://jeff.squarecontrol.com/archives/68#comments</comments>
		<pubDate>Sat, 17 Dec 2011 23:54:46 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Shopping]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=68</guid>
		<description><![CDATA[Every year, the Barnes &#038; Noble store at our mall allows a nonprofit to come in and wrap gifts for donations. So, you can purchase your gifts and get them wrapped, all in one go.]]></description>
			<content:encoded><![CDATA[<p>Every year, the Barnes &#038; Noble store at our mall allows a nonprofit to come in and wrap gifts for donations. So, you can purchase your gifts and get them wrapped, all in one go.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/68/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Issue with DNS Dynamic Update and IPv6 Tunnels</title>
		<link>http://jeff.squarecontrol.com/archives/66</link>
		<comments>http://jeff.squarecontrol.com/archives/66#comments</comments>
		<pubDate>Fri, 16 Dec 2011 17:36:59 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[IPv6]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=66</guid>
		<description><![CDATA[If you have disabled an IPv6 tunnel using the netsh command-line tool, the IPv6 interface will be successfully removed. However, the client will continue to register that interface&#8217;s IPv6 address with the DNS server until the server is rebooted. To work around this issue, simply stop and restart the dnscache service (DNS Client service). This [...]]]></description>
			<content:encoded><![CDATA[<p>If you have disabled an IPv6 tunnel using the <strong>netsh</strong> command-line tool, the IPv6 interface will be successfully removed.  However, the client will continue to register that interface&#8217;s IPv6 address with the DNS server until the server is rebooted.</p>
<p>To work around this issue, simply stop and restart the <strong>dnscache</strong> service (DNS Client service).  This service is the one that actually registers names with the DNS server.  Restarting it will cause it to re-inventory the interfaces and stop uploading old data.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/66/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to tell if your cat is on drugs</title>
		<link>http://jeff.squarecontrol.com/archives/62</link>
		<comments>http://jeff.squarecontrol.com/archives/62#comments</comments>
		<pubDate>Fri, 16 Dec 2011 00:54:00 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Cat]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=62</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><span id="more-62"></span></p>
<p><a href="http://jeff.squarecontrol.com/wp-content/uploads/2011/12/party-fails-crunk-critters-cats-on-drugs-caffeine-acid-coffee.jpg"><img src="http://jeff.squarecontrol.com/wp-content/uploads/2011/12/party-fails-crunk-critters-cats-on-drugs-caffeine-acid-coffee.jpg" alt="" title="party-fails-crunk-critters-cats-on-drugs-caffeine-acid-coffee" width="352" height="2500" class="alignnone size-full wp-image-63" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/62/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managing Software Updates on the ConfigMgr Server &#8211; Part 4</title>
		<link>http://jeff.squarecontrol.com/archives/56</link>
		<comments>http://jeff.squarecontrol.com/archives/56#comments</comments>
		<pubDate>Thu, 15 Dec 2011 23:55:59 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[SoftwareUpdates]]></category>
		<category><![CDATA[VBscript]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=56</guid>
		<description><![CDATA[This post has to deal with getting rid of the old, expired updates. Microsoft will replace its updates with newer versions and there is no need to continue to replicate, advertise, or even store old versions since the clients will not install them anyway. The following script will get rid of old, expired updates and [...]]]></description>
			<content:encoded><![CDATA[<p>This post has to deal with getting rid of the old, expired updates.  Microsoft will replace its updates with newer versions and there is no need to continue to replicate, advertise, or even store old versions since the clients will not install them anyway.</p>
<p><span id="more-56"></span></p>
<p>The following script will get rid of old, expired updates and their files for you.  Just run it on a regular basis to clean up the system.</p>
<p>Save the following as <strong>CleanupOldUpdates.wsf</strong>:</p>
<pre class="prettyprint lang-VB">&lt;job&gt;
&lt;runtime&gt;
&lt;named name=&#34;AlsoRemoveUnrequired&#34; type=string required=false helpstring=&#34;Removes updates that are not required that are more than n days old (default is 7)&#34; &#47;&gt;
&lt;&#47;runtime&gt;
&lt;script language=vbscript&gt;
&#39;This script will scan through the updates and remove old items from
&#39;deployments, packages, and update lists where the Expired attribute
&#39;is set to TRUE.

Set SMS = GetObject(&#34;winmgmts:&#47;&#47;.&#47;root&#47;sms&#47;site_***&#34;) &#39;Replace *** with your sitecode
Set SO = WScript.StdOut
Set WMIDate = CreateObject(&#34;WbemScripting.SWbemDateTime&#34;)
Set aNamed = WScript.Arguments.Named
If aNamed.Exists(&#34;AlsoRemoveUnrequired&#34;) Then
	If aNamed(&#34;AlsoRemoveUnrequired&#34;) = &#34;&#34; Then
		UnrequiredLimit = 7
	Else
		If IsNumeric(aNamed(&#34;AlsoRemoveUnrequired&#34;)) Then
			UnrequiredLimit = CLng(aNamed(&#34;AlsoRemoveUnrequired&#34;))
		Else
			WScript.Arguments.ShowUsage
			WScript.Quit
		End If
	End If
	SO.WriteLine &#34;Will also consider updates more than &#34; &#038; UnrequiredLimit &#038; &#34; days old that are not required to be&#34; &#038; vbCrLf &#038; &#34;expired&#34;
	UnrequiredDate = DateAdd(&#34;d&#34;,0-UnrequiredLimit,Now())
	WMIDate.SetVarDate UnrequiredDate
	WMIDate.UTC=False
	UnrequiredDateWMI = WMIDate.Value
	SO.WriteLine UnrequiredDate
	SO.WriteLine UnrequiredDateWMI
End If

&#39;*************************************************************************
&#39; Clean up Deployments
&#39;*************************************************************************

SO.WriteLine &#34;*******************************************************************************&#34;
SO.WriteLine &#34;Cleaning up Deployments&#34;
SO.WriteLine &#34;*******************************************************************************&#34;
SO.WriteLine

&#39;Get the assignments and parse through them, looking for expired updates
Set collAssignments = SMS.Get(&#34;SMS_UpdatesAssignment&#34;).Instances_
Dim AssignedCIs()

For Each AssignmentItem in collAssignments
	Set Assignment=SMS.Get(Split(AssignmentItem.Path_,&#34;:&#34;)(1))	&#39;This object has lazy properties that need to be obtained
	SO.WriteLine &#34;ASSIGNMENT: &#34; &#038; Assignment.AssignmentName &#038; &#34; &#91;&#34; &#038; Assignment.AssignmentID &#038; &#34;&#93;&#34;

	&#39;We&#39;ll hold the updates assigned to this list in an array
	UpdateCount = 0
	UpdateCountOriginal = 0
	Redim AssignedCIs(UpdateCount)

	&#39;Since enumerating updates is &#34;expensive&#34;, we&#39;ll only target assignments that are known
	&#39;to have expired updates
	If Assignment.ContainsExpiredUpdates or aNamed.Exists(&#34;AlsoRemoveUnrequired&#34;) Then
		SO.WriteLine &#34;  Getting expired updates...&#34;
		For I = LBound(Assignment.AssignedCIs) to UBound(Assignment.AssignedCIs)
			If UBound(Assignment.AssignedCIs)&lt;&gt;0 Then SO.Write String(79,Chr(8)) &#038; FormatPercent(I&#47;UBound(Assignment.AssignedCIs))
			Set Update=SMS.Get(&#34;SMS_SoftwareUpdate.CI_ID=&#34; &#038; Assignment.AssignedCIs(I))
			If Update.IsExpired Then
				SO.WriteLine String(79,Chr(8)) &#038; &#34;  &#34; &#038; Update.ArticleID &#038; &#34; is expired &#91;&#34; &#038; Update.CI_ID &#038; &#34;&#93;&#34;
			ElseIf aNamed.Exists(&#34;AlsoRemoveUnrequired&#34;) and Update.NumMissing=0 and Update.NumPresent=0 and Update.DateRevised&lt;UnrequiredDateWMI Then
				SO.WriteLine String(79,Chr(8)) &#038; &#34;  &#34; &#038; Update.ArticleID &#038; &#34; is not required &#91;&#34; &#038; Update.CI_ID &#038; &#34;&#93;&#34;
			Else
				Redim Preserve AssignedCIs(UpdateCount)
				AssignedCIs(UpdateCount) = Update.CI_ID
				UpdateCount = UpdateCount + 1
			End If
			UpdateCountOriginal = UpdateCountOriginal + 1
		Next
		SO.Write String(79,Chr(8))

		&#39;If the array is a different size than the original array, we&#39;ve removed some
		If UpdateCount &lt; UpdateCountOriginal Then
			SO.WriteLine &#34;    Removed &#34; &#038; UpdateCountOriginal-UpdateCount &#038; &#34; update(s)&#34;

			&#39;Save the changes
			If Join(AssignedCIs,&#34;,&#34;)=&#34;&#34; Then
				SO.WriteLine &#34;!!! All updates need to be removed from this deployment.  Please add new ones or remove the deployment altogether.&#34;
				SO.WriteLine
			Else
				Assignment.AssignedCIs = AssignedCIs
				Assignment.Put_
			End If
		End If
	End If
Next

&#39;*************************************************************************
&#39; Clean up Packages
&#39;*************************************************************************

SO.WriteLine
SO.WriteLine
SO.WriteLine &#34;*******************************************************************************&#34;
SO.WriteLine &#34;Cleaning up Packages&#34;
SO.WriteLine &#34;*******************************************************************************&#34;
SO.WriteLine

&#39;Get the deployment packages
Set collPackages = SMS.Get(&#34;SMS_SoftwareUpdatesPackage&#34;).Instances_

&#39;Find a list of all expired updates that are provisioned
Set collUpdates = SMS.ExecQuery(&#34;Select * from SMS_SoftwareUpdate where IsContentProvisioned = 1 and IsExpired = 1&#34;)
If aNamed.Exists(&#34;AlsoRemoveUnrequired&#34;) Then _
	Set collUpdatesUnreq = SMS.ExecQuery(&#34;Select * from SMS_SoftwareUpdate where IsContentProvisioned = 1 and NumMissing = 0 and NumPresent = 0 and DateRevised &lt; &#39;&#34; &#038; UnrequiredDate &#038; &#34;&#39;&#34;)
Dim ContentIDs()
ContentCount = 0

For Each oUpdate in collUpdates
	SO.WriteLine &#34;Compiling content IDs for expired update &#34; &#038; oUpdate.ArticleID &#038; &#34; &#91;&#34; &#038; oUpdate.CI_ID &#038; &#34;&#93;&#34;
	Set collContent = SMS.ExecQuery(&#34;Select * from SMS_CIToContent where CI_ID = &#34; &#038; oUpdate.CI_ID)
	For Each oContent in collContent
		If oContent.ContentDownloaded Then
			SO.WriteLine &#34;    Added content ID &#34; &#038; oContent.ContentID
			Redim Preserve ContentIDs(ContentCount)
			COntentIDs(ContentCount) = oContent.ContentID
			ContentCount = ContentCount + 1
		End If
	Next
Next

If aNamed.Exists(&#34;AlsoRemoveUnrequired&#34;) Then
	For Each oUpdate in collUpdatesUnreq
		SO.WriteLine &#34;Compiling content IDs for unrequired update &#34; &#038; oUpdate.ArticleID &#038; &#34; &#91;&#34; &#038; oUpdate.CI_ID &#038; &#34;&#93;&#34;
		set collContent = SMS.ExecQuery(&#34;Select * from SMS_CItoContent where CI_ID = &#34; &#038; oUpdate.CI_ID)
		For Each oContent in collContent
			if oContent.ContentDownloaded Then
				SO.WriteLine &#34;    Added content ID &#34; &#038; oContent.ContentID
				Redim Preserve ContentIDs(ContentCount)
				ContentIDs(ContentCount) = oContent.ContentID
				ContentCount = ContentCount + 1
			End If
		Next
	Next
End If

SO.WriteLine &#34;Found a total of &#34; &#038; ContentCount &#038; &#34; content item(s) to be removed&#34;

If ContentCount &gt; 0 Then
	On Error Resume Next
	For Each oPackage in collPackages
		SO.WriteLine &#34;Removing from &#34; &#038; oPackage.Name &#038; &#34; &#91;&#34; &#038; oPackage.PackageID &#038; &#34;&#93;&#34;
		oPackage.RemoveContent ContentIDs, True
		If Err.Number = 0 Then SO.WriteLine &#34;    Success&#34;
	Next
	On Error Goto 0
End If

&#39;*************************************************************************
&#39; Clean up Update Lists
&#39;*************************************************************************

SO.WriteLine
SO.WriteLine
SO.WriteLine &#34;*******************************************************************************&#34;
SO.WriteLine &#34;Cleaning up Update Lists&#34;
SO.WriteLine &#34;*******************************************************************************&#34;
SO.WriteLine

&#39;Get the update lists and parse through them, looking for expired updates
Set collLists = SMS.Get(&#34;SMS_AuthorizationList&#34;).Instances_
Dim Updates()

For Each ListItem in collLists
	&#39;SO.WriteLine Split(ListItem.Path_,&#34;:&#34;)(1)
	Set List=SMS.Get(Split(ListItem.Path_,&#34;:&#34;)(1))	&#39;This object has lazy properties that need to be obtained
	SO.WriteLine &#34;UPDATE_LIST: &#34; &#038; List.LocalizedDisplayName &#038; &#34; &#91;&#34; &#038; List.CI_ID &#038; &#34;&#93;&#34;

	&#39;We&#39;ll hold the updates assigned to this list in an array of CI_IDs
	UpdateCount = 0
	Redim arrUpdate(UpdateCount)

	&#39;Enumerate the existing updates assigned to the list
	Set collUpdateIDs = SMS.ExecQuery(&#34;Select SMS_SoftwareUpdate.* from SMS_CIRelation join SMS_SoftwareUpdate on SMS_CIRelation.ToCIID=SMS_SoftwareUpdate.CI_ID where SMS_CIRelation.FromCIID=&#34; &#038; List.CI_ID)
	&#39;SO.WriteLine collUpdateIDs.Count

	&#39;Check each one and, if expired, don&#39;t add it into our array - only good updates go into the array
	If collUpdateIDs.Count&gt;0 Then
		For Each Update in collUpdateIDs
			If Update.IsExpired Then
				SO.WriteLine String(79,Chr(8)) &#038; &#34;  &#34; &#038; Update.ArticleID &#038; &#34; is expired &#91;&#34; &#038; Update.CI_ID &#038; &#34;&#93;&#34;
			ElseIf aNamed.Exists(&#34;AlsoRemoveUnrequired&#34;) and Update.NumMissing=0 and Update.NumPresent=0 and Update.DateRevised&lt;UnrequiredDateWMI Then
				SO.WriteLine String(79,Chr(8)) &#038; &#34;  &#34; &#038; Update.ArticleID &#038; &#34; is not required &#91;&#34; &#038; Update.CI_ID &#038; &#34;&#93;&#34;
			Else
				Redim Preserve arrUpdate(UpdateCount)
				arrUpdate(UpdateCount) = Update.CI_ID
				UpdateCount = UpdateCount + 1
			End If
		Next
	End If

	&#39;If the array is a different size than the original collection, we&#39;ve removed some
	If UpdateCount &lt; collUpdateIDs.Count Then
		SO.WriteLine &#34;    Removed &#34; &#038; (collUpdateIDs.Count - UpdateCount) &#038; &#34; update(s)&#34;

		&#39;Save the new update membership
		If Join(arrUpdate,&#34;,&#34;) &lt;&gt; &#34;&#34; Then
			List.Updates = arrUpdate
			List.Put_
		Else
			SO.WriteLine &#34;!!! All updates need to be removed - please remove this list outright or add current updates before cleaning up old ones.&#34;
			SO.WriteLine
		End If
	End If
Next
&lt;&#47;script&gt;
&lt;&#47;job&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/56/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managing Software Updates on the ConfigMgr Server &#8211; Part 3</title>
		<link>http://jeff.squarecontrol.com/archives/49</link>
		<comments>http://jeff.squarecontrol.com/archives/49#comments</comments>
		<pubDate>Thu, 15 Dec 2011 23:47:15 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[SoftwareUpdates]]></category>
		<category><![CDATA[VBscript]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=49</guid>
		<description><![CDATA[If you end up using my method, you&#8217;ll end up with a slew of update lists and packages, one per month. Sometimes, it is convenient to roll those up into an annual list/package and deploy that to end users. The following script can be used to combine several monthly update lists for the specified year [...]]]></description>
			<content:encoded><![CDATA[<p>If you end up using my method, you&#8217;ll end up with a slew of update lists and packages, one per month.  Sometimes, it is convenient to roll those up into an annual list/package and deploy that to end users.</p>
<p><span id="more-49"></span></p>
<p>The following script can be used to combine several monthly update lists for the specified year into one single list.  This can then be deployed to clients using the script found in <a href="http://jeff.squarecontrol.com/archives/47" title="Managing Software Updates on the ConfigMgr Server – Part 2">Part 2</a> of this series.</p>
<p>Save the following file as <strong>CombineYears.wsf</strong>:</p>
<pre class="prettyprint lang-VB">&lt;job&gt;
&lt;runtime&gt;
&lt;description&gt;
This utility will combine several &#34;Software Updates YYYY-MM&#34; lists into a
single list for a given year.  This allows the individual lists to be
unassigned and to utilize the annual list for future assignments.  This
helps to simplify and minimize the amount of assignments that the user
workstation must churn through when analyzing for updates
&lt;&#47;description&gt;
&lt;unnamed name=Year required=1 many=true helpstring=&#34;The four digit year of lists to be combined&#34; &#47;&gt;
&lt;&#47;runtime&gt;
&lt;script language=VBScript&gt;

&#39;Connect to SCCM
Set SCCM = GetObject(&#34;winmgmts:&#47;&#47;.&#47;root&#47;sms&#47;site_***&#34;) &#39;Replace *** with your sitecode

Set WMIDate = CreateObject(&#34;WBemSCripting.SWbemDateTime&#34;)
Set SO = WScript.StdOut

&#39;Validate parameters
Set uNamed = WScript.Arguments.Unnamed

&#39;Ensure that we have at least one
If uNamed.Count = 0 Then
	WScript.Arguments.ShowUSage
	WScript.Quit 1
End If

&#39;Ensure that they are four-digit numbers
For Each strYear in uNamed
	If Not IsNumeric(strYear) Then
		WScript.Arguments.ShowUsage
		WScript.Quit 1
	End If
	If Len(strYear) &lt;&gt; 4 Then
		WScript.Arguments.ShowUsage
		WScript.Quit 1
	End If
Next

For Each strYear in uNamed
	SO.WriteLine &#34;Looking to combine lists for the year &#34; &#038; strYear
	&#39;Look for matching lists
	Set colLists = SCCM.Get(&#34;SMS_AuthorizationList&#34;).Instances_
	Set Updates = CreateObject(&#34;Scripting.Dictionary&#34;)
	UpdateCount = 0
	For Each ListItem in colLists
		If Left(UCase(ListItem.LocalizedDisplayName),22) = &#34;SOFTWARE UPDATES &#34; &#038; strYear &#038; &#34;-&#34; Then
			Set List = SCCM.Get(Split(ListItem.Path_,&#34;:&#34;)(1))	&#39;Need to get the object due to lazy properties
			SO.WriteLine &#34;  &#34; &#038; List.LOcalizedDisplayName
			&#39;Get the updates that are in this list
			Set collUpdateIDs = SCCM.ExecQuery(&#34;Select SMS_SoftwareUpdate.* from SMS_CIRelation join SMS_SoftwareUpdate on SMS_CIRelation.ToCIID=SMS_SoftwareUpdate.CI_ID where SMS_CIRelation.FromCIID=&#34; &#038; List.CI_ID)
			If collUpdateIDs.Count &gt; 0 Then
				For Each Update in collUpdateIDs
					Updates.Add CStr(Update.CI_ID), Update
					UpdateCOunt = UpdateCount + 1
				Next
			End If
		End If
	Next

	&#39;We now have all of our updates into the Updates array
	SO.WriteLine &#34;    &#34; &#038; UpdateCount &#038; &#34; update(s) to be combined into a single list&#34;

	Set Info = SCCM.Get(&#34;SMS_CI_LocalizedProperties&#34;).SpawnInstance_
	Info.Description = &#34;Auto-generated Update List&#34;
	Info.DisplayName = &#34;Software Updates &#34; &#038; strYear &#038; &#34; Annual Summary&#34;
	Info.InformativeURL = &#34;&#34;
	Info.LocaleID=&#34;1033&#34;
	Set List = SCCM.Get(&#34;SMS_AuthorizationList&#34;).SpawnInstance_
	List.Updates = Updates.Keys
	List.LocalizedInformation = Array(Info)
	List.Put_
Next

&lt;&#47;script&gt;
&lt;&#47;job&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/49/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managing Software Updates on the ConfigMgr Server &#8211; Part 2</title>
		<link>http://jeff.squarecontrol.com/archives/47</link>
		<comments>http://jeff.squarecontrol.com/archives/47#comments</comments>
		<pubDate>Thu, 15 Dec 2011 22:21:40 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[SoftwareUpdates]]></category>
		<category><![CDATA[VBscript]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=47</guid>
		<description><![CDATA[Once you have an update list created (either manually or via the script noted in Part 1, you&#8217;ll need to deploy them. In order to do that, you can use the Deployment Templates built in to the ConfigMgr console. If you need to deploy to several collections at once (or with slightly different settings), you&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>Once you have an update list created (either manually or via the script noted in <a href="http://jeff.squarecontrol.com/archives/42" title="Managing Software Updates on the ConfigMgr Server – Part 1">Part 1</a>, you&#8217;ll need to deploy them.  In order to do that, you can use the Deployment Templates built in to the ConfigMgr console.  If you need to deploy to several collections at once (or with slightly different settings), you&#8217;ll need to run through the deployment wizard multiple times.  I&#8217;ve developed this script to help make that process a bit more efficient.</p>
<p><span id="more-47"></span></p>
<p>This script requires that the content for the update list specified be downloaded into a deployment package and that any EULAs have been accepted.  Otherwise, it will produce errors.</p>
<p>The script creates output, so it should be run under CSCRIPT on the site server itself.</p>
<p>The script was written for a particular process, which you&#8217;ll want to modify for your environment.  At the place where I work, we deploy updates initially to a &#8220;Dogfood&#8221; group that performs initial testing to ensure that the updates don&#8217;t cause bluescreens or other major havoc.  The next phase sees the deployment to the &#8220;Tech&#8221; team (the whole IT department), followed by a deployment to the production workstations.  We also have separate collections for production servers and for computers that represent the operating system image source.  Because of that, there are several different groups where you&#8217;ll want to update the collection ID to match your environment.</p>
<p>Also, don&#8217;t forget to update the sitecode to the one for your environment.</p>
<p>The way the script works, you can combine several groups on the command line at once (for example, /D /S /I to deploy to Dogfood, Servers, and Image computers simultaneously).  The script handles all of the deployment settings, so you don&#8217;t actually <em>need</em> deployment templates for this to work.  I still recommend them for manual deployments or other one-offs so that you can remain consistent.</p>
<p>Save the following as <strong>DeployUpdates.wsf</strong>:</p>
<pre class="prettyprint lang-VB">&lt;job&gt;
&lt;runtime&gt;
&lt;description&gt;
This script will create a deployment for the named Update List and
assign it to the specified target(s).

This script does NOT use the templates found in SCCM.  Any changes
needed to the template must be coded in the script.
&lt;&#47;description&gt;
&lt;named name=&#34;L&#34; type=string helpstring=&#34;Name of the update list&#34; required=true &#47;&gt;
&lt;named name=&#34;D&#34; type=simple helpstring=&#34;Deploy to DOGFOOD&#34; &#47;&gt;
&lt;named name=&#34;I&#34; type=simple helpstring=&#34;Deploy to IMAGE&#34; &#47;&gt;
&lt;named name=&#34;S&#34; type=simple helpstring=&#34;Deploy to SVR&#34; &#47;&gt;
&lt;named name=&#34;T&#34; type=simple helpstring=&#34;Deploy to TECH&#34; &#47;&gt;
&lt;named name=&#34;W&#34; type=simple helpstring=&#34;Deploy to WKS&#34; &#47;&gt;
&lt;&#47;runtime&gt;
&lt;script language=&#34;VBScript&#34;&gt;

Const DogfoodCollectionID = &#34;***ID***&#34;
Const DogfoodDeadline = -1
Const DogfoodNotify = False

Const ImageCollectionID = &#34;***ID***&#34;
Const ImageDeadline = -1
Const ImageNotify = True

Const SvrCollectionID = &#34;***ID***&#34;
Const SvrDeadline = 1
Const SvrNotify = True

Const TechCollectionID = &#34;***ID***&#34;
Const TechDeadline = -1
Const TechNotify = False

Const WksCollectionID = &#34;***ID***&#34;
Const WksDeadline = -1
Const WksNotify = False

Const SiteCode = &#34;***&#34;

&#39;Get SCCM WMI Connection
Set SCCM = GetObject(&#34;winmgmts:&#47;&#47;.&#47;root&#47;sms&#47;site_&#34; &#038; SiteCode)
Set WMIDate = CreateObject(&#34;WbemScripting.SWbemDateTime&#34;)

&#39;Check named arguments
Set aNamed = WScript.Arguments.Named
If Not aNamed.Exists(&#34;L&#34;) Then
	&#39;Missing list
	WScript.Arguments.ShowUsage
	WScript.Quit 1
End If
If Not (aNamed.Exists(&#34;D&#34;) or aNamed.Exists(&#34;I&#34;) or aNamed.Exists(&#34;S&#34;) or aNamed.Exists(&#34;T&#34;) or aNamed.Exists(&#34;W&#34;)) Then
	&#39;Missing target
	WScript.Arguments.ShowUsage
	WScript.Quit 1
End If

&#39;See if the list exists
Set RS = SCCM.ExecQuery(&#34;select * from SMS_AuthorizationList where LocalizedDisplayName=&#39;&#34; &#038; aNamed(&#34;L&#34;) &#038; &#34;&#39;&#34;)
If RS.Count = 0 Then
	WScript.Echo &#34;The Update List &#34; &#038; aNamed(&#34;L&#34;) &#038; &#34; cannot be found.  Please check spelling.&#34;
	WScript.Quit 1
End If

&#39;Get the corrected name so that letter case matches what is visible to the user
For Each AL in RS
	Set lbAL = SCCM.Get(&#34;SMS_AuthorizationList.CI_ID=&#34; &#038; AL.CI_ID)
	UpdateListName = lbAL.LocalizedDisplayName
	UpdateArray = lbAL.Updates
Next
WScript.Echo &#34;Creating deployments for &#34; &#038; UpdateListName
WScript.Echo &#34;This deployment will be for &#34; &#038; UBound(UpdateArray)+1 &#038; &#34; update(s)&#34;

&#39;Create the deployments requested
If aNamed.Exists(&#34;D&#34;) Then AddDeployment &#34; to DOGFOOD&#34;, DogfoodCollectionID, DogfoodDeadline, DogfoodNotify
If aNamed.Exists(&#34;I&#34;) Then AddDeployment &#34; to IMAGE&#34;, ImageCollectionID, ImageDeadline, ImageNotify
If aNamed.Exists(&#34;S&#34;) Then AddDeployment &#34; to SVR&#34;, SvrCollectionID, SvrDeadline, SvrNotify
If aNamed.Exists(&#34;T&#34;) Then AddDeployment &#34; to TECH&#34;, TechCollectionID, TechDeadline, TechNotify
If aNamed.Exists(&#34;W&#34;) Then AddDeployment &#34; to WKS&#34;, WksCollectionID, WksDeadline, WksNotify

Sub AddDeployment(NameSuffix, TargetCollectionID, SetDeadline, NotifyUser)
	WScript.Echo &#34;Adding deployment&#34; &#038; NameSuffix
	Set UA = SCCM.Get(&#34;SMS_UpdatesAssignment&#34;).SpawnInstance_

	UA.ApplyToSubTargets = False
	UA.AssignedCIs = UpdateArray
	UA.AssignmentAction = 2		&#39;This will apply the updates (not just detect them)
	UA.AssignmentDescription = &#34;&#34;
	UA.AssignmentName = UpdateListName &#038; NameSuffix
	UA.DesiredConfigType = 1	&#39;Updates are REQUIRED
	UA.DPLocality = 80			&#39;Download from local and remote distribution points
	UA.LocaleID = 1033			&#39;English
	UA.LogComplianceToWinEvent = True
	UA.NotifyUser = NotifyUser
	UA.OverrideServiceWindows = False
	UA.RaiseMomAlertsOnFailure = False
	UA.ReadOnly = False
	UA.RebootOutsideOfServiceWindows = False
	UA.SendDetailedNonComplianceStatus = True
	If SetDeadline &gt;= 0 Then
		WMIDate.SetVarDate DateAdd(&#34;h&#34;,SetDeadline,Now())
		WMIDate.UTCSpecified = False
		UA.EnforcementDeadline = WMIDate.Value
	End If
	WMIDate.SetVarDate(Now())
	WMIDate.UTCSpecified = False
	UA.StartTime = WMIDate.Value
	UA.SuppressReboot = 0
	UA.TargetCollectionID = TargetCollectionID
	UA.UseGMTTimes = False

	UA.Put_
End Sub

&lt;&#47;script&gt;
&lt;&#47;job&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/47/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Managing Software Updates on the ConfigMgr Server &#8211; Part 1</title>
		<link>http://jeff.squarecontrol.com/archives/42</link>
		<comments>http://jeff.squarecontrol.com/archives/42#comments</comments>
		<pubDate>Thu, 15 Dec 2011 22:10:13 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[SoftwareUpdates]]></category>
		<category><![CDATA[VBscript]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=42</guid>
		<description><![CDATA[Collecting and deploying software updates on the server is a regular task (at least monthly) and somewhat tedious. To assist with this process, I&#8217;ve developed a handful of scripts that help to automate some of this work. In this first article, I want to share a script that I use to actually create the update [...]]]></description>
			<content:encoded><![CDATA[<p>Collecting and deploying software updates on the server is a regular task (at least monthly) and somewhat tedious.  To assist with this process, I&#8217;ve developed a handful of scripts that help to automate some of this work.</p>
<p>In this first article, I want to share a script that I use to actually create the update list.  This script will search for updates that have not yet been deployed and that are actually required by at least one client system (so you need to usually wait a day or so for inventory of any new updates to be gathered).</p>
<p><span id="more-42"></span></p>
<p>The script will default to creating an update list called <strong>Software Updates YYYY-MM</strong> for the current month.  If one already exists, it appends a lowercase letter to the end to provide unique update lists.</p>
<p>Once the update list is created, you can go into the ConfigMgr console to actually review the list (to ensure that it is or is not deploying the latest Internet Explorer, for example), to accept any EULAs, and to actually download the updates into a deployment package.</p>
<p>This script should be run from the ConfigMgr site server itself.  Be sure to replace the *** in the &#8220;set SCCM&#8221; line to your site code.  This script produces output and should be run under CSCRIPT.</p>
<p>For command-line options, run the script with the &#8220;/?&#8221; switch.</p>
<p>Save the following as <strong>UpdateList.wsf</string>:</p>
<pre class="prettyprint lang-VB">&lt;job&gt;
&lt;runtime&gt;
&lt;description&gt;
This script will create an update list that contains updates according to the
criteria specified on the command line.
&lt;&#47;description&gt;
&lt;named name=Range					helpstring=&#34;Range of months back from today to search for updates                           (default 2)&#34; type=string required=false &#47;&gt;
&lt;named name=IncludeDeployed 		helpstring=&#34;Include updates that have already been deployed&#34; type=simple required=false &#47;&gt;
&lt;named name=IncludeUnrequired		helpstring=&#34;Include updates that are not required&#34; type=simple required=false &#47;&gt;
&lt;named name=Categories 				helpstring=&#34;Specifies categories to include separated by commas                             (default SU,CU,UR,DU)&#34; type=string required=false &#47;&gt;
&lt;named name=ListName				helpstring=&#34;Name of the Update List to create                                               (default Software Updates YYYY-MM)&#34; type=string required=false &#47;&gt;
&lt;named name=IncludeProducts			helpstring=&#34;Display names of products to include updates for,								regardless of category (default Silverlight)&#34; type=string required=false &#47;&gt;
&lt;&#47;runtime&gt;
&lt;script language=vbscript&gt;

&#39;Connect to SCCM WMI provider
set SCCM = GetObject(&#34;winmgmts:&#47;&#47;.&#47;root&#47;sms&#47;site_***&#34;) &#39;Replace *** with your sitecode!

Set WMIDate = CreateObject(&#34;WbemScripting.SWbemDateTime&#34;)

&#39;Note any articles that should _never_ be automatically included
ArticlesToNeverInclude=Array(&#34;974571&#34;)

&#39;Note any products that should _never_ be automatically included
ProductsToNeverInclude=Array(&#34;ProductFamily:352f9494-d516-4b40-a21a-cd2416098982&#34;, _
		&#34;Product:83a83e29-7d55-44a0-afed-aea164bc35e6&#34;, _
		&#34;Product:3cf32f7c-d8ee-43f8-a0da-8b88a6f8af1a&#34;, _
		&#34;Product:26bb6be1-37d1-4ca6-baee-ec00b2f7d0f1&#34;, _
		&#34;Product:9b135dd5-fc75-4609-a6ae-fb5d22333ef0&#34;)	&#39;All versions of Exchange server

&#39;Set variables based on parameters

Range = 2
If WScript.Arguments.Named.Exists(&#34;Range&#34;) Then
	If IsNumeric(WScript.Arguments.Named(&#34;Range&#34;)) Then Range = WScript.Arguments.Named(&#34;Range&#34;)
End If
RangeStart = DateAdd(&#34;m&#34;,0-Range,Now())

IncludeDeployed = False
If WScript.Arguments.Named.Exists(&#34;IncludeDeployed&#34;) Then IncludeDeployed = True

IncludeUnrequired = False
If WScript.Arguments.Named.Exists(&#34;IncludeUnrequired&#34;) Then IncludeUnrequired = True

Categories = &#34;SU,CU,UR,DU&#34;
If WScript.Arguments.Named.Exists(&#34;Categories&#34;) Then Categories = UCase(WScript.Arguments.Named(&#34;Categories&#34;))

IncludeProducts = &#34;Silverlight,PowerShell&#34;
If WScript.Arguments.Named.Exists(&#34;IncludeProducts&#34;) Then IncludeProducts = WScript.Arguments.Named(&#34;IncludeProducts&#34;)

ListName = &#34;Software Updates &#34; &#038; Year(Now()) &#038; &#34;-&#34;
If Month(Now())&lt;10 Then ListName = ListName &#038; &#34;0&#34;
ListName = ListName &#038; Month(Now())
If WScript.Arguments.Named.Exists(&#34;ListName&#34;) Then ListName = WScript.Arguments.Named(&#34;ListName&#34;)

&#39;Create category filter
If InStr(Categories,&#34;,&#34;) Then arrCat = Split(Categories,&#34;,&#34;) Else arrCat = Array(Categories)
WQL = &#34;Select * from SMS_UpdateCategoryInstance where CategoryTypeName=&#39;UpdateClassification&#39;&#34;
Set SCCMCats = SCCM.ExecQuery(WQL)
For Each SCCMCat in SCCMCats
	If Instr(SCCMCat.LocalizedCategoryInstanceName,&#34; &#34;) Then Words = Split(SCCMCat.LocalizedCategoryInstanceName,&#34; &#34;) Else Words=Array(SCCMCat.LocalizedCategoryInstanceName)
	Initials = &#34;&#34;
	For I = LBound(Words) to UBound(Words)
		Initials = Initials &#038; UCase(Left(Words(I),1))
	Next
	For I = LBound(arrCat) to UBound(arrCat)
		If arrCat(I) = Initials Then arrCat(I) = SCCMCat.CategoryInstance_UniqueID
	Next
Next
CategoryFilter = &#34; and (&#34;
For I = LBound(arrCat) to UBound(arrCat)
	CategoryFilter = CategoryFilter &#038; &#34;CategoryInstance_UniqueIDs=&#39;&#34; &#038; arrCat(I) &#038; &#34;&#39; or &#34;
Next

&#39;Include product filter
If Instr(IncludeProducts,&#34;,&#34;) Then arrProducts = Split(IncludeProducts,&#34;,&#34;) Else arrProducts = Array(IncludeProducts)
WQL = &#34;Select * from SMS_UpdateCategoryInstance where CategoryTypeName=&#39;Product&#39;&#34;
Set SCCMProds = SCCM.ExecQuery(WQL)
For Each SCCMProd in SCCMProds
	For I = LBound(arrProducts) to UBound(arrProducts)
		If UCase(SCCMProd.LocalizedCategoryInstanceName) = UCase(arrProducts(I)) Then arrProducts(I) = SCCMProd.CategoryInstance_UniqueID
	Next
Next
For I = LBound(arrProducts) to UBound(arrProducts)
	CategoryFilter = CategoryFilter &#038; &#34;CategoryInstance_UniqueIDs=&#39;&#34; &#038; arrProducts(I) &#038; &#34;&#39; or &#34;
Next

CategoryFilter = Left(CategoryFilter,Len(CategoryFilter)-4) &#038; &#34;)&#34;

&#39;Exclude Article Filter
ArticleFilter = &#34; and not (&#34;
For I = LBound(ArticlesToNeverInclude) to UBound(ArticlesToNeverInclude)
	ArticleFilter = ArticleFilter &#038; &#34;ArticleID=&#39;&#34; &#038; ArticlesToNeverInclude(I) &#038; &#34;&#39; or &#34;
Next
ArticleFilter = Left(ArticleFilter,Len(ArticleFilter)-4) &#038; &#34;)&#34;

&#39;Exclude Product Filter
ProductFilter = &#34; and not (&#34;
For I = LBound(ProductsToNeverInclude) to UBound(ProductsToNeverInclude)
	ProductFilter = ProductFilter &#038; &#34;CategoryInstance_UniqueIDs=&#39;&#34; &#038; ProductsToNeverInclude(I) &#038; &#34;&#39; or &#34;
Next
ProductFilter = Left(ProductFilter,Len(ProductFilter)-4) &#038; &#34;)&#34;

&#39;Locate updates that match our criteria
WScript.Echo &#34;Querying for updates...&#34;
WQL = &#34;Select * from SMS_SoftwareUpdate where IsExpired=0 and DateRevised &gt;= &#39;&#34; &#038; RangeStart &#038; &#34;&#39; and LocalizedDisplayName not like &#39;%for Itanium-based Systems%&#39;&#34;
WQL = WQL &#038; &#34; and LocalizedDisplayName not like &#39;%IA64-based%&#39; and LocalizedDisplayName not like &#39;%Windows Embedded%&#39;&#34;
If Not IncludeDeployed Then WQL = WQL &#038; &#34; and IsDeployed=0&#34;
If Not IncludeUnrequired Then WQL = WQL &#038; &#34; and NumMissing&gt;0&#34;
WQL = WQL &#038; CategoryFilter &#038; ArticleFilter &#038; ProductFilter
&#39;WScript.Echo WQL
Set UpdateCollection=SCCM.ExecQuery(WQL)
WScript.Echo &#34;...Found &#34; &#038; UpdateCollection.Count &#038; &#34; update(s) that match criteria&#34;

Dim UpdateCI_IDs()
Redim UpdateCI_IDs(-1)

For Each Update in UpdateCollection
	&#39;Apply some filters to the updates
	WScript.Echo Update.ArticleID &#038; vbTab &#038; Update.DateRevised &#038; vbTab &#038; Update.LocalizedDisplayName
	Redim Preserve UpdateCI_IDs(UBound(UpdateCI_IDs)+1)
	UpdateCI_IDs(UBound(UpdateCI_IDs)) = Update.CI_ID
Next

WScript.Echo
WScript.Echo  &#34;Press ENTER to create the list&#34;
X = WScript.StdIn.ReadLine

&#39;Ensure that the list name is unique
ListNameToUse=ListName
I = 96
WQL = &#34;Select * from SMS_AuthorizationList where LocalizedDisplayName like &#39;&#34; &#038; ListName &#038; &#34;%&#39;&#34;
Set ExistingLists = SCCM.ExecQuery(WQL)
For Each ListItem in ExistingLists
	If Not IsNumeric(Right(ListItem.LocalizedDisplayName,1)) Then
		C = Asc(Right(ListItem.LocalizedDisplayName,1))
		If C &gt; I Then I = C
	End If
Next
If ExistingLists.Count &gt; 0 Then ListNameToUse = ListName &#038; Chr(I+1)
WScript.Echo &#34;Creating Update List &#34; &#038; ListNameToUse

Set Info = SCCM.Get(&#34;SMS_CI_LocalizedProperties&#34;).SpawnInstance_
Info.Description=&#34;Auto-generated Update List&#34;
Info.DisplayName=ListNameToUse
Info.InformativeURL=&#34;&#34;
Info.LocaleID=&#34;1033&#34;
Set List = SCCM.Get(&#34;SMS_AuthorizationList&#34;).SpawnInstance_
List.Updates = UpdateCI_IDs
List.LocalizedInformation = Array(Info)
List.Put_
&lt;&#47;script&gt;
&lt;&#47;job&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/42/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deploying Software Updates on a ConfigMgr Client from the Command-Line</title>
		<link>http://jeff.squarecontrol.com/archives/26</link>
		<comments>http://jeff.squarecontrol.com/archives/26#comments</comments>
		<pubDate>Thu, 15 Dec 2011 19:05:15 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[SoftwareUpdates]]></category>
		<category><![CDATA[VBscript]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=26</guid>
		<description><![CDATA[There are times where it is advantageous to deploy software updates for a ConfigMgr client from the command-line.  You may be telnetted/SSH&#8217;d into a command-window or you might be managing a Server Core edition of Windows Server.  I&#8217;ve authored a script that can be used to manage your ConfigMgr software updates on the client. Help [...]]]></description>
			<content:encoded><![CDATA[<p>There are times where it is advantageous to deploy software updates for a ConfigMgr client from the command-line.  You may be telnetted/SSH&#8217;d into a command-window or you might be managing a Server Core edition of Windows Server.  I&#8217;ve authored a script that can be used to manage your ConfigMgr software updates on the client.</p>
<p><span id="more-26"></span></p>
<p>Help for the script can be found by typing in the script name followed by /?.  It is recommended that you run this with the CSCRIPT interpretter since it does produce output.  Also, you <strong><em>must</em></strong> be running a 32-bit command prompt that is elevated to administrator privileges.</p>
<p>One other advantage to this script is that it allows you to force the state of the Software Updates task-bar icon.  When running Terminal Services on Windows 2008 or later operating systems, the &#8220;first&#8221; person to log in will be the &#8220;console&#8221; session (as far as ConfigMgr is concerned) and will see the task-bar icon appear.  If you don&#8217;t want your average users to be able to install software updates without your approval, you can use this script to force the icon off and only turn it on when you need to (or just use the script to deploy updates).  Because of the way that ConfigMgr works, you&#8217;ll need to ensure that <strong>all</strong> other users are actually logged off before you can successfully view and manage the software update process.</p>
<p>Save this script as <strong>SoftwareUpdates.wsf</strong>:</p>
<pre class="prettyprint lang-VB">&lt;job&gt;
&lt;runtime&gt;
&lt;description&gt;
Version 1.0

This script will manage software updates on the local client and allow
you to list and install updates in addition to managing settings for
the ConfigMgr software updates client.

Note: This command must be run from within a 32-bit interpreter using
      Administrative rights.  For 64-bit operating systems, usually, this
      will mean using CSCRIPT from C:\Windows\Syswow64.
&lt;&#47;description&gt;
&lt;named name=ICON helpstring=&#34;Turns the taskbar icon ON, OFF, AUTO&#34; required=false type=string &#47;&gt;
&lt;named name=LIST helpstring=&#34;Lists software updates that are currently applicable&#34; required=false type=simple &#47;&gt;
&lt;named name=SCAN helpstring=&#34;Perform scan using the online catalog&#34; required=false type=simple &#47;&gt;
&lt;named name=EVAL helpstring=&#34;Perform deployment evaluation using cached catalog&#34; required=false type=simple &#47;&gt;
&lt;named name=INSTALL helpstring=&#34;Install updates (defaults to mandatory only)&#34; required=false type=simple &#47;&gt;
&lt;named name=ALL helpstring=&#34;When used with &#47;INSTALL, installs non-mandatory updates&#34; required=false type=simple &#47;&gt;
&lt;named name=ONLY helpstring=&#34;When used with &#47;INSTALL, installs only the specified articles&#34; required=false type=string &#47;&gt;
&lt;named name=NEVER helpstring=&#34;When used with &#47;INSTALL, prevents install of specified articles&#34; required=false type=string &#47;&gt;
&lt;example&gt;
Examples:

SoftwareUpdates.wsf
   Displays the current state of the taskbar icon.

SoftwareUpdates.wsf &#47;ICON:ON
   Forces the taskbar icon to be on whenever updates are available for install.

SoftwareUpdates.wsf &#47;SCAN
   Performs an online catalog scan for updates.  Does not (by itself) make the
   taskbar icon appear if updates are applicable.

SoftwareUpdates.wsf &#47;EVAL
   Performs an evaluation of updates against assignments to see what is
   actually applicable.  This will make the taskbar icon appear if updates are
   applicable and the taskbar icon is set to ON or AUTO.  Can be combined with
   &#47;SCAN to perform an online scan and then evaluation in one execution of the
   command.

SoftwareUpdates.wsf &#47;LIST
   Lists software updates that are applicable on this system.  The &#34;M&#34; column
   in the results will have an &#34;X&#34; if the update is mandatory.

SoftwareUpdates.wsf &#47;INSTALL
   Installs all applicable software updates that are mandatory.  No reboot will
   occur.  This can be modified by the following switches:
      &#47;ALL -   Installs non-mandatory updates as well
      &#47;ONLY -  Installs only the matching software updates by article ID
               Use the format &#47;ONLY:&#34;123456,234567,345678&#34;
      &#47;NEVER - Prevents installation of updates matching specified article ID
               Use the format &#47;NEVER:&#34;123456,234567,345678&#34;

Scan, Evaluation, and Installation can be combined into one command line:
   SoftwareUpdates.wsf &#47;SCAN &#47;EVAL &#47;INSTALL &#47;ALL
&lt;&#47;example&gt;
&lt;&#47;runtime&gt;

&lt;script language=VBScript&gt;

Set UpdatesDeployment = CreateObject(&#34;UDA.CCMUpdatesDeployment&#34;)
Set Client = CreateObject(&#34;CPApplet.CPAppletMgr&#34;)
Set DepAgentWMI = GetObject(&#34;winmgmts:&#47;&#47;.&#47;root&#47;ccm&#47;softwareupdates&#47;deploymentagent&#34;)
Set aNamed = WScript.Arguments.Named
Set SO = WScript.StdOut
Set FSO = CreateObject(&#34;Scripting.FileSystemObject&#34;)
Spinner = Array(&#34;-&#34;,&#34;\&#34;,&#34;|&#34;,&#34;&#47;&#34;)

If aNamed.Exists(&#34;ICON&#34;) Then
	SetIcon
End If

If aNamed.Count = 0 or aNamed.Exists(&#34;ICON&#34;) Then
	IconStat = CLng(UpdatesDeployment.GetuserExperienceFlag)
	Select Case IconStat
		Case 0: SO.WriteLine &#34;Software Updates icon is set to AUTO (policy-based)&#34;
		Case 1: SO.WriteLine &#34;Software Updates icon is set to ON (always visible when updates available)&#34;
		Case 2: SO.WriteLine &#34;Software Updates icon is set to OFF (never visible)&#34;
	End Select
End If

If aNamed.Exists(&#34;LIST&#34;) Then ListUpdates

If aNamed.Exists(&#34;SCAN&#34;) Then ScanUpdates

If aNamed.Exists(&#34;EVAL&#34;) Then EvaluateUpdates

If aNamed.Exists(&#34;INSTALL&#34;) Then InstallUpdates

Sub SetIcon()
	Select Case UCase(aNamed(&#34;ICON&#34;))
		Case &#34;ON&#34;, &#34;+&#34;, &#34;1&#34;, &#34;TRUE&#34;, &#34;T&#34;: NewValue = 1
		Case &#34;OFF&#34;, &#34;-&#34;, &#34;0&#34;, &#34;FALSE&#34;, &#34;F&#34;: NewValue = 2
		Case Else: NewValue = 0
	End Select
	UpdatesDeployment.SetUserExperienceFlag NewValue
End Sub

Function ListUpdates()
	Set UpdatesCollection = UpdatesDeployment.EnumerateUpdates(2, TRUE, progress)
	SO.WriteLine &#34;There are &#34; &#038; UpdatesCollection.Getcount() &#038; &#34; update(s) listed.&#34; &#038; vbCrLf

	SO.WriteLine &#34;M Article Bulletin Title                                        State&#34;
	SO.WriteLine &#34;- ------- -------- -------------------------------------------- ---------------&#34;

	For I = 0 to UpdatesCollection.GetCount()-1
		Set Update = UpdatesCollection.GetUpdate(I)

		On Error Resume Next

		Data=Update.GetEnforcementDeadline()
		If CLng(Data) = 0 Then
			SO.Write &#34;  &#34;
		Else
			SO.Write &#34;X &#34;
		End If
		Err.Clear		

		Data = Update.GetArticleId()
		If Err.Number = 0 Then
			SO.Write Truncate(Data,7) &#038; &#34; &#34;
		Else
			SO.Write Space(8)
		End If
		Err.Clear

		Data = Update.GetBulletinId()
		If Err.Number = 0 Then
			SO.Write Truncate(Data,8) &#038; &#34; &#34;
		Else
			SO.Write &#34;none     &#34;
		End If
		Err.Clear

		Data = Update.GetName(1033)
		If Err.Number = 0 Then
			SO.Write Truncate(Data,44) &#038; &#34; &#34;
		Else
			SO.Write Truncate(Err.Description,44) &#038; &#34; &#34;
		End If
		Err.Clear

		Update.GetProgress Data, Progress, ErrorCode
		If Err.Number = 0 Then
			Select Case Data
				Case 0: 
					Data2 = Update.GetState()
					If Err.Number = 0 Then
						Select Case Data2
							Case 0: SO.Write Truncate(&#34;Not Present&#34;,15)
							Case 1: SO.Write Truncate(&#34;Present&#34;,15)
							Case 2: SO.Write Truncate(&#34;Not Applicable&#34;,15)
							Case 3: SO.Write Truncate(&#34;Unknown&#34;,15)
							Case 4: SO.Write Truncate(&#34;Eval Error&#34;,15)
							Case 5: SO.Write Truncate(&#34;Not Evaluated&#34;,15)
						End Select
					Else
						SO.Write Truncate(&#34;None&#34;,15)
					End If
					Err.Clear
				Case 1: SO.Write Truncate(&#34;Available&#34;,15)
				Case 2: SO.Write Truncate(&#34;Submitted&#34;,15) : progress = 1
				Case 3: SO.Write Truncate(&#34;Detecting&#34;,15) : progress = 1
				Case 4: SO.Write Truncate(&#34;Download CI Definition&#34;,15) : progress = 1
				Case 5: SO.Write Truncate(&#34;Download SDM Package&#34;,15) : progress = 1
				Case 6: SO.Write Truncate(&#34;Pre-download&#34;,15) : progress = 1
				Case 7: SO.Write Truncate(&#34;Downloading&#34;,15) : progress = 1
				Case 8: SO.Write Truncate(&#34;Waiting to install&#34;,15) : progress = 1
				Case 9: SO.Write Truncate(&#34;Installing&#34;,15) : progress = 1
				Case 10: SO.Write Truncate(&#34;Pending Soft Reboot&#34;,15)
				Case 11: SO.Write Truncate(&#34;Pending Hard Reboot&#34;,15)
				Case 12: SO.Write Truncate(&#34;Waiting Reboot&#34;,15)
				Case 13: SO.Write Truncate(&#34;Verifying&#34;,15) : progress = 1
				Case 14: SO.Write Truncate(&#34;Install Complete&#34;,15)
				Case 15: SO.Write Truncate(&#34;Error:&#34; &#038; ErrorCode, 15)
				Case 16: SO.Write Truncate(&#34;Waiting for Window&#34;,15)
				Case Else: SO.Write Truncate(Data,15)
			End Select
		End If
		Err.Clear

		On Error Goto 0

		SO.WriteLine

	Next

	ListUpdates = Array(UpdatesCollection.GetCount(), progress)
End Function

Function Truncate(strIn, intLength)
	Dim strOut
	strOut = Left(strIn,intLength)
	Truncate = strOut &#038; Space(intLength-Len(strOut))
End Function

Sub ScanUpdates
	SO.WriteLine &#34;Initiating a scan for updates using online catalog data.&#34;

	&#39;Determine the last log entry time so that we can watch for END entries
	Set WULog = FSO.OpenTextFile(&#34;C:\Windows\WindowsUpdate.log&#34;)
	Do Until WULog.AtEndOfStream
		L = Split(WULog.ReadLine(),vbTab)
		EntryTime = CDate(L(0) &#038; &#34; &#34; &#038; Left(L(1),8))
	Loop
	WULog.Close
	LastEntry = EntryTime

	&#39;Initiate the scan
	Set ActionsCollection = Client.GetClientActions()
	For Each Action in ActionsCollection
		If Action.Name = &#34;Updates Source Scan Cycle&#34; Then Action.PerformAction
	Next

	&#39;Wait a few seconds before we start to look for the end time
	SO.WriteLine &#34;Waiting one second&#34;
	WScript.Sleep 1000

	&#39;Start to scan the log, looking for the end entry
	SO.WriteLine &#34;Tracking WU Log for Completion Entry...&#34;
	EndFound = False
	WaitCount = 0
	Do Until EndFound
		Set WULog = FSO.OpenTextFile(&#34;C:\Windows\WindowsUpdate.log&#34;)
		Do Until WULog.AtEndOfStream
			L = Split(WULog.ReadLine(),vbTab)
			EntryTime = CDate(L(0) &#038; &#34; &#34; &#038; Left(L(1),8))
			If EntryTime &gt; LastEntry Then
				If L(4) = &#34;COMAPI&#34; Then
					If L(5) = &#34;--  END  --  COMAPI: Search &#91;ClientId = CcmExec&#93;&#34; Then EndFound = True
				End If
			End If
		Loop
		WULog.Close
		SO.Write Chr(8) &#038; Spinner(WaitCount mod 4)
		WaitCount = WaitCount + 1
		WScript.Sleep 250
	Loop
	SO.WriteLine Chr(8) &#038; &#34;...Search completed&#34;
	WScript.Sleep 500
End Sub

Sub EvaluateUpdates()
	SO.WriteLine &#34;Initiating a deployment evaluation scan for updates using cached catalog data.&#34;

	Set ActionsCollection = Client.GetClientActions()
	For Each Action in ActionsCollection
		If Action.Name = &#34;Software Updates Assignments Evaluation Cycle&#34; Then Action.PerformAction
	Next

	SO.WriteLine &#34;...Initated&#34;

	WScript.Sleep 5000
	Set JobMonitor = DepAgentWMI.Get(&#34;CCM_AssignmentJobEx1&#34;).Instances_
	Do Until JobMonitor.Count = 0
		SO.Write String(80,Chr(8))
		SO.Write &#34;Waiting for &#34; &#038; JobMonitor.Count &#038; &#34; evaluation jobs to finish...&#34;
		WScript.Sleep 1000
		Set JobMonitor = DepAgentWMI.Get(&#34;CCM_AssignmentJobEx1&#34;).Instances_
	Loop
	SO.Write String(80,Chr(8)) &#038; Space(79) &#038; String(79,Chr(8))
	SO.WriteLine &#34;Evaluation completed&#34;

	&#39;Show the updates that are now applicable
	SO.WriteLine
	ListUpdates
End Sub

Sub InstallUpdates()
	&#39;This command will install mandatory updates (unless modified by &#47;ALL, &#47;ONLY, or &#47;NEVER)

	Set UpdatesToInstall = CreateObject(&#34;Scripting.Dictionary&#34;)
	Set OnlyUpdates = CreateObject(&#34;Scripting.Dictionary&#34;)
	Set NeverUpdates = CreateObject(&#34;Scripting.Dictionary&#34;)

	SO.WriteLine &#34;Preparing to install updates&#34;

	If aNamed.Exists(&#34;NEVER&#34;) Then
		If Instr(aNamed(&#34;NEVER&#34;),&#34;,&#34;) &gt; 0 Then
			Temp = Split(aNamed(&#34;NEVER&#34;),&#34;,&#34;)
			For I = LBound(Temp) to UBound(Temp)
				If Not NeverUpdates.Exists(UCase(Temp(I))) Then NeverUpdates.Add UCase(Temp(I)),UCase(Temp(I))
			Next
		Else
			NeverUpdates.Add UCase(aNamed(&#34;NEVER&#34;)),UCase(aNamed(&#34;NEVER&#34;))
		End If
	End If

	UseOnly = False
	If aNamed.Exists(&#34;ONLY&#34;) Then
		UseOnly = True
		If Instr(aNamed(&#34;ONLY&#34;),&#34;,&#34;) &gt; 0 Then
			Temp = Split(aNamed(&#34;ONLY&#34;),&#34;,&#34;)
			For I = LBound(Temp) to UBound(Temp)
				If Not OnlyUpdates.Exists(Ucase(Temp(I))) Then OnlyUpdates.Add UCase(Temp(I)),UCase(Temp(I))
			Next
		Else
			OnlyUpdates.Add UCase(aNamed(&#34;ONLY&#34;)),UCase(aNamed(&#34;ONLY&#34;))
		End If
	End If

	&#39;Get all applicable updates
	Set UpdatesCollection = UpdatesDeployment.EnumerateUpdates(2, TRUE, progress)

	&#39;Run through them and build our list of updates to deploy
	For I = 0 to UpdatesCollection.GetCount()-1
		Set Update = UpdatesCollection.GetUpdate(I)
		IncludeThis = False
		ArticleID = UCase(Update.GetArticleId())
		If Not NeverUpdates.Exists(ArticleId) Then
			If UseOnly Then
				If OnlyUpdates.Exists(ArticleId) Then
					IncludeThis = True
				End If
			ElseIf aNamed.Exists(&#34;ALL&#34;) Then
				IncludeThis = True
			Else
				If CLng(Update.GetEnforcementDeadline()) &lt;&gt; 0 Then
					If Now() &gt; CDate(Update.GetEnforcementDeadline()) Then IncludeThis = True
				End If
			End If
		End If

		If IncludeThis Then
			ID = Update.GetId()
			UpdatesToInstall.Add ID, Update
		End If
	Next

	If progress = 0 Then	&#39;No other job in progress
		If UpdatesToInstall.Count &gt; 0 Then	&#39;We have selected updates to install
			SO.WriteLine &#34;Set to install &#34; &#038; UpdatesToInstall.Count &#038; &#34; update(s).&#34;
			UpdatesDeployment.InstallUpdates UpdatesToInstall.Keys, 0, 11

			SO.WriteLine &#34;Will start status check in 10 seconds.&#34; &#038; vbCrLf
			WScript.Sleep 8000

			InstallDone = False
			Do Until InstallDone
				WScript.Sleep 1000
				Status = ListUpdates()
				If Status(1) = 0 Then InstallDone = True
				If Status(0) = 0 Then InstallDone = True

				SO.WriteLine
			Loop

			SO.WriteLine &#34;Update installation is completed.  Please reboot if required.&#34;
		Else
			SO.WriteLine &#34;There are no updates that match your criteria.&#34;
			SO.WriteLine &#34;Run SoftwareUpdates.wsf &#47;LIST to view applicable updates.&#34;
			SO.WriteLine &#34;If no updates are manadatory, try the &#47;INSTALL &#47;ALL switches.&#34;
		End If
	Else
		SO.WriteLine &#34;Another installation is in progress.  Please wait for that to complete.&#34;
	End If
End Sub

&lt;&#47;script&gt;
&lt;&#47;job&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/26/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Active Directory Rights Management Services Templates</title>
		<link>http://jeff.squarecontrol.com/archives/21</link>
		<comments>http://jeff.squarecontrol.com/archives/21#comments</comments>
		<pubDate>Thu, 15 Dec 2011 02:37:18 +0000</pubDate>
		<dc:creator>Jeff Huston</dc:creator>
				<category><![CDATA[Microsoft Systems Management]]></category>
		<category><![CDATA[AD]]></category>
		<category><![CDATA[ConfigMgr]]></category>
		<category><![CDATA[GroupPolicy]]></category>
		<category><![CDATA[RMS]]></category>

		<guid isPermaLink="false">http://jeff.squarecontrol.com/?p=21</guid>
		<description><![CDATA[The title is a bit of a mouthful, but here I&#8217;m talking about AD RMS templates and how to distribute them to client computers. Microsoft provides a pair of scheduled tasks that are designed to update the templates on the client computer.  By default, they are disabled and you&#8217;ll need to enable them to get [...]]]></description>
			<content:encoded><![CDATA[<p>The title is a bit of a mouthful, but here I&#8217;m talking about AD RMS templates and how to distribute them to client computers.</p>
<p><span id="more-21"></span></p>
<p>Microsoft provides a pair of scheduled tasks that are designed to update the templates on the client computer.  By default, they are disabled and you&#8217;ll need to enable them to get them to work.  You can find them in Task Scheduler, in the task library, under Microsoft\Windows\Active Directory Rights Management Services Client.  There is an &#8220;Automatic&#8221; task (that runs based on a schedule) and a &#8220;Manual&#8221; task that is initiated by the end-user.  Both run as the end-user (but elevated rights are required to enable/disable the tasks).</p>
<p>The tasks call out to a COM object to actually handle the update of the templates.  In the environment that I work in, this COM object utterly failed (in fact, it would outright delete existing templates off of the client computers!).</p>
<p>So, we decided to roll our own and perform the deployment via System Center Configuration Manager.  For this deployment, I ended up creating two packages.  One has a script that runs as an Administrator and disables the scheduled task (using the SCHTASKS command).  The second is the one that actually copies the RMS template XML files to the user&#8217;s application data folder (since this is specific to each user, this program runs in the user&#8217;s context).</p>
<p>For your reference, the template path is %UserProfile%\AppData\Local\Microsoft\DRM\Templates, but can be changed by registry key (which can be managed by Group Policy).</p>
<p>Since you&#8217;ll only have one RMS service per forest, I feel pretty confident that you can merely wipe out any existing XML files in that template directory before replacing them with your properly authored ones.</p>
<p>For this advertisement, I choose to run it once per week, regardless of connectivity (fast/slow) by downloading it to the local cache directory.  This way, we can have an update &#8220;roll out&#8221; period of about a week to the majority of systems and catch the rest when they return to the network.  Users only need the templates when they author documents or emails that are then rights protected; once the template is applied, the XML isn&#8217;t needed for opening or editing the files.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeff.squarecontrol.com/archives/21/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

