<?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>Ken Smith's ConfigMgr Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/kensmith/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/kensmith/feed.xml</link>
    <description>ConfigMgr tips from a Microsoft Premier Field Engineer</description>
    <lastBuildDate>Wed, 17 Apr 2019 04:07:07 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Managing Workstation Uptime with Compliance Settings</title>
      <link>https://docs.microsoft.com/archive/blogs/kensmith/managing-workstation-uptime-with-compliance-settings</link>
      <pubDate>Tue, 04 Nov 2014 08:47:55 GMT</pubDate>
      <dc:creator><![CDATA[Ken Smith (PFE)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kensmith/2014/11/04/managing-workstation-uptime-with-compliance-settings/</guid>
      <description><![CDATA[Background
I was recently approached by one of my customers who was looking for a way to force...]]></description>
      <content:encoded><![CDATA[<h1></h1>
<h2>Background</h2>
I was recently approached by one of my customers who was looking for a way to force their users to reboot their workstations at least once every 7 days for maintenance reasons.  In the past, I’ve seen this handled via a combination of DCM/Compliance Settings, collections, and package/program deployments.

While this approach works well, a more streamlined approach can be taken by utilizing the remediation capability we get natively in ConfigMgr 2012.

In today’s blog post, we’re going to discuss how to accomplish this without involving collection refresh schedules and persistent package deployments.
<h2>Creating the Configuration Item</h2>
First, we’ll need to create a Configuration Item that will detect the uptime for a workstation and includes a remediation that will initiate a reboot.

On the “Assets and Compliance” tab, we want to create a new configuration item under the “Compliance Settings” folder.  Name the configuration item and make sure the type is set to “Windows”.

<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Create_CI_7C32DD8D.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="Create_CI" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Create_CI_thumb_649B301A.png" alt="Create_CI" width="551" height="484" border="0" /></a>

On the “Supported Platforms” step, it is generally a good idea to limit the scope of your CI to the platforms that will be targeted.  In this case, we don’t want any servers to reboot once a week, so we’ll include only workstation operating systems.

<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Supported_Platforms_5018714D.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="Supported_Platforms" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Supported_Platforms_thumb_2B1AB0D4.png" alt="Supported_Platforms" width="548" height="484" border="0" /></a>

Finally, on the “Compliance Rules” step, we’ll create a new setting.  Our setting type will be a script and the data type returned by the script will be an integer.

<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Create_Setting_339E101E.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="Create_Setting" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Create_Setting_thumb_0A9601D3.png" alt="Create_Setting" width="514" height="484" border="0" /></a>

Our discovery script will need to detect the system uptime and report back whether or not the system has an uptime greater than 7 days.  To accomplish this, we’ll use a simple PowerShell script that reads the last boot time from WMI and calculates the uptime for us.
<pre class="PowerShellColorizedScript"><span style="color: #006400">#Use Get-WMIObject to read the Win32_OperatingSystem class</span>            
<span style="color: #ff4500">$Win32OS</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">Get-WMIObject</span> <span style="color: #000080">-Class</span> <span style="color: #8a2be2">Win32_OperatingSystem</span>            
            
<span style="color: #006400">#Calculate the uptime based on the LastBootUpTime property and the local date and time</span>            
<span style="color: #ff4500">$Uptime</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$Win32OS</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ConvertToDateTime</span><span style="color: #000000">(</span><span style="color: #ff4500">$Win32OS</span><span style="color: #a9a9a9">.</span><span style="color: #000000">LocalDateTime</span><span style="color: #000000">)</span> <span style="color: #a9a9a9">-</span> <span style="color: #000000">`
</span><span style="color: #ff4500">$Win32OS</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ConvertToDateTime</span><span style="color: #000000">(</span><span style="color: #ff4500">$Win32OS</span><span style="color: #a9a9a9">.</span><span style="color: #000000">LastBootUpTime</span><span style="color: #000000">)</span>            
            
<span style="color: #006400">#Check if the total number of days in our uptime calculation is greater than 7</span>            
<span style="color: #006400">#Return a 0 for a non-compliant system and a 1 if the system is compliant</span>            
<span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$Uptime</span><span style="color: #a9a9a9">.</span><span style="color: #000000">TotalDays</span> <span style="color: #a9a9a9">-gt</span> <span style="color: #800080">7</span><span style="color: #000000">)</span><span style="color: #000000">{</span>            
 <span style="color: #ff4500">$compliant</span> <span style="color: #a9a9a9">=</span> <span style="color: #800080">0</span>            
<span style="color: #000000">}</span>            
<span style="color: #00008b">else</span> <span style="color: #000000">{</span>            
 <span style="color: #ff4500">$compliant</span> <span style="color: #a9a9a9">=</span> <span style="color: #800080">1</span>            
<span style="color: #000000">}</span>            
            
<span style="color: #0000ff">echo</span> <span style="color: #ff4500">$compliant</span></pre>
Next, we’ll need to create a remediation script.  This will run when a system is detected as being non-compliant and is the magic that lets us avoid having to deal with collection refresh timers and perpetual package/program deployments.  Instead, we’ll use a PowerShell script that initiates a shutdown with a 60 minute countdown.  To modify the countdown time, just change the value of the “/t 3600” argument. The message displayed on the reboot pop-up can be changed by modifying the text for the “/c” argument.
<pre class="PowerShellColorizedScript"><span style="color: #0000ff">Start-Process</span> <span style="color: #8a2be2">shutdown</span> <span style="color: #000080">-ArgumentList</span> <span style="color: #000000">`
</span><span style="color: #8b0000">'/r /t 3600 /c "It has been more than 7 days since the last system reboot."'</span> <span style="color: #000000">`
</span><span style="color: #000080">-wait</span> <span style="color: #000080">-NoNewWindow</span> <span style="color: #000080">-PassThru</span></pre>
For our compliance rule, we want to create a value rule that checks for our value echoed in our detection script to be equal to 1.  If the workstation has been up for longer than 7 days and the script returns a 0, the compliance will fail and our remediation script will run.  Be sure to check the “Run specified remediation script…” option to ensure that the shutdown command is issued to non-compliant workstations.
<pre class="PowerShellColorizedScript"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Compliance_Rule_5A02841A.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="Compliance_Rule" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Compliance_Rule_thumb_0E36AD61.png" alt="Compliance_Rule" width="471" height="484" border="0" /></a></pre>
Now that we have both our setting and our compliance rules created, we can finish the “Create Configuration Item” wizard.
<h2>Creating the Baseline</h2>
With our Configuration Item created, we next move on to creating a baseline.  Here, we will add the configuration item we just created.

<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Create_Baseline_4BC69BDB.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="Create_Baseline" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Create_Baseline_thumb_54B62E1A.png" alt="Create_Baseline" width="533" height="484" border="0" /></a>
<h2>Deploying the Baseline</h2>
In our final step, we’re going to deploy the baseline that was created to a collection of workstations on which we’d like to enforce our 7 day reboot policy. Be sure to check the “Remediate noncompliant rules when supported” and “Allow remediation outside the maintenance window” (if you have maintenance windows configured for your workstations).  Set the schedule to be frequent enough to catch machines in a reasonable timeframe after hitting 7 days of uptime, but not so aggressive as to affect system performance.  I recommend every 1 day as a happy medium.

<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Deploy_Baseline_76355DA9.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="Deploy_Baseline" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/Deploy_Baseline_thumb_383BCCEB.png" alt="Deploy_Baseline" width="481" height="484" border="0" /></a>]]></content:encoded>
    </item>
    <item>
      <title>Migrating the Content Library between Distribution Points in SCCM 2012 SP1</title>
      <link>https://docs.microsoft.com/archive/blogs/kensmith/migrating-the-content-library-between-distribution-points-in-sccm-2012-sp1</link>
      <pubDate>Thu, 01 Aug 2013 11:04:00 GMT</pubDate>
      <dc:creator><![CDATA[Ken Smith (PFE)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/kensmith/2013/08/01/migrating-the-content-library-between-distribution-points-in-sccm-2012-sp1/</guid>
      <description><![CDATA[I recently had a very good question from one of my customers regarding how to migrate content from...]]></description>
      <content:encoded><![CDATA[I recently had a very good question from one of my customers regarding how to migrate content from one DP to another, avoiding the need to re-distribute content over the WAN.  In the SMS 2003 and SCCM 2007 days, we <a href="https://blogs.technet.com/b/configurationmgr/archive/2009/05/07/configmgr-2007-the-preload-package-tool-preloadpkgonsite-exe-explained.aspx">used the preloadpkgonsite.exe tool</a> to accomplish the job.  With the switch to the content library in SCCM 2012, however, that is no longer an option.  In today’s blog, we’re going to cover how to accomplish this same task with PowerShell.  If you would like to download the script to follow along, you can find it in the <a href="https://gallery.technet.microsoft.com/CloneDP-for-SCCM-2012-SP1-825ce5b1">Technet Gallery</a>.

The process for migrating content from the content library of one DP to another can be broken down into three basic steps:
<ol>
	<li>Create prestage content files for all content on the source distribution point</li>
	<li>Run the ExtractContent.exe tool on the target DP to load the pre-stage content into the content library</li>
	<li>Assign the content for distribution to the target DP</li>
</ol>
The workhorse for step 1 of this task will be the new “<a href="https://technet.microsoft.com/en-us/library/jj821974(v=sc.10).aspx"><strong>Publish-CMPrestageContent</strong></a>” commandlet released with the SP1 update of the SCCM PowerShell module.  This commandlet was not around in the RTM release of SCCM 2012, so you must be on SP1, at a minimum.

Before we get too heavily into the code, a couple of prerequisites should be mentioned.

First, the PowerShell module for Configuration Manager is a 32-bit module, so you will need to make sure you are running the 32-bit version of PowerShell.

Second, the Publish-CMPrestageContent command will actually download the content from the source DP to the computer that is running the PowerShell module.  If you run this command from your workstation that is across the WAN, it will have the unintended consequence of transferring all of our package content across the WAN as well.  To avoid this, you will need to have the SCCM console installed on the DP you will be using as your source DP.

Third, our script uses environment variables to automatically detect where the console is installed.  This allows us to handle cases where it is not installed to the default folder, but requires that the environment variable has been created on the system.  If you have freshly installed the SCCM console, you’ll need to log out and back in to ensure that the environment variable can be read by PowerShell.
<h2><strong>Step 1) – Create prestage content files</strong></h2>
In our example script, we’ll execute the script in prestage mode with the required parameters:
<pre style="margin: 10px;border: 10px solid #012456;color: #ffffff;font-family: monospace;background-color: #012456">PS C:\&gt;.\CloneDP.ps1 -Prestage -SourceDP sccm01.contoso.com -TargetDP 
DP01.contoso.com -ContentShare \\dp01.contoso.com\c$\pkgx</pre>
&nbsp;

In this example, we’re cloning all of the content from the SCCM01 DP to the DP01 DP.  The prestage files will be put in the “Pkgx” folder on DP02 using the admin share, though you can select any network share on the LAN to store the prestage content that we will later import.

Following along in the example script, you can see that before we can begin creating our prestage commands, we need to grab a list of deployment packages that have been deployed to our source DP so that we can begin to loop through them:
<pre class="PowerShellColorizedScript">         
<span style="color: #ff4500">$DeploymentPackages</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">Get-CMDeploymentPackage</span> <span style="color: #000080">-DistributionPointName</span> <span style="color: #ff4500">$SourceDP</span></pre>
One of the key things to note with the Publish-CMPrestageContent commandlet is that there is a different parameter you must specify depending on the type of content you are prestaging.  As a result, we’ll use a variable ($command) and build the command syntax as we go along.  To start, we’ll add the commandlet to the variable:
<pre class="PowerShellColorizedScript"><span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">=</span> <span style="color: #8b0000">"Publish-CMPrestageContent "</span></pre>
We can then use a switch statement to build the parameters required depending on what type of deployment package we are currently working with:
<pre class="PowerShellColorizedScript"><span style="color: #00008b">Switch</span> <span style="color: #000000">(</span><span style="color: #ff4500">$DeploymentPackage</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ObjectTypeID</span><span style="color: #000000">)</span> <span style="color: #000000">{</span>            
        <span style="color: #800080">2</span>  <span style="color: #000000">{</span> <span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-PackageID $($DeploymentPackage.PackageID) "</span> <span style="color: #000000">}</span>
        <span style="color: #800080">14</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-OperatingSystemInstallerId $($DeploymentPackage.PackageID) "</span><span style="color: #000000">}</span>           
        <span style="color: #800080">18</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-OperatingSystemImageId $($DeploymentPackage.PackageID) "</span><span style="color: #000000">}</span>
        <span style="color: #800080">19</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-BootImageId $($DeploymentPackage.PackageID) "</span><span style="color: #000000">}</span>  
        <span style="color: #800080">23</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-DriverPackageID $($DeploymentPackage.PackageID) "</span><span style="color: #000000">}</span>
        <span style="color: #800080">24</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-DeploymentPackageID $($DeploymentPackage.PackageID) "</span><span style="color: #000000">}</span>
        <span style="color: #800080">31</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-ApplicationName '$($DeploymentPackage.Name)' "</span><span style="color: #000000">}</span> 
    <span style="color: #000000">}</span></pre>
All of the parameters for the various content types will use the PackageID to identify what content we are looking to prestage, with the exception of the Application content type.  In this case, the application name is the most easily accessible property gathered by the Get-CMDeploymentPackage commandlet, so we use that instead.  See the table below for a list of ObjectTypeIDs and the content types they refer to:

&nbsp;
<div style="direction: ltr">
<table style="border: 1pt solid #a3a3a3;border-collapse: collapse;direction: ltr" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Name</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">PackageType</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">2</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Driver Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">23</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Task Sequence Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">20</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Software Updates Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">24</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Device Setting Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">21</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Virtual App</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">31</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Application</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">31</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Image Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">18</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Boot Image Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">19</p>
</td>
</tr>
<tr>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 2.256in;vertical-align: top">
<p style="margin: 0in;color: black;font-family: calibri;font-size: 11pt">Operating System Install Package</p>
</td>
<td style="padding: 4pt;border: 1pt solid #a3a3a3;width: 1.058in;vertical-align: top">
<p style="margin: 0in;text-align: right;color: black;font-family: calibri;font-size: 11pt">14</p>
</td>
</tr>
</tbody>
</table>
</div>
&nbsp;

Finally, we can add the parameters that are universal to all of the various content types.  For these parameters, we’ll have the pre-stage file initially created in the %temp% folder and get the content from the source DP passed via the script parameters:
<pre class="PowerShellColorizedScript"><span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-FileName '$($env:TEMP)\$($DeploymentPackage.PackageID).pkgx'” `</span></pre>
<blockquote>
<pre class="PowerShellColorizedScript"><span style="color: #8b0000">+ “ -DistributionPointName $($SourceDP)"</span></pre>
</blockquote>
Now that our command syntax is fully built, we’ll call the command using Invoke-Expression before finally using Move-Item to move the prestage file to a share on our target DP:
<pre class="PowerShellColorizedScript"><span style="color: #0000ff">Invoke-Expression</span> <span style="color: #ff4500">$command</span></pre>
<pre class="PowerShellColorizedScript">           
            
<span style="color: #0000ff">Move-Item</span> <span style="color: #8b0000">"$($env:TEMP)\$($DeploymentPackage.PackageID).pkgx"</span> `</pre>
<blockquote>
<pre class="PowerShellColorizedScript"><span style="color: #8b0000">"$($ContentShare)\$($DeploymentPackage.PackageID).pkgx"</span> <span style="color: #000080">-Force</span>            
</pre>
</blockquote>
At this point, we should have a folder full of prestage content files on our target DP that should look something like the image below.

<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/6278.image7_3D018A96.png"><img title="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/1832.image7_thumb_1AAC85CE.png" alt="image" width="554" height="160" border="0" /></a>
<h2><strong>Step 2) – Extract the prestage files</strong></h2>
For this step we’re going to use the ExtractContent.exe utility that is automatically installed when you install the DP role on a server.  It will be located in the tools folder in the DP install directory, which in our case is <strong>“c:\SMS_DP$\sms\Tools\ExtractContent.exe”</strong>.  If you have UAC enabled, be sure to run your command prompt with administrative credentials.

<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/1778.image_1153514B.png"><img title="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/66/metablogapi/5432.image_thumb_00DAE050.png" alt="image" width="554" height="276" border="0" /></a>

As you can see from the image above, the basic argument we want to give the ExtractContent.exe tool is the /P command to point it at our folder of prestage packages.  A nice feature to note is that we can point this at either an individual “.pkgx” file or an entire folder of them, which in our case will be “c:\Pkgx”.

We’ll run “<strong>ExtractContent.exe /P:c:\Pkgx”</strong> to extract the content out of our “.pkgx” files and into the content library.  The output isn’t very verbose, but you can monitor the “PrestageContent.log” in the log folder of the DP install directory while the command is running.

Once everything is complete and you have reviewed the “PrestageContent.log” file, you can delete the folder containing all of your “.pkgx” files, as they are no longer needed.
<h2><strong>Step 3) – Assign content to your target DP</strong></h2>
If you are using distribution point groups to assign your content rather than selecting individual DP’s, at this point you can add the target DP to the distribution point group.  Otherwise, we’ll use the finalize mode of the sample script to target all of the content that has been prestaged to the target DP. Using either method will utilize the extracted content on the target DP rather than re-distributing the files from the primary site.
<pre style="margin: 10px;border: 10px solid #012456;color: #ffffff;font-family: monospace;background-color: #012456">PS C:\&gt;.\CloneDP.ps1 -Finalize -SourceDP SCCM01.contoso.com 
-TargetDP DP01.contoso.com</pre>
When in finalize mode, we once again use the Get-CMDeploymentPackage to get a listing of packages on the source DP.  We will once again use the $command variable to build our syntax:
<pre class="PowerShellColorizedScript"><span style="color: #8b0000">"Start-CMContentDistribution "</span></pre>
The Start-CMContentDistribution commandlet uses the same parameters to identify the content ID as the Publish-CMPrestageContent commandlet, so we reuse the same switch statement to include those parameters into our command line.

Finally, we complete the $command string with the target DP and then Invoke-Expression to initiate the deployment:
<pre class="PowerShellColorizedScript"><span style="color: #ff4500">$command</span> <span style="color: #a9a9a9">+=</span> <span style="color: #8b0000">"-DistributionPointName $($TargetDP)"</span></pre>
<pre class="PowerShellColorizedScript"><span style="color: #0000ff">Invoke-Expression</span> <span style="color: #ff4500">$command</span></pre>
<pre class="PowerShellColorizedScript"></pre>
<h2><strong>Get the code!</strong></h2>
If you haven’t already done so, you can grab the code for the sample script from the <a href="https://gallery.technet.microsoft.com/CloneDP-for-SCCM-2012-SP1-825ce5b1">TechNet Gallery</a>!]]></content:encoded>
    </item>
  </channel>
</rss>