<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Configuration Manager PFE Kevin</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/cmpfekevin/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/feed.xml</link>
    <description />
    <lastBuildDate>Thu, 14 Jun 2018 15:50:34 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Updating ConfigMgr Linux Clients</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/updating-configmgr-linux-clients</link>
      <pubDate>Thu, 14 Jun 2018 11:50:33 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/?p=745</guid>
      <description><![CDATA[Jeff Butte published a great blog showing a way to manage the upgrade of your Linux...]]></description>
      <content:encoded><![CDATA[Jeff Butte published a great <a href="https://blogs.technet.microsoft.com/jeffbutte/2018/03/09/upgrading-system-center-configuration-manager-sccm-linux-clients/">blog </a>showing a way to manage the upgrade of your Linux clients.

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>ConfigMgr Export/Import Hardware Inventory Classes</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/configmgr-exportimport-hardware-inventory-classes</link>
      <pubDate>Thu, 05 Apr 2018 08:50:05 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/?p=725</guid>
      <description><![CDATA[Here is something that I have run into a few times now so I created a script to help make all our...]]></description>
      <content:encoded><![CDATA[Here is something that I have run into a few times now so I created a script to help make all our lives a bit easier.

When applying updates to the ConfigMgr environment, modifications to the Hardware Inventory classes in the default and custom client settings sometimes get reset to the default.  For some people and environments, this might not matter too much.  However, if you have heavily customized Hardware Inventory Class settings or many custom client settings that you might want to preserve, this can be an annoyance.

I decided the create a PowerShell script that will export all the current Hardware Inventory Class settings from the default and custom client settings into an XML file.  The script can also then use the same XML file to import the setting back (post update).

You can find the full script <a href="https://gallery.technet.microsoft.com/scriptcenter/ConfigMgr-Export-Import-bab6f0cf">here</a>.

&nbsp;

What I will do here, like I typically do, it break the script down for you as a learning exercise.

The first part of the script just sets up our variables to be used:
<div>
<pre><span>[cmdletbinding</span><span>()</span><span>]</span>
<span>param</span><span>(</span>
<span>    </span><span>[parameter</span><span>(</span><span>Mandatory</span><span>=$true)</span><span>]</span>
<span>    </span><span>[ValidatePattern</span><span>('.*(.</span><span>xml</span><span>)</span><span>')</span><span>]</span>
<span>    </span><span>[String]</span>
<span>    </span><span>$</span><span>XMLFile</span><span>,
</span>
<span>    </span><span>[switch]</span>
<span>    </span><span>$</span><span>Import</span><span>,
</span>
<span>    </span><span>[parameter</span><span>(</span><span>Mandatory</span><span>=$true)</span><span>]</span>
<span>    </span><span>[string]</span>
<span>    </span><span>$</span><span>SiteCode</span><span>,</span>

<span>    </span><span>[parameter</span><span>(</span><span>Mandatory</span><span>=$true)</span><span>]</span>
<span>    </span><span>[string]</span>
<span>    </span><span>$</span><span>CMProvider</span><span> </span><span>=</span><span> </span><span>"."</span>
<span>)</span>

<span>$</span><span>CIMProps</span><span> </span><span>=</span><span> @{</span>
<span>    ComputerName </span><span>=</span><span> </span><span>$</span><span>CMProvider</span>
<span>    Namespace </span><span>=</span><span> </span><span>"root\sms\site_</span><span>$($</span><span>SiteCode</span><span>)</span><span>"</span>
<span>}</span>

<span>$</span><span>TodaysDate</span><span> </span><span>=</span><span> </span><span>get-date</span><span> </span><span>-</span><span>Format </span><span>"yyyy-MM-dd-HHmmss"</span></pre>
</div>
We have defined 4 parameters that will be used in the script; XMLFile, Import, SiteCode, CMProvider.

The SiteCode and CMProvider are required for the script to know what server hosts the CMProvider and the SiteCode is required to know the correct WMI Namespace to connect to.

The XMLFile is the name of the file we will be exporting the settings to or importing the settings from. This parameter has a Regular Expression ValidatePattern to ensure the file name ends with .XML.  This is important in this case because we later do a "split" on the file name at the .xml part to include today's date for some version control.

The Import switch parameter we use at the end to determine what "mode" we are running in.

&nbsp;

The next part of the script is the ExportClientHardwareInventoryClasses scriptblock.  This is the part that actually connects to the ConfigMgr Provider, queries for the client settings, and saves the information to an XML File.
<div>
<pre><span>$</span><span>ExportClientHardwareInventoryClasses</span><span> </span><span>=</span><span> {</span></pre>
</div>
We start off by splitting the XMLFile name and adding today's date to it and setting up an array (ExportHWInvClasses) to store our results.
<div>
<pre><span>    </span><span>$</span><span>File</span><span> </span><span>=</span><span> </span><span>$</span><span>XMLFile</span><span> </span><span>-split</span><span> </span><span>'.xml'</span>
<span>    </span><span>$</span><span>File</span><span> </span><span>=</span><span> </span><span>"</span><span>$($</span><span>XMLFile</span><span>)</span><span>-</span><span>$($</span><span>TodaysDate</span><span>)</span><span>.xml"</span>
<span>    </span><span>$</span><span>ExportHWInvClasses</span><span> </span><span>=</span><span> </span><span>@()</span><span>    
</span></pre>
</div>
Next, we connect to the ConfigMgr provider using the values stored in the $CIMProps hashtable using the splat (@) operator.  We query the SMS_ClientSettings WMI class and pipe again to Get-CIMInstance in order to retrieve the lazy properties.  This class contains the custom client settings.
<pre><span>    </span><span>$</span><span>ClientSettings</span><span> </span><span>=</span><span> </span><span>Get-CimInstance</span><span> @CIMProps </span><span>-</span><span>ClassName SMS_ClientSettings </span><span>|</span><span> </span><span>Get-CimInstance</span></pre>
Next, we query the SMS_ClientSettingsDefault class as this class contains the default client settings.  We have to do a little data manipulation of the returned object to make it "match" the same as the custom client settings.  The default hardware inventory report id is well known so we create a new property on our resulting object and add the report id.  The Hardware Inventory Agent ID is 15, so we add that value as well since we are filtering on it later.  We then add this to the array of client settings.
<pre><span>    </span><span>$</span><span>DefaultClientSettings</span><span> </span><span>=</span><span>  </span><span>Get-CimInstance</span><span> @CIMProps </span><span>-</span><span>ClassName SMS_ClientSettingsDefault </span><span>|</span><span> </span><span>Get-CimInstance</span>
<span>    </span><span>$</span><span>DefaultClientSettings</span><span> </span><span>|</span><span> </span><span>Add-Member</span><span> </span><span>-</span><span>NotePropertyName AgentConfigurations </span><span>-</span><span>NotePropertyValue @{}</span>
<span>    </span><span>$</span><span>DefaultClientSettings</span><span>.AgentConfigurations.Add</span><span>(</span><span>'AgentID'</span><span>,</span><span>15</span><span>)</span>
<span>    </span><span>$</span><span>DefaultClientSettings</span><span>.AgentConfigurations.Add</span><span>(</span><span>'InventoryReportID'</span><span>,</span><span>'{00000000-0000-0000-0000-000000000001}'</span><span>)</span>
<span>    </span><span>$</span><span>ClientSettings</span><span> </span><span>+=</span><span> </span><span>$</span><span>DefaultClientSettings</span></pre>
<span>The next step is to loop through the clients settings that we have found, extract the InventoryReportID value. We create a hashtable to store the data in, noting the ClientSetting, AgentConfigurations, and the InventoryReport.  The InventoryReport data is gathered by querying the SMS_InventoryReport class with the InventoryReportID to get the details about which inventory classes and properties are enabled for collection.  These are lazy properties so we have to pipe to Get-CimInstance again to get the details.</span>
<pre><span>    </span><span>Foreach</span><span> </span><span>($</span><span>ClientSetting</span><span> </span><span>in</span><span> </span><span>$</span><span>ClientSettings</span><span>)</span><span> {</span>
<span>        </span><span>if</span><span> </span><span>($</span><span>HWInvSetting</span><span> </span><span>=</span><span> </span><span>$</span><span>ClientSetting</span><span>.AgentConfigurations</span><span> </span><span>|</span><span> </span><span>where</span><span> {</span><span>$</span><span>_</span><span>.AgentID</span><span> </span><span>-eq</span><span> </span><span>15</span><span>}</span><span>)</span><span> {</span>
<span>            </span><span>write-verbose</span><span> </span><span>$</span><span>HWInvSetting</span><span>.InventoryReportID</span><span> </span>
<span>            </span><span>$</span><span>HWInvDetails</span><span> </span><span>=</span><span> @{</span>
<span>                ClientSetting </span><span>=</span><span> </span><span>$</span><span>ClientSetting</span>
<span>                AgentConfiguration </span><span>=</span><span> </span><span>$</span><span>HWInvSetting</span>
<span>                InventoryReport </span><span>=</span><span>  </span><span>Get-CimInstance</span><span> @CIMProps </span><span>-</span><span>ClassName SMS_InventoryReport </span><span>-</span><span>Filter </span><span>(</span><span>'InventoryReportID = "'</span><span> </span><span>+</span><span> </span><span>$</span><span>HWInvSetting</span><span>.InventoryReportID</span><span> </span><span>+</span><span> </span><span>'"'</span><span>)</span><span> </span><span>|</span><span> </span><span>Get-CimInstance</span>
<span>            }</span>
<span>            </span><span>$</span><span>ExportHWInvClasses</span><span> </span><span>+=</span><span> </span><span>$</span><span>HWInvDetails</span>
<span>        }</span>
<span>    }</span></pre>
Then we export the results to an the XML File
<pre><span>    </span><span>Export-Clixml</span><span> </span><span>-</span><span>InputObject </span><span>$</span><span>ExportHWInvClasses</span><span> </span><span>-</span><span>Path </span><span>$</span><span>File</span>
<span>}</span></pre>
The next section is the scriptblock that is used to Import Client Hardware Inventory Classes.  If takes the XMLFile as an input to read in the data that was stored.
<div>
<pre><span>$</span><span>ImportClientHardwareInventoryClasses</span><span> </span><span>=</span><span> {
</span><span>    </span><span>$</span><span>ImportedHWInvClasses</span><span> </span><span>=</span><span> </span><span>Import-Clixml</span><span> </span><span>$</span><span>XMLFile
</span></pre>
</div>
Then we loop through the resulting object, connect to WMI, and retrieve the matching Inventory Report, set the ReportClasses on the Inventory Report to those from the XML file, and then set that object back in WMI.  This results in updating the Hardware Inventory Classes/Properties on each Client Settings that was exported.
<div>
<pre><span>    </span><span>foreach</span><span> </span><span>($</span><span>ClientSetting</span><span> </span><span>in</span><span> </span><span>$</span><span>ImportedHWInvClasses</span><span>)</span><span> {</span>
<span>        </span><span>$</span><span>InventoryReport</span><span> </span><span>=</span><span> </span><span>Get-CimInstance</span><span> @CIMProps </span><span>-</span><span>ClassName SMS_InventoryReport </span><span>-</span><span>Filter </span><span>(</span><span>'InventoryReportID = "'</span><span>+</span><span> </span><span>$</span><span>ClientSetting</span><span>.InventoryReport.InventoryReportID</span><span> </span><span>+</span><span> </span><span>'"'</span><span>)</span><span> </span><span>|</span><span> </span><span>Get-CimInstance</span>
<span>        </span><span>$</span><span>InventoryReport</span><span>.ReportClasses</span><span> </span><span>=</span><span> </span><span>$</span><span>ClientSetting</span><span>.InventoryReport.ReportClasses</span>
<span>        </span><span>$</span><span>InventoryReport</span><span> </span><span>|</span><span> </span><span>Set-CimInstance</span>
<span>    }</span>
<span>}
</span></pre>
Finally, we have the control portion of the script which determines which script block gets executed, the import or export.  This is based on the switch parameter provided to the script.  If -import is not added to the parameters when run, the script is running in export mode.  With -import entered, the script runs in import mode.
<div>
<pre><span>If</span><span> </span><span>($</span><span>Import</span><span>)</span><span> {</span>
<span>    </span><span>Invoke-Command</span><span> </span><span>$</span><span>ImportClientHardwareInventoryClasses</span>
<span>} </span><span>else</span><span> {</span>
<span>    </span><span>Invoke-Command</span><span> </span><span>$</span><span>ExportClientHardwareInventoryClasses</span>
<span>}</span></pre>
</div>
</div>
&nbsp;

Let me know what your thoughts are!

&nbsp;

<hr />

As noted below, all code is provided for sample use only.

Microsoft provides programming examples for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose.

This sample assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. Microsoft support professionals can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific needs. If you have limited programming experience, you may want to contact a Microsoft Certified Partner or the Microsoft fee-based consulting line at (800) 936-5200.

For more information about Microsoft Certified Partners, please visit the following Microsoft Web site: <a href="https://partner.microsoft.com/global/30000104">https://partner.microsoft.com/global/30000104</a>
<div>
<pre></pre>
</div>]]></content:encoded>
    </item>
    <item>
      <title>Using Powershell to Update DNS Records on GoDaddy API</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/using-powershell-to-update-dns-records-on-godaddy-api</link>
      <pubDate>Tue, 27 Sep 2016 14:23:40 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/?p=705</guid>
      <description><![CDATA[I was recently working on using the GoDaddy API in lieu of using dynamicDNS to keep my lab IP up to...]]></description>
      <content:encoded><![CDATA[I was recently working on using the GoDaddy API in lieu of using dynamicDNS to keep my lab IP up to date.  I stumbled across a post on Stack Overflow where someone had already started some work on this, but had not quite got it working.

I was able to take what they had provided, make a couple of changes, and get it working.  It might help you out to!

<a href="https://stackoverflow.com/questions/39123202/error-422-when-using-powershell-to-update-dns-records-on-godaddy-api">https://stackoverflow.com/questions/39123202/error-422-when-using-powershell-to-update-dns-records-on-godaddy-api</a>

Enjoy!

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Schannel SSL and TLS Registry Keys Reporting</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/schannel-ssl-and-tls-registry-keys-reporting</link>
      <pubDate>Sun, 18 Sep 2016 21:07:57 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/?p=625</guid>
      <description><![CDATA[I have seen this topic come up more and more recently. In many cases, organizations wish to report...]]></description>
      <content:encoded><![CDATA[I have seen this topic come up more and more recently. In many cases, organizations wish to report on and manage the Schannel registry values. Configuration Manager can help monitor, report, and implement these changes.

Before modifying any of these settings, please make sure that you understand the implications. Please review <a href="https://support.microsoft.com/en-us/kb/245030">https://support.microsoft.com/en-us/kb/245030</a> very cafeully.

&nbsp;

First, let's look at the register keys/values that are required for SCHANNEL SSL and TLS settings.
<ul>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client</li>
 	<li>HKLM SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server</li>
</ul>
Under each key, there are two values that can be set, Enabled and DisableByDefault.

&nbsp;

In a situation like this, your organization may first wish to collect data about what these registry values are set to (if anything) in the environment. To best accomplish this, we need to extend Hardware Inventory in ConfigMgr to gather these registry settings.

We start by creating entries for the Configuration.mof file. These entries will gather the data from the registry values and store the information in WMI using the WMI Registry Provider.

Download the ZIP file from:
<ul>
 	<li><a href="https://gallery.technet.microsoft.com/scriptcenter/SChannel-SSL-and-TLS-d2e1ff3f">https://gallery.technet.microsoft.com/scriptcenter/SChannel-SSL-and-TLS-d2e1ff3f</a></li>
</ul>
Copy of content of the schannel_ssltls_conf.mof into the configuration.mof file on your CAS/Primary site.

(Place your modifications between the "Added extensions start" and "Added extensions end")

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel01.png"><img width="583" height="380" class="alignnone wp-image-626" alt="schannel01" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel01.png" /></a>

This will allow your clients to create a WMI Class named SCHANNEL_SSLTLS in root\cimv2 that will contain data from the SCHANNEL SSL and TLS registry values

You can confirm this after the clients process policy be using wbemtest or powershell to see that the class exists. If there are not values set in the registry, the instances may show null data.

Next, the schannel_ssltls_sms.mof needs to be imported into the default clients settings hardware inventory. When importing, you can choose whether or not you wish to enable the collection of the data in the default settings or not.

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel02.png"><img width="490" height="382" class="alignnone wp-image-635" alt="schannel02" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel02.png" /></a>

Select Set Classes…

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel03.png"><img width="490" height="421" class="alignnone wp-image-645" alt="schannel03" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel03.png" /></a>

Choose Import…

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel04.png"><img width="465" height="302" class="alignnone wp-image-655" alt="schannel04" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel04.png" /></a>

Browse to where you extracted the ZIP and select the schannel_ssltls_def.mof and choose open

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel05.png"><img width="372" height="410" class="alignnone wp-image-656" alt="schannel05" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel05.png" /></a>

Select Import

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel06.png"><img width="596" height="180" class="alignnone wp-image-666" alt="schannel06" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel06.png" /></a>

And the new class shows at the top of the list (later it will be in Alpha order). If you wish to not collect the data in the Default Client Settings, you can uncheck the box now, otherwise all clients will begin to try to attempt to collect data from the SCHANNEL_SSLTLS WMI Class.

&nbsp;

Once the clients begin to collect the data, you can view the information on each client under their Resource Explorer.

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel07.png"><img width="462" height="303" class="alignnone wp-image-675" alt="schannel07" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel07.png" /></a>

&nbsp;

If you have used the provided files, there is also a RDL file that can be loaded into Reporting Services to provide a Per Collection repot for the Schannel Settings.

<a href="https://msdnshared.blob.core.windows.net/media/2016/09/schannel08.png"><img width="557" height="391" class="alignnone wp-image-685" alt="schannel08" src="https://msdnshared.blob.core.windows.net/media/2016/09/schannel08.png" /></a>]]></content:encoded>
    </item>
    <item>
      <title>Top Console/Primary User</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/top-consoleprimary-user</link>
      <pubDate>Fri, 12 Aug 2016 13:12:23 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/?p=615</guid>
      <description><![CDATA[Check out this blog over at AskPFEPLat by Stephen Mathews.  It's another take on determine the...]]></description>
      <content:encoded><![CDATA[Check out this blog over at AskPFEPLat by Stephen Mathews.  It's another take on determine the primary user of a computer.

https://blogs.technet.microsoft.com/askpfeplat/2016/07/12/determining-the-dominant-user-and-setting-the-managedby-computer-attribute/

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Using PoSH to get Folder Size</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/using-posh-to-get-folder-size</link>
      <pubDate>Fri, 08 Jul 2016 14:59:45 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/?p=505</guid>
      <description><![CDATA[I don't know about you, but there are time when I am trying to track down where all my hard drive...]]></description>
      <content:encoded><![CDATA[I don't know about you, but there are time when I am trying to track down where all my hard drive space is going. When your system has User Account Control (UAC) enabled, right clicking on a folder to get the properties may not always show the right size.

I turn to PowerShell for a solution.

Start off by launching PowerShell as Administrator
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/015.png"><img class="alignnone size-medium wp-image-515" src="https://msdnshared.blob.core.windows.net/media/2016/07/015-300x227.png" alt="01" width="300" height="227" /></a></p>
Then change to the directory that contains the folder you want to see the size of, for example, c:\users and run the dir . cmdlet
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/026.png"><img class="alignnone wp-image-525 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/026.png" alt="02" width="495" height="282" /></a></p>
To determine a folder size, we need to recursively query the folder for all the items in the folder and add up their file size. With the dir (get-childItem) cmdlet, the "length" property is the file size.

We can see this from running
<pre style="padding-left: 30px">dir .\Administrator -r</pre>
<p style="padding-left: 30px"> <a href="https://msdnshared.blob.core.windows.net/media/2016/07/036.png"><img class="alignnone wp-image-526 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/036.png" alt="03" width="474" height="505" /></a></p>
In this case, I have 4 files that have a "length", now I want to "measure" the size of each one of these items in my folder. We can pipe our results to the Measure-Object cmdlet that allows us to sum the length property
<pre style="padding-left: 30px">dir .\Administrator -r | Measure-Object -Property Length -Sum
</pre>
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/044.png"><img class="alignnone wp-image-535 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/044.png" alt="04" width="576" height="154" /></a></p>
We are telling Measure-object to Sum the length property on all the items below .\Administrator. We can see there are 4 files that have a total size of 1942 bytes

Most of the time, reading size values in bytes is not incredibly useful, so let's change it to MB. We start by just extracting the sum value by piping the results to select-object
<pre style="padding-left: 30px">dir .\Administrator -r | Measure-Object -Property Length -Sum | select -ExpandProperty Sum
</pre>
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/054.png"><img class="alignnone wp-image-536 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/054.png" alt="05" width="776" height="51" /></a></p>
&nbsp;

This provides us with just the value from the measure-object cmdlet. Now you can divide this twice by 1024. The first time to change the format to kilobytes, the second time to megabytes. (Additions in "red")
<pre style="padding-left: 30px"><span style="color: #ff0000">((</span>dir .\Administrator -r | Measure-Object -Property Length -Sum | select -ExpandProperty Sum<span style="color: #ff0000">)/1024/1024)</span></pre>
<p style="padding-left: 30px"><span style="color: #ff0000"> <a href="https://msdnshared.blob.core.windows.net/media/2016/07/063.png"><img class="alignnone wp-image-545 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/063.png" alt="06" width="826" height="28" /></a> </span></p>
Now we have a way to measure the size of a single folder. But I want to know what the size is of each folder in c:\users. This could be pretty tedious if you have lots of profiles on a system. So let's think about how we can do this.

First, I would want to list all the directories/folders that are at the root of c:\users. If we look at all the properties that are available using Get-ChildItem (dir) by using dir | gm, we can see there is a property called PSIsContainer. If this value it true, than the item is a directory, if it's false, it’s a file. Now we can use our Get-ChildItem (dir) cmdlet and pipe the results to where-object cmdlet to filter our results to only show directories
<pre style="padding-left: 30px">dir . | where-object {$_.PSIsContainer -eq $True}</pre>
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/073.png"><img class="alignnone wp-image-555 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/073.png" alt="07" width="550" height="205" /></a></p>
Next, we want to measure to size of each one of these folders, so we will need a ForEach (%) loop to measure each directory. The command might looks something like this:
<pre style="padding-left: 30px">dir . | where-object {$_.PSIsContainer -eq $True} | % {((dir $_ -r | Measure-Object -Property Length -Sum | select -ExpandProperty Sum)/1024/1024)}</pre>
Notice that we have combined out first command to measure a single directory with our second command that returns all directories in the current directory. This allows us to measure all the "sub folders"
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/08.png"><img class="alignnone wp-image-565 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/08.png" alt="08" width="835" height="217" /></a></p>
So now we have results. We see that one folder had no files to measure so it threw an error and the list is a little hard to look at. You have to line up each entry with the results from your "dir . | where-object {$_.PSIsContainer -eq $True}" command.

Maybe we can improve the results a bit. Let's first start with using some .Net code to force our value into a decimal with 2 digits. To do this, we are going to add this code to convert our value, "{0:n2}" -f
<pre style="padding-left: 30px">dir . | where-object {$_.PSIsContainer -eq $True} | % {<span style="color: #ff0000">"{0:n2}" -f</span> ((dir $_ -r | Measure-Object -Property Length -Sum | select -ExpandProperty Sum)/1024/1024)}</pre>
(for more information on formatting numbers, see: <a href="https://technet.microsoft.com/en-us/library/ee692795.aspx">https://technet.microsoft.com/en-us/library/ee692795.aspx</a>)

Using this formatting technique we see that all of our folders have less than 0.00 MB in them.
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/09.png"><img class="alignnone wp-image-566 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/09.png" alt="09" width="830" height="212" /></a></p>
So let's move to a different directory like "Program Files" and get some better results.
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/102.png"><img class="alignnone wp-image-575 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/102.png" alt="10" width="837" height="510" /></a></p>
Now the data looks better, however, it's still hard to determine which folder is which size. Here we can use a PowerShell Hash Table to help out. Let's define an empty Hash Table
<pre style="padding-left: 30px">$FolderSize = @{}</pre>
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/116.png"><img class="alignnone wp-image-585 size-full" src="https://msdnshared.blob.core.windows.net/media/2016/07/116.png" alt="11" width="843" height="391" /></a></p>
Next, we need to modify our command a little more to add data to this table instead of printing it to the screen.
<pre style="padding-left: 30px">dir . | where-object {$_.PSIsContainer -eq $True} | % {<span style="color: #ff0000">$FolderSize.Add($_.FullName,</span> "{0:n2}" -f ((dir $_ -r | Measure-Object -Property Length -Sum | select -ExpandProperty Sum)/1024/1024)<span style="color: #ff0000">)</span>}</pre>
We can now look at the data stored in our $FolderSize hash table and since it's an object, we can manipulate it like other object (such as format-list (fl)). It makes it easy to now line up the directory and the size of the directory.
<p style="padding-left: 30px"><a href="https://msdnshared.blob.core.windows.net/media/2016/07/121.png"><img class="alignnone size-full wp-image-595" src="https://msdnshared.blob.core.windows.net/media/2016/07/121.png" alt="12" width="814" height="791" /></a></p>
So let's bring is all together.

First we create a empty Hash table. Second we measure all the sub-directories that exists in the current directory and put them into the has table. Finally we view the hash table.
<pre style="padding-left: 30px">$FolderSize = @{}</pre>
<pre style="padding-left: 30px">dir . | where-object {$_.PSIsContainer -eq $True} | % {$FolderSize.Add($_.FullName, "{0:n2}" -f ((dir $_ -r | Measure-Object -Property Length -Sum | select -ExpandProperty Sum)/1024/1024))}</pre>
<pre style="padding-left: 30px">$FolderSize</pre>
Alternatively, there is a great tool in the Sysinternals Suite called du.exe that works well.

<a href="https://technet.microsoft.com/en-us/sysinternals/du">https://technet.microsoft.com/en-us/sysinternals/du</a>

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Peer Cache Reporting</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/peer-cache-reporting</link>
      <pubDate>Wed, 06 Jul 2016 19:43:42 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/?p=235</guid>
      <description><![CDATA[Check out this great blog on with an example custom report that Seth built for Peer...]]></description>
      <content:encoded><![CDATA[Check out this great blog on with an example custom report that Seth built for Peer Cache!

&nbsp;

<a href="https://blogs.technet.microsoft.com/setprice/2016/06/29/pe-peer-cache-custom-reporting-examples/">https://blogs.technet.microsoft.com/setprice/2016/06/29/pe-peer-cache-custom-reporting-examples/</a>

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Turning NETSTAT results into an Object</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/turning-netstat-results-into-an-object</link>
      <pubDate>Fri, 11 Dec 2015 12:50:00 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/2015/12/11/turning-netstat-results-into-an-object/</guid>
      <description><![CDATA[A customer was trying to extract some data from the netstat command.&nbsp; The customer had...]]></description>
      <content:encoded><![CDATA[<p></p>
<p><span style="font-family:Calibri;font-size:medium;">A customer was trying to extract some data from the netstat command.&nbsp; The customer had already formed part of the syntax, but needed some additional assistance with filtering out the values they wished to see.</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">Let&rsquo;s take a look at the results of the <span style="font-family:courier new,courier;">netstat &ndash;nao</span> command</span></p>
<p></p>
<p style="margin-left:30px;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/6648.01.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/6648.01.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/6648.01.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/6648.01.jpg" border="0" /></a></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">In this case, the customer wanted to filter only on &ldquo;Listening&rdquo; ports.&nbsp; They had already accomplished this by piping the netstat &ndash;nao command to the select-string cmdlet</span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;font-size:medium;">Netstat &ndash;nao | select-string &ldquo;Listening&rdquo;</span></p>
<p style="margin-left:30px;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/0167.02.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/0167.02.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/0167.02.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/0167.02.jpg" border="0" /></a><br /></span></p>
<p></p>
<p></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">They wanted to further filter down the list by looking for only certain ports.&nbsp; Again, this was accomplished by piping the resulting into another select-string cmdlet.</span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">netstat -nao | Select-String &quot;Listening&quot; | Select-String &quot;:80|:3389|:445&quot;&nbsp;</span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:Calibri;font-size:medium;">&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/03.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/03.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/03.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/03.jpg" border="0" /></a></span></p>
<p></p>
<p><span style="font-size:medium;"><span style="font-family:Times New Roman;"></span><span style="font-family:Calibri;">&nbsp;</span></span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">The next part is where the big challenge comes in.&nbsp; The customer only wanted the data from Columns 2 and 5.&nbsp; This would be the bound IP and listening Port and the associated PID.&nbsp; Since we are using netstat the data returned is just text, there is not native way to select those columns.</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">In order to do this, we need to extract the data we want from the lines.&nbsp; We came up with two solutions, the 1 liner and turning the data into an object.</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">Let&rsquo;s start with the 1 liner.</span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">netstat -nao | Select-String &quot;Listening&quot; | Select-String &quot;:80|:3389|:445&quot; | % {$a = $_ -split &#39;\s\s*&#39; ; write-host &quot;$($a[2]), $($a[5])&quot;&nbsp; }&nbsp;</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">In this case, we are piping the results to a foreach (% - alias) loop, and then splitting the value of each line into an array using the whitespace as a delimiter.&nbsp; We are using the regular expression (\s\s*) to identify contiguous whitespace between the column.&nbsp; The remaining values from the split are stored as an array in the $a variable.&nbsp; We then want to write out columns 2 and 5 to the console.</span></p>
<p></p>
<p style="margin-left:30px;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/04.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/04.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/04.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/04.jpg" border="0" /></a></p>
<p></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">Although this does provide the desired output, it&rsquo;s not very pretty.</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">Let&rsquo;s see turn these results into an object instead.</span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">$ListeningPort = @()</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">$GetPorts =&nbsp; netstat -nao | Select-String &quot;Listening&quot; | Select-String &quot;:80|:3389|:445&quot;&nbsp;</span></p>
<p style="margin-left:30px;"></p>
<p><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:courier new,courier;">Foreach ($Port in $GetPorts) {</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;</span><span style="font-family:courier new,courier;">&nbsp;&nbsp; $a = $Port -split &#39;\s\s*&#39;</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; $Ports = New-Object System.Object</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; $Ports | Add-Member -MemberType NoteProperty -Name &#39;BoundIP:Port&#39; -Value $a[2]</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; $Ports | Add-Member -MemberType NoteProperty -Name &#39;PID&#39; -Value $a[5]</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; $ListeningPort += $Ports</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;</span><span style="font-family:courier new,courier;">&nbsp;}</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;</span><span style="font-family:courier new,courier;">$ListeningPort</span></p>
<p style="margin-left:30px;"></p>
<p><span style="font-family:courier new,courier;">&nbsp;</span></p>
<p></p>
<p>&nbsp;</p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">This takes a little more work, put provides much better output.&nbsp; First, we create a variable ($ListeningPort) as an empty array to hold our objects. </span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">$ListeningPort = @()</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">Then we take our command to filter the NETSTAT command to the rows we are interested in and store those in the $GetPorts variable.</span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">$GetPorts =&nbsp; netstat -nao | Select-String &quot;Listening&quot; | Select-String &quot;:80|:3389|:445&quot;&nbsp;</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">Now we run the results through a ForEach loop and for each line, we still split on the whitespace (</span>&#39;\s\s*&#39;<span style="font-family:Calibri;"><span style="font-size:medium;">) and store that data into $a.&nbsp; </span></span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">Foreach ($Port in $GetPorts) {</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $a = $Port -split &#39;\s\s*&#39;</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">After that, we create a System.Object and add two properties for the object, BoundPort:IP and PID.&nbsp; We store the split data in positions 2 and 5 from $a are value in the object.</span></p>
<p></p>
<p style="margin-left:30px;">&nbsp;&nbsp;&nbsp; <span style="font-family:courier new,courier;">$Ports = New-Object System.Object</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp;&nbsp;$Ports | Add-Member -MemberType NoteProperty -Name &#39;BoundIP:Port&#39; -Value $a[2]</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">&nbsp; $Ports | Add-Member -MemberType NoteProperty -Name &#39;PID&#39; -Value $a[5]</span></p>
<p style="margin-left:30px;"></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;font-size:medium;">&nbsp;</span></p>
<p></p>
<p><span style="font-family:Calibri;"><span style="font-size:medium;">We then stuff the resulting object $Ports into the array ($ListeningPorts) that we initialized in the beginning.&nbsp; </span></span></p>
<p></p>
<p style="margin-left:30px;"><span style="font-family:courier new,courier;">$ListeningPort += $Ports</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">The ForEach loop does this for each line from NETSTAT that matches our Select-String queries.&nbsp; The resulting array of objects $ListeningPorts provides a nice clean, exportable output.</span></p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p></p>
<p style="margin-left:30px;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/05.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/05.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/05.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/05.jpg" border="0" /></a></p>
<p style="margin-left:30px;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/06.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/06.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/06.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/06.jpg" border="0" /></a></p>
<p></p>
<p></p>
<p><span style="font-family:Calibri;font-size:small;">This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment.&nbsp; THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.&nbsp; We grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and distribute the object code form of the Sample Code, provided that You agree: (i)&nbsp;to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; (ii)&nbsp;to include a valid copyright notice on Your software product in which the Sample Code is embedded; and (iii)&nbsp;to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits, including attorneys&rsquo; fees, that arise or result from the use or distribution of the Sample Code.&nbsp;</span></p>]]></content:encoded>
    </item>
    <item>
      <title>Case of the never-ending Full Collection Evaluation</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/case-of-the-never-ending-full-collection-evaluation</link>
      <pubDate>Fri, 09 Oct 2015 13:10:00 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/2015/10/09/case-of-the-never-ending-full-collection-evaluation/</guid>
      <description><![CDATA[&nbsp;I was recently working with a customer with a large number of collections set for incremental...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;<span style="font-size:small;">I was recently working with a customer with a large number of collections set for incremental evaluation.&nbsp; The customer had tuned the settings on the primary sites to only run incremental every 30 minutes, their evaluation of incremental normal takes between 10-15 minutes to complete.</span></p>
<p><span style="font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;">Recently, many of the collections began showing the hourglass icon in the console on a consistent basis.&nbsp; Upon investigation, it appeared that one of the primary sites was running almost a constant full evaluation cycle of all their collections.&nbsp;</span></p>
<p><span style="font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;">In the colleval.log, we were able to pick out a message that too out:</span></p>
<p><span style="font-size:small;">spCollBeginIncEvaluation: Too many changes, marking incremental collections for full evaluation</span></p>
<p><span style="font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;">We started looking into why this site was having more changes then the others.&nbsp; We could not determine any logic reason.</span></p>
<p>&nbsp;</p>
<p><span style="font-size:small;">I decided to go to my lab, and take a closer look at the spCollBeginIncEvaluation stored procedure.&nbsp; I found it runs two queries to determine what items are going to be seen as eligible for incremental evaluation.&nbsp;</span></p>
<ul>
<li>
<p><span style="font-size:small;">First, it looks at the number of collections with flag 4 (Incremental) set, have a query rule, and are not currently being evaluated</span></p>
</li>
<li>
<p><span style="font-size:small;">Next, a query identifies computer objects from the CollectionNotifications table and gathers machine ID&#39;s from devices that match the tables used in the query rules from the collections in the previous query.&nbsp;</span></p>
</li>
<li>
<p><span style="font-size:small;">Finally, the stored procedure multiples the number of collections from the first query by the number of machine ID&#39;s from the second query.&nbsp; If the number is bigger than 10,000,000 (yes, 10 million) then full evaluation will be triggered instead of incremental.</span></p>
</li>
</ul>
<p>&nbsp;</p>
<p><span style="font-size:small;">I could not image how we could have more than 10 million &ldquo;changes&rdquo; that needed to be updated, but I started watching the data, and the number of machineID&#39;s return was growing astronomically between cycles, (up to 20,000 machines that would show up on the list).</span></p>
<p><span style="font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;">In this case, I have more 500 collections found that needed incremental evaluation, and 20,000+ machine ID&rsquo;s (500 x 20,000 = 10,000,000).&nbsp; I was over 10 million &ldquo;changes&rdquo;, thus the stored procedure was triggering Full Evaluation.</span></p>
<p><br /><span style="font-size:small;"> So now we needed to understand why 20,000+ were updating data within a 30-minute window.&nbsp;</span></p>
<p><span style="font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;">We took the data from the CollectionNotification table and copied it into excel, and found that of the 20,000 record updates, that 18,000 of them were associated with table name v_CH_ClientSummary.</span></p>
<p style="margin-left:30px;"><span style="font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/01.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/01.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/01.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/01.jpg" border="0" /></a><br /></span></p>
<p>&nbsp;&nbsp;&nbsp;</p>
<p><span style="font-size:small;">So the question became, what is updating this view for so many clients each 30 minutes.&nbsp; Turns out, this view/table updates each time a client requests policy.&nbsp; So, if I have my policy interval set to 60 min, on average, half of my clients are going to request policy within 30 minutes, so If I have 40,000 clients, each 30 minutes, 20,000 clients are going to update policy.&nbsp;</span></p>
<p><span style="font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;">Now, I wanted to find the collections that are using incremental updates and have queries to the v_CH_ClientSummary view, with this query:</span></p>
<p style="margin-left:30px;"><span style="font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/02.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/02.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/02.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/02.jpg" border="0" /></a><br /></span></p>
<p><span style="font-size:small;">&nbsp;&nbsp;</span></p>
<p><span style="font-size:small;">Now that I found the collection(s), I removed the incremental evaluation check box from the collection and the number of machineID&#39;s that needed updating each 30 min went from 20,000 to less than 2,000.</span></p>
<p><span style="font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;">The morale of the story, don&#39;t create collections that use incremental evaluation from the v_CH_ClientSummary view (wmi class SMS_G_System_CH_ClientSummary or in the query builder &#39;Client Status&#39;)</span></p>
<p style="margin-left:30px;"><span style="font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/03.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/03.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/98/39/03.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-98-39/03.png" border="0" /></a><br /></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Also found good reference information here:(<a href="/b/senthilkumar/archive/2014/06/08/configmgr-2012-r2-collection-evaluation-overview.aspx">https://blogs.technet.com/b/senthilkumar/archive/2014/06/08/configmgr-2012-r2-collection-evaluation-overview.aspx</a>)</p>
<p></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p></p>]]></content:encoded>
    </item>
    <item>
      <title>FREE Technology Day - March 14 - Microsoft Reston, VA</title>
      <link>https://docs.microsoft.com/archive/blogs/cmpfekevin/free-technology-day-march-14-microsoft-reston-va</link>
      <pubDate>Sat, 21 Feb 2015 07:28:00 GMT</pubDate>
      <dc:creator><![CDATA[PFE Kevin]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/cmpfekevin/2015/02/21/free-technology-day-march-14-microsoft-reston-va/</guid>
      <description><![CDATA[Hi Everyone!

There is a District of Columbia Maryland Virginia Management User Group (DMVMUG)...]]></description>
      <content:encoded><![CDATA[<p>Hi Everyone!</p>
<p></p>
<p>There is a District of Columbia Maryland Virginia Management User Group (DMVMUG) Conference on March 14th in the Microsoft office in&nbsp; Reston, VA.&nbsp;</p>
<p></p>
<p>Registration is required</p>
<p><a title="https://dmvmug.eventbrite.com" href="https://dmvmug.eventbrite.com">dmvmug.eventbrite.com</a></p>
<p></p>
<p>See you there!</p>
<p></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/9839/00/00/03/64/55/00/Flyer-RestonVA2015.pdf" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-9839-00-00-03-64-55-00/Flyer_2D00_RestonVA2015.pdf">Flyer-RestonVA2015.pdf</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>