﻿<?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>Adam Meltzer's Configuration Manager Blog</title>
    <atom:link
      href="https://review.docs.microsoft.com/archive/blogs/ameltzer/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 04:37:10 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>PowerShell: Automating creation and editing of Task Sequences in 1706 (TP and CB)</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/powershell-automating-creation-and-editing-of-task-sequences-in-1706-tp-and-cb</link>
      <pubDate>Tue, 27 Jun 2017 21:29:42 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/?p=406</guid>
      <description><![CDATA[Our development team has been working hard on implementing a much requested automation scenario for...]]></description>
      <content:encoded><![CDATA[<p>Our development team has been working hard on implementing a much requested automation scenario for PowerShell in Configuration Manager, and that’s being able to create and modify task sequence steps.</p><p>Task sequence editing has three separate pieces: groups of steps, commands (such as “Install Application” and “Partition Disk”), and conditions. With 1706 Current Branch and Technical Preview we now have PowerShell support for creating and removing groups, all conditional statements, and what have been identified as the most commonly used task sequence steps.</p><p>The typical flow is something like this:</p><ol><li>Create your task sequence steps and groups (New-CMTaskSequenceStep<em>Command</em>)</li><li>Create a task sequence (New-CMTaskSequence)</li><li>Add the steps you’ve created to the task sequence ($ts | Add-CMTaskSequenceStep –Step ($step1, $step2, $step3)</li></ol><p>In 1706, the following Step types are supported for Get, New, Remove, and Set operations: </p><ul><li>Run command line (<em>Verb</em>-CMTaskSequenceStepRunCommandLine)</li><li>Install application (<em>Verb</em>-CMTaskSequenceStepInstallApplication)</li><li>Install software (<em>Verb</em>-CMTaskSequenceStepInstallSoftware)</li><li>Install update (<em>Verb</em>-CMTaskSequenceStepInstallUpdate)</li><li>Partition disk (<em>Verb</em>-CMTaskSequenceStepPartitionDisk)</li><li>Reboot (<em>Verb</em>-CMTaskSequenceStepReboot)</li><li>Run PowerShell script (<em>Verb</em>-CMTaskSequenceStepRunPowerShellScript)</li><li>Setup Windows and Configuration Manager (<em>Verb</em>-CMTaskSequenceStepSetupWindowsAndConfigMgr)</li><li>Set variable (<em>Verb</em>-CMTaskSequenceStepSetVariable)</li></ul><p>We plan to add additional Step types in future releases.</p><p>Here’s an example showing how easy it is to create a new custom task sequence that runs two PowerShell scripts:</p><div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ec6627bb-35e6-4be3-b43b-53897f9e2618" style="margin: 0px;padding: 0px;float: none"><pre>
$step1 = New-CMTaskSequenceStepRunPowerShellScript -Name "Run script 1" -PackageID $PackageId -ScriptName "script1.ps1" -ExecutionPolicy Bypass
$step2 = New-CMTaskSequenceStepRunPowerShellScript -Name "Run script 2" -PackageID $PackageId -ScriptName "script2.ps1" -ExecutionPolicy Bypass
$ts = New-CMTaskSequence -Name "Run scripts" -CustomTaskSequence
$ts | Add-CMTaskSequenceStep -Step ($step1, $step2)
</pre>
</div><p>If you’re interested in tracking the ongoing progress of this feature, you can follow the <a href="https://configurationmanager.uservoice.com/forums/300492-ideas/suggestions/8800573-powershell-cmdlets-for-editing-task-sequences">original feedback for this issue on UserVoice</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Configuration Manager Updates and Servicing PowerShell automation coming to 1705 TP</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/configuration-manager-updates-and-servicing-powershell-automation-coming-to-1705-tp</link>
      <pubDate>Wed, 24 May 2017 18:15:19 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/?p=385</guid>
      <description><![CDATA[By popular demand, we have added several new cmdlets in the 1705 TP for automating updates and...]]></description>
      <content:encoded><![CDATA[<p>By popular demand, we have added several new cmdlets in the 1705 TP for automating updates and servicing in Configuration Manager. Moving forward this should greatly simplify automated lab deployments and update scenarios.</p> <p>These cmdlets allow you to do all of the same functionality that you can do in the UI: get updates, download updates, perform a prerequisite check, install updates, and monitor updates installation.</p> <p>In this post, I will walk through a few scenarios and how you can now automate them in PowerShell.</p> <h3></h3> <h1>New cmdlets for updates and servicing automation</h1> <p>The following new cmdlets have been created to automate updates and servicing scenarios:</p> <ul> <li>Enable-CMSiteFeature – Used to enable a pre-release feature. Note that this is a one-way operation so there’s no corresponding Disable-CMSiteFeature cmdlet.  <li>Get-CMSiteFeature – Gets the available features for the site.  <li>Get-CMSiteUpdate – Gets the available updates for the site.  <li>Get-CMSiteUpdateHistory – Gets the update history. This is only for informational purposes.  <li>Get-CMSiteUpdateInstallStatus – Gets the install status for a particular update. This can be used for monitoring.  <li>Install-CMSiteUpdate – Installs an update and allows for optionally skipping prerequisite checking and specifying a pre-release collection.  <li>Invoke-CMSitePromotePreproductionClient – Promotes a pre-production client.  <li>Invoke-CMSiteUpdateCheck – Checks with Microsoft for any updates to Configuration Manager.  <li>Invoke-CMSiteUpdateDownload – Downloads an available update.  <li>Invoke-CMSiteUpdatePrerequisiteCheck – Performs a prerequisite check for an update.</li></ul> <p>In addition to these new cmdlets, Set-CMHierarchySetting has been updated to allow for enabling pre-release features with the <strong>–EnablePrereleaseFeature</strong> parameter. Note that this is a one-way operation and once you enable pre-release features you cannot disable them.</p> <p>We hope you find these new cmdlets useful for automating updates and servicing scenarios. Please report any bugs or issues you find with these new cmdlets on UserVoice or Connect.</p> <h1>Examples</h1> <h2>Download an update and monitor its status</h2> <div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:bc4616bc-2633-4f74-8f6c-b1d0adb5b8b1" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
# Get the update object for the 1704 TP and invoke a download
$update = Get-CMSiteUpdate -Name &quot;Configuration Manager Technical Preview 1704&quot; -Fast
$update | Invoke-CMSiteUpdateDownload

# Now monitor the download status

while($true) {
    cls
   $update | Get-CMSiteUpdateInstallStatus  -Step Download | select orderid, progress, description | ft
    sleep 5
}
</pre>
</div>
<p>This will produce an output like this:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:364115ef-de12-4a9b-a2be-a072fcd0f6d5" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
orderid progress description                                                                                                                                 
------- -------- -----------                                                                                                                                 
      0      100 Processing update package. Check dmpdownloader.log for details.                                                                             
      1        0 If your service connection point is online, the update package cab is downloaded. If your service connection point is offline, this step ...
      2        0 Extracting update package payload. Check dmpdownloader.log for details.                                                                     
      3        0 If redistributable files are required and not included with the update, they are downloaded.  If files do not need to be downloaded, this...
      4        0 The update package has been reported as downloaded. Check dmpdownloader.log and hman.log for details. 
</pre>
</div>
<h2>Perform a prerequisite check and monitor its status</h2>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:6353660a-cb3f-4ba6-b37c-7205503ad593" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
$update = Get-CMSiteUpdate -Name &quot;Configuration Manager Technical Preview 1704&quot; -Fast
$update | Invoke-CMSiteUpdatePrerequisiteCheck

while($true) {
    cls
    $update | Get-CMSiteUpdateInstallStatus -Step Prerequisite | select orderid, progress, description | ft
    sleep 5
}
</pre>
</div>
<p>This will produce an output like this:</p>

<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:9ecb599f-cc17-4933-bc55-930869cf17d0" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
orderid progress description                                                                                                                                 
------- -------- -----------                                                                                                                                 
      0      100 Verifies that the logged on user account has administrative rights on the site system computer.                                             
      0      100 Starting with version 1706, Upgrade Assessment Toolkit is no longer supported. https://go.microsoft.com/fwlink/?linkid=841654               
      1      100 Verifies that the user running Setup has local administrator rights on the central administration site server.                              
      2      100 Checks if the user account running Setup has sysadmin rights on the SQL Server for the CAS.                                                 
      3      100 Check Server Service (LanmanServer) is running.                                                                                             
      4      100 Verifies that the computer specified for installation is a member of a Windows domain.                                                      
      5      100 Verify that the Active Directory domain functional level is Windows Server 2003 or later.                                                   
      6      100 Checks that the site server computer has sufficient available disk space to install the site server.                                        
      7      100 Checks if a system restart is pending.                                                                                                      
      8      100 Checking unsupported Read-Only Domain Controller on site server.                                                                            
      9      100 Checking Site Server FQDN Length.                                                                                                           
     10      100 Verifies that the Microsoft Core XML Services (MSXML) version 6.0 or later libraries are installed.                                         
     11      100 Determines if the Windows Server 2003-based schannel hotfix is installed on the site server.                                                
     12      100 Verifies that the Microsoft Remote Differential Compression (RDC) library is registered on the computer specified for Configuration Manag...
     13      100 Checking Windows Installer Version &gt;= 4.5.                                                                                                  
     14      100 Checks if the target site server computer already has existing Configuration Manager server components installed.                           
     15      100 Checks if the Windows Firewall is disabled or if a relevant Windows Firewall exception exists for SQL Server.                               
     16      100 Checks if the Windows Firewall is disabled or if a relevant Windows Firewall exception exists for SQL Server.                               
     17      100 Check SQL Server service running account.                                                                                                   
     18      100 Check to see if the selected SQL Server instance is already in use by another Configuration Manager site                                    
     19      100 Verifies that the site server&#039;s database collation matches the database collation of its parent site.                                       
     20      100 Verifies that the Microsoft .NET Framework version 3.5 is installed on Configuration Manager central administration site servers, primary...
     21      100 Checks whether the Windows Deployment Tools component of Windows Assessment and Deployment Kit (ADK) for Windows 10 is installed.           
     22      100 Checks whether the User State Migration Tool (USMT) component of Windows Assessment and Deployment Kit (ADK) for Windows 10 is installed.   
     23      100 Checks if the FQDN provided for the site system uses the primary DNS hostname for the computer.                                             
     24      100 Checks if the specified site code is already in use by another site in your hierarchy.                                                      
     25      100 Check the parent Central Administration Site has the same version.                                                                          
     26      100 Verifies that the SQL Server instance and Configuration Manager site database (if present) are configured to use a supported collation.     
     27      100 Verifies that the site server is processing critical inboxes in a timely fashion, and that inboxes do not contain files older than one day. 
     29      100 Verifies that all distribution points in the site have the latest version of software distribution packages.                                
     30      100 Verifies that the SQL Server database collation settings of the tempdb database and site database to be upgraded are the same.              
     31      100 Share Name in Package has invalid character: #.                                                                                             
     32      100 Verifies that SUM is not using any virtual locations for active SUPs.                                                                       
     33      100 Verifies that no active source hierarchy is currently configured for migration.                                                             
     34      100 Verifies that all site servers in the hierarchy meet the Configuration Manager minimum version that is required for upgrade.                
     35      100 No Active MP Replica detected                                                                                                               
     36      100 Verifies that the replication status of the parent site is Replication Active (corresponds to status=125).                                  
     37      100 Checking that the site system role &#039;Out of band service point&#039; is not deployed.                                                             
     38      100 Checking whether the site system role &#039;System Health Validator&#039; exists in the hierarchy.                                                    
     39      100 Checking whether there are software updates that are enabled for NAP                                                                        
     40      100 Pre-requisite rule to verify database consistency                                                                                           
     41      100 Verifies that the user account running Configuration Manager Setup has been granted sysadmin SQL Server role permissions on the SQL Serve...
     42      100 Verifies that the user account running Configuration Manager Setup has been granted sysadmin SQL Server role permissions on the SQL Serve...
     43      100 Verifies that the site server computer account has administrative rights on the SQL Server and management point.                            
     44      100 Verifies that the version of Microsoft SQL Server installed on the computer selected to host the site database meets the minimum requirem...
     45      100 Checking the site SQL Server is not Express Edition.                                                                                        
     46      100 Checking the site SQL Server Tcp is enabled and set to Static port.                                                                         
     47      100 Checks if the SQL Server hosting the Configuration Manager site database is using a case-insensitive collation.                             
     48      100 Check that the specified FQDN for the SQL Server computer is valid.                                                                         
     49      100 Check target SDK machine is not Windows Cluster Node.                                                                                       
     50      100 Checks whether the Windows Preinstallation Environment component of Windows Assessment and Deployment Kit (ADK) for Windows 10 is installed.
     51      100 Checks if SMS Provider machine has same domain as site server.                                                                              
     52      100 Checking whether there are custom Client Agent Settings that enable NAP                                                                     
     53      100 Checking whether the default Client Agent Settings enable NAP                                                                               
     54      100 Checking secondary read state of availability group replicas                                                                                
     55      100 Checking failover state of availability group replicas                                                                                      
     56      100 Checking availability group replicas for instance configuration                                                                             
     57      100 Checks if default value is set for SQL Index Create Memory                                                                                  
     58      100 Starting with version 1702, Configuration Manager does not support SQL Server 2008 R2. https://go.microsoft.com/fwlink/?linkid=841654. Th...
     59      100 Verifies that the site server operating system meets the minimum requirement of Windows Server 2008 R2 for site server installation.        
     61      100 Starting with version 1702, Configuration Manager does not support Windows Server 2008 R2 operating system. https://go.microsoft.com/fwli...
     62      100 Verifies that the site system to be upgraded meets the minimum operating system requirement of Windows Server 2008 R2 for site system ins...
     63      100 Starting with version 1702, Configuration Manager does not support Windows Server 2008 R2 operating system. https://go.microsoft.com/fwli...
     64      100 Starting with version 1702, Configuration Manager does not support Software Update Points on Loadbalancers (NLB/HLB).
</pre>
</div>

<h2>Install an update and monitor its status</h2>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:8a42f4b6-e9cb-4774-8f33-30effa210c9d" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
$update = Get-CMSiteUpdate -Name &quot;Configuration Manager Technical Preview 1704&quot; -Fast
$update | Install-CMSiteUpdate -IgnorePrerequisiteWarning -Force

while($true) {
    cls
    $update | Get-CMSiteUpdateInstallStatus -Step All -Complete | select orderid, progress, description -Last 10 | ft
    sleep 5
}
</pre>
</div>
<p>This uses the –Complete parameter for Get-CMSiteUpdateInstallStatus and only displays the completed steps. This can be useful for monitoring of long running tasks like installation.</p>]]></content:encoded>
    </item>
    <item>
      <title>Configuration Manager Client Messaging SDK is now on NuGet.org</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/configuration-manager-client-messaging-sdk-is-now-on-nuget-org</link>
      <pubDate>Tue, 02 May 2017 19:05:31 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/?p=395</guid>
      <description><![CDATA[The Configuration Manager Client Messaging SDK is now published on NuGet.org. This release also has...]]></description>
      <content:encoded><![CDATA[<p>The Configuration Manager Client Messaging SDK is now published on NuGet.org. This release also has several bug fixes.</p> <p>For more information, see the <a href="https://blogs.technet.microsoft.com/enterprisemobility/2017/04/26/configuration-manager-client-messaging-sdk-available-on-nuget-org/">post on the Enterprise Mobility and Security blog.</a></p>]]></content:encoded>
    </item>
    <item>
      <title>PowerShell: How to add enhanced detection methods to deployment types (1705 TP)</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/powershell-how-to-add-enhanced-detection-methods-to-deployment-types-1704-tp</link>
      <pubDate>Thu, 20 Apr 2017 21:39:42 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/?p=375</guid>
      <description><![CDATA[Update: These cmdlets did not make it into the 1704 TP, but they will be in the 1705 TP. This...]]></description>
      <content:encoded><![CDATA[<p><strong>Update</strong>: These cmdlets did not make it into the 1704 TP, but they will be in the 1705 TP. This posting has been updated to correct this.</p> <p>In the upcoming 1705 technical preview of Configuration Manager, we have finally added the much-requested ability to add enhanced detection method clauses to deployment types PowerShell. This posting will discuss the basic concepts of how this will work, along with what is and is not supported at this time.</p> <h2>What is supported</h2> <p>For 1704 technical preview the following functionality can now be done through PowerShell:</p> <ul> <li>Add and remove file, folder, registry key, registry key value, and MSI version detection clauses to MSI and script deployment types.  <li>Add and remove bundle and package detection clauses to Mac deployment types. </li></ul> <h2>What is not supported</h2> <p>These features are planned to be added in a future release:</p> <ul> <li>Modify detection clauses in place  <li>Group/ungroup detection clauses </li></ul> <h2>How it works</h2> <p>A detection clause object is created with one of the new New-CMDetectionClause&lt;type&gt; cmdlets, and then added to a new or existing deployment type using the -AddDetectionClause parameter. One or more detection clauses can be added at a time.</p> <div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0866ce7b-ab83-41f7-8c73-45f2be458ad2" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><!-- ABOVE ONLY ADDED FOR WLW2010 PREVIEW PURPOSES AND NOT POSTED TO BLOG--></div> <h3>Example</h3> <p>Two detection clauses are created, one for an existing installer matching a specific value, and another for a directory to exist on the C drive. These clauses are then added to a new deployment type.</p> <div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:a90a1fc2-1c2c-4df7-a819-a902ef72ea38" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
$clause1 = New-CMDetectionClauseWindowsInstaller -ProductCode $guid [Value -ExpressionOperator IsEquals -ExpectedValue &quot;1.1.1.1&quot; # Do a version check
$clause2 = New-CMDetectionClauseDirectory -DirectoryName &quot;mymsi&quot; -Path &quot;C:\&quot; -Existence # c:\mymsi should exist
$app | Add-CMMsiDeploymentType -ContentLocation &quot;\\myserver\mypath\mymsi.msi&quot; -Force -AddDetectionClause ($clause1, $clause2)
</pre>
</div>
<h2>What cmdlets are included</h2>
<p>These cmdlets have been created in 1704 to enable DCM rule and setting support:</p>
<ul>
<li>New-CMDetectionClauseDirectory (MSI, Script) 
<li>New-CMDetectionClauseFile (MSI, Script) 
<li>New-CMDetectionClauseMacBundle (Mac) 
<li>New-CMDetectionClauseMacPackage (Mac) 
<li>New-CMDetectionClauseRegistryKey (MSI, Script) 
<li>New-CMDetectionClauseRegistryKeyValue (MSI, Script) 
<li>New-CMDetectionClauseWindowsInstaller (MSI, Script) </li></ul>
<p>Note: Add/Set-CMMsiDeploymentType, Add/Set-CMScriptDeploymentType, and Add/Set-CMMacDeploymentType now have new -AddDetectionClause and -RemoveDetectionClauseparameters to facilitate adding and removing enhanced detection methods.</p>]]></content:encoded>
    </item>
    <item>
      <title>PowerShell: How to add compliance settings and rules to configuration items (1705 TP)</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/powershell-how-to-add-compliance-settings-and-rules-to-configuration-items-1704-tp</link>
      <pubDate>Thu, 20 Apr 2017 21:38:42 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/?p=365</guid>
      <description><![CDATA[Update: These cmdlets did not make it into the 1704 TP, but they will be in the 1705 TP. This...]]></description>
      <content:encoded><![CDATA[<p><strong>Update</strong>: These cmdlets did not make it into the 1704 TP, but they will be in the 1705 TP. This posting has been updated to correct this.</p> <p>In the upcoming 1705 technical preview of Configuration Manager, we have finally added the much-requested ability to add Settings and Rules to Configuration Items from within PowerShell. This posting will discuss the basic concepts of how this will work, along with what is and is not supported at this time.</p> <h2>What is supported</h2> <p>For 1704 technical preview the following functionality can now be done through PowerShell:</p> <ul> <li>Add/Remove/Modify Settings to Configuration Items. All Settings supported in the administrator console are supported through PowerShell: registry key, registry key value, script, file, folder, WQL query, AD query, assembly property, IIS metabase, SQL query, and XPath query.  <li>Add/Remove/Modify Rules linked to Settings within Configuration Items. This includes basic value checks, existential checks (exist, not exist, occurrence), and complex value checks for applicable Setting types (file/folder properties, assembly properties, registry key permissions). </li></ul> <h2>How it works</h2> <p>All Settings can be created without corresponding Rules in a single cmdlet call. All settings with existential Rules can also be created with a single cmdlet call. Some settings with value Rules can be created with a single cmdlet call while other, more complex Rule types will require a more complicated but easily understandable pattern of cmdlet calls. We may simplify this in the future. (See Example 4 below.)</p> <h3>Example 1</h3> <p>Creating a registry key value Setting without any Rules:</p> <div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:3297b63f-9829-44cd-ac8f-094afcfb62d0" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
# Creates a setting looking for HKLM\Software\Microsoft\Windows NT\CurrentVersion:ReleaseId
$ci | Add-CMComplianceSettingRegistryKeyValue -SettingName &quot;ReleaseId no rule&quot; -DataType String -Hive LocalMachine -KeyName &quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion&quot; -ValueName &quot;ReleaseId&quot; -NoRule
</pre>
</div>
<h3>Example 2</h3>
<p>Creating a registry key value Setting with an existential Rule (must exist):</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:8e133e71-7c44-4a2e-8042-ef0b547ebd18" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
# Creates a setting requiring the HKLM\Software\Microsoft\WindowsNT\CurrentVersion:ReleaseId registry key to exist
$ci | Add-CMComplianceSettingRegistryKeyValue -SettingName &quot;ReleaseId must exist&quot; -DataType String -Hive LocalMachine -KeyName &quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion&quot; -ValueName &quot;ReleaseId&quot; -ExistentialRule -Existence MustExist
</pre>
</div>
<h3>Example 3</h3>
<p>Creating a registry key value Setting with a value Rule (must equal “1703”):</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:848f9061-04cb-4d4e-bd3f-1016ae5eeaee" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
# Creates a setting requiring the HKLM\Software\Microsoft\WindowsNT\CurrentVersion:ReleaseId registry key to be equal to &quot;1703&quot;
$ci | Add-CMComplianceSettingRegistryKeyValue -SettingName &quot;ReleaseId must be 1703&quot; -DataType String -Hive LocalMachine -KeyName &quot;SOFTWARE\Microsoft\Windows NT\CurrentVersion&quot; -ValueName &quot;ReleaseId&quot; -ValueRule -ExpressionOperator IsEqual -ExpectedValue &quot;1703&quot;
</pre>
</div>
<p>In value rules, critical parameters are “ExpressionOperator” and “ExpectedValue”. It’s worth noting that “ExpectedValue” supports arrays of values so if you’re using an ExpressionOperator that requires (Between) or supports many (OneOf/NoneOf/AllOf) values, you can use the same parameter for this. Cmdlets will validate the input to ensure you’re not doing something unsupported – such as using IsEquals with multiple ExpectedValue arguments.</p>
<h3>Example 4</h3>
<p>Some setting value Rules require more specialized input. As such, these Setting types do not support a single cmdlet at this time. For those scenarios, you need to follow this pattern:</p>
<ol>
<li>Create the Setting using Add-CMComplianceSetting&lt;type&gt; 
<li>Get the DcmObjectModel Setting object (as opposed to a SMS Provider object) using Get-CMComplianceSetting 
<li>Create the Rule using New-CMComplianceRule&lt;type&gt; 
<li>Apply the Rule to the setting using Add-CMComplianceSettingRule </li></ol>
<p>This example creates a file rule that requires the specified file to have a specific attribute:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0866ce7b-ab83-41f7-8c73-45f2be458ad2" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
$ci | Add-CMComplianceSettingFile -Path &quot;C:\&quot; -FileName &quot;hiberfile.sys&quot; -NoRule -SettingName &quot;hiberfile.sys must have system attribute&quot;
$setting = $ci | Get-CMComplianceSetting -SettingName &quot;hiberfile.sys must have system attribute&quot; # Get the SDK setting object
$rule = $setting | New-CMComplianceRuleFileFolderAttribute -RuleName &quot;hiberfile.sys must be system&quot; -System $true # Create the rule
$ci | Add-CMComplianceSettingRule $rule # Bind the rule to the CI
</pre>
</div>
<h2>What cmdlets are included</h2>
<p>These cmdlets have been created in 1704 to enable Configuration Item Rule and Setting support:</p>
<ul>
<li>Add/Set-CMComplianceSettingActiveDirectory 
<li>Add/Set-CMComplianceSettingAssembly 
<li>Add/Set-CMComplianceSettingDirectory 
<li>Add/Set-CMComplainceSettingFile 
<li>Add/Set-CMComplianceSettingIisMetabase 
<li>Add/Set-CMComplianceSettingRegistryKey 
<li>Add/Set-CMComplianceSettingRegistryKeyValue 
<li>Add-CMComplianceSettingRule 
<li>Add/Set-CMComplianceSettingScript 
<li>Add/Set-CMComplianceSettingSqlQuery 
<li>Add/Set-CMComplianceSettingWqlQuery 
<li>Add/Set-CMComplianceSettingXPathQuery 
<li>Get-CMComplianceRule 
<li>Get-CMComplianceSetting 
<li>New-CMComplianceRuleAssembly 
<li>New-CMComplianceRuleExistential 
<li>New-CMComplianceRuleFileFolderAttribute 
<li>New-CMComplianceRuleFileFolderDate 
<li>New-CMComplianceRuleFileFolderPermission 
<li>New-CMComplianceRuleFileFolderSimple 
<li>New-CMComplianceRuleFileFolderSize 
<li>New-CMComplianceRuleRegistryKeyPermission 
<li>New-CMComplianceRuleValue 
<li>New-CMComplianceRuleVersion 
<li>Remove-CMComplianceRule 
<li>Remove-CMComplianceSetting </li></ul>
<p>Note: The previously existing Add-CMComplianceRegistrySetting and New-CMComplianceRule cmdlets were experimental and for lab use only. They have been removed from 1704.</p>]]></content:encoded>
    </item>
    <item>
      <title>SDK: Creating DDRs on the site server using the client messaging SDK part 2: creating System DDRs</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/sdk-creating-ddrs-on-the-site-server-using-the-client-messaging-sdk-part-2-creating-system-ddrs</link>
      <pubDate>Thu, 02 Oct 2014 10:42:32 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/2014/10/02/sdk-creating-ddrs-on-the-site-server-using-the-client-messaging-sdk-part-2-creating-system-ddrs/</guid>
      <description><![CDATA[Last year I posted about functionality in the Configuration Manager client messaging SDK to generate...]]></description>
      <content:encoded><![CDATA[<p>Last year I posted about functionality in the Configuration Manager client messaging SDK to generate DDRs and provided samples on how to create a DDR for a completely custom agent type: a printer. It's also a common scenario on wanting to generate DDRs to add additional discovery information for regular client systems. It's very similar to do this but with a couple of subtle differences that I will cover here. The main difference is that you need to use an architecture of 'System' (case sensitive) and you need to be careful to make sure your 'Name' matches what's in the database exactly or else you may end up renaming the record and causing confusion.</p>
<p>Here's a simple PowerShell script that demonstrates this:</p>
<pre class="scroll"><code class="cplusplus"># This must be set to match the path to the Configuration Manager 2012 SDK<br /> $modulePath = 'D:\Program Files (x86)\Microsoft System Center 2012 R2 Configuration Manager SDK\Redistributables\Microsoft.ConfigurationManagement.Messaging.dll'<br /> <br /> # Set this to match your machine name<br /> $name = 'R2311195'<br /> <br /> # This must be a name of your special DDR generator<br /> $agentName = 'MySpecialThirdPartyAgent'<br /> <br /> # This should match your site code<br /> $siteCode = 'R2S'<br /> <br /> # Now we generate the DDR object<br /> $ddr = New-Object -typename Microsoft.ConfigurationManagement.Messaging.Messages.Server.DiscoveryDataRecordFile -ArgumentList $agentName<br /> $ddr.SiteCode = $siteCode<br /> $ddr.Architecture = 'System'<br /> $ddr.AddStringProperty('Name', [Microsoft.ConfigurationManagement.Messaging.Messages.Server.DdmDiscoveryFlags]::Key -bor [Microsoft.ConfigurationManagement.Messaging.Messages.Server.DdmDiscoveryFlags]::Name, 32, $name)<br /> $ddr.AddStringProperty('Netbios Name', [Microsoft.ConfigurationManagement.Messaging.Messages.Server.DdmDiscoveryFlags]::Name, 16, $name)<br /> $ddr.AddIntegerProperty('TestInstallAuto', [Microsoft.ConfigurationManagement.Messaging.Messages.Server.DdmDiscoveryFlags]::None, 0)<br /> $ddr.AddIntegerProperty('TestInstall', [Microsoft.ConfigurationManagement.Messaging.Messages.Server.DdmDiscoveryFlags]::None, 1)<br /> $ddr.AddStringProperty('Wow', [Microsoft.ConfigurationManagement.Messaging.Messages.Server.DdmDiscoveryFlags]::None, 32, "Such custom")<br /> $ddr.SerializeToInbox()</code></pre>
<p>This creates a new DDR and adds it into the inbox. After a few seconds,&nbsp;DDM will process this and those changes should be reflected in the discovery data for the machine:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/0815.disco.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/0815.disco.png" alt="" border="0" /></a>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Using signed PowerShell scripts with configuration items and applications</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/using-signed-powershell-scripts-with-configuration-items-and-applications</link>
      <pubDate>Wed, 24 Sep 2014 11:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/2014/09/24/using-signed-powershell-scripts-with-configuration-items-and-applications/</guid>
      <description><![CDATA[Edit: The deployment type detection method issue will be resolved in 1706 Current Branch. It will...]]></description>
      <content:encoded><![CDATA[<p><strong>Edit:</strong> The deployment type detection method issue will be resolved in 1706 Current Branch. It will also be available for testing in 1705 Technical Preview.</p> <p>In the past if you wanted to use a signed PowerShell script as a configuration item detection method or deployment type detection method, you would see an error on the client when it tried to process the script. Configuration Manager 2012 R2 CU2 has a fix in place to mitigate this problem and allow for using signed PowerShell scripts in configuration items and detection methods. You can download CU2 from here: <a title="https://support.microsoft.com/kb/2970177" href="https://support.microsoft.com/kb/2970177">https://support.microsoft.com/kb/2970177</a>. Note that the signer of the script must be pre-trusted or else the script will continue to fail.</p> <p>For this new functionality to work both the administrator console and client needs to be updated to R2 CU2 as this fix requires changes to both pieces of the product.</p> <p>First let's talk about configuration item detection methods. To add a signed PowerShell script, when editing a discovery or remediation script you must use "Open" to add the signed script. You cannot copy and paste it. There's a UI change in that the script becomes read only in the admin console until you "Clear" it or change the data type. This is by design. Once the configuration item gets down to the client it should process the signed PowerShell script without any issues.</p> <p>Things are more complicated with deployment type detection methods. At this time there is no UI code to allow for signed PowerShell scripts but fortunately the client-side fix to allow for signed PowerShell scripts applies both to applications and configuration items. You can use the PowerShell script attached to this blog posting to add a signed PowerShell script to a deployment type in a way the client will be able to properly process. The way it works is you edit the top few lines in the script to match your environment's site code and provider host name. Please also read the information in the header of the script carefully. Notably it will overwrite any previous script in your deployment type. If you edit the script in the admin console after adding it using this script, the script will fail on the client. There's examples in the header of the PowerShell script showing how to use it.</p> <p>Feel free to let me know if you have any further questions!</p> <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/56/02/78/updatescriptdt.ps1">updatescriptdt.ps1</a></p>]]></content:encoded>
    </item>
    <item>
      <title>SDK: Creating custom inventory classes for clients with the client messaging SDK</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/sdk-creating-custom-inventory-classes-for-clients-with-the-client-messaging-sdk</link>
      <pubDate>Wed, 10 Apr 2013 14:26:00 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/2013/04/10/sdk-creating-custom-inventory-classes-for-clients-with-the-client-messaging-sdk/</guid>
      <description><![CDATA[Out of the box, the client messaging SDK contains several basic hardware inventory classes for...]]></description>
      <content:encoded><![CDATA[<p>Out of the box, the client messaging SDK contains several basic hardware inventory classes for sending inventory data such as CCM_System, Win32_NetworkAdapter, and some others. It has the ability to create inventory data on the fly from pre-formatted XML using InventoryInstanceGeneric. It also has some wrapper functionality to convert existing data in WMI to pre-formatted inventory classes through Microsoft.ConfigurationManagement.Messaging.Messages.WmiClassToInventoryReportInstance. If there’s interest I can go more into this in a future.</p> <p>If you want to use the object model to create your own custom inventory classes for collection, it’s pretty simple to do this. A prerequisite for making the most of this is knowledge about how XML Serialization in the .NET framework works as this process is heavily dependent on this internally. If you don’t know much about this it should still be pretty easy to get started; things just become more difficult when you’re trying to expose more advanced data sets.</p> <p>For basic details on how to send a hardware inventory message, check out my post with an <a href="https://blogs.msdn.com/b/ameltzer/archive/2012/07/12/sdk-in-depth-sample-on-how-to-use-the-client-messaging-sdk.aspx">in-depth sample on how to use the messaging SDK</a>.</p> <p>Here’s an example inventory class that I created by extending the SDK for a Contoso Perpetual Energy Reactor attachment:</p> <div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:9fac0b11-6ba4-4751-85a2-cc6a752b17ef" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
/// &lt;summary&gt;
/// This class represents an inventory instance of a Contoso Perpetual Motion Reactor attachment
/// &lt;/summary&gt;
[XmlRoot(&quot;Contoso_PerpetualMotionReactor&quot;)] // Must define an XmlRoot that represents the class name
public sealed class InventoryElementRecordPerpetualMotionReactor : InventoryInstanceElement
{
    private readonly Collection&lt;string&gt; attachments = new Collection&lt;string&gt;();
 
    /// &lt;summary&gt;
    /// Reactor model
    /// &lt;/summary&gt;
    [XmlElement]
    public string Model { get; set; }
 
    /// &lt;summary&gt;
    /// Version
    /// &lt;/summary&gt;
    [XmlElement]
    public uint Version { get; set; }
 
    /// &lt;summary&gt;
    /// Attachments for the energy reactor
    /// &lt;/summary&gt;
    [XmlElement]
    public Collection&lt;string&gt; Attachments
    {
        get { return attachments; }
    }
 
    /// &lt;summary&gt;
    /// Discover an inventory instance element based local configuration
    /// &lt;/summary&gt;
    /// &lt;remarks&gt;This is optional and only here for documentation purposes. By default, DiscoverSelf() will simply throw a NotImplementedException unless
    /// you override it with your own discovery logic&lt;/remarks&gt;
    protected override void DiscoverSelf()
    {
        base.DiscoverSelf();
    }
 
    /// &lt;summary&gt;
    /// Initializes a new instance of the &lt;see cref=&quot;InventoryElementRecordPerpetualMotionReactor&quot;/&gt; class.
    /// &lt;/summary&gt;
    public InventoryElementRecordPerpetualMotionReactor()
        : base(
            &quot;Contoso_PerpetualMotionReactor&quot;, // associated base class
            &quot;Contoso_PerpetualMotionReactor&quot;, // associated parent class
            @&quot;root\Contoso&quot; /* namespace (scope) */)
    {
    }
}
</pre>
</div>
<p>Keep in mind the XmlRoot and XmlElement attributes. These are used to format the class to XML before sending it to the management point. Here’s an example of how this class will look when serialized to XML (reformatted for clarity):</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:d6b598df-4f48-48d3-9f92-7bbcbd387b5c" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
&lt;Contoso_PerpetualMotionReactor&gt;
    &lt;Model&gt;Contoso Perpetual Motion Reactor (Nuclear Powered)&lt;/Model&gt;
    &lt;Version&gt;1&lt;/Version&gt;
    &lt;Attachments&gt;Dirty Water Cooling Tower&lt;/Attachments&gt;
    &lt;Attachments&gt;Unobtanium Heat Sink&lt;/Attachments&gt;
    &lt;Attachments&gt;Analogue gauges&lt;/Attachments&gt;
    &lt;Attachments&gt;Sport suspension package&lt;/Attachments&gt;
&lt;/Contoso_PerpetualMotionReactor&gt;
</pre>
</div>
<p>This will be embedded into the inventory report that’s sent to the management point. Here’s some sample code that could bring all these things together to send this:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f07adb4d-dee7-446d-b63b-b3ecb0bba6ce" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
ConfigMgrHardwareInventoryMessage customHinvMessage = new ConfigMgrHardwareInventoryMessage();
customHinvMessage.Settings.HostName = mpHostname;
customHinvMessage.AddCertificateToMessage(certificate, CertificatePurposes.Signing | CertificatePurposes.Encryption);
customHinvMessage.SmsId = clientId;
customHinvMessage.SiteCode = siteCode;
customHinvMessage.NetBiosName = &quot;MyDummyHostName&quot;;
customHinvMessage.DomainName = &quot;MyDomain.net&quot;;
 
InventoryElementRecordPerpetualMotionReactor reactor = new InventoryElementRecordPerpetualMotionReactor();
reactor.Model = &quot;Contoso Perpetual Motion Reactor (Nuclear Powered)&quot;;
reactor.Version = 1;
reactor.Attachments.Add(&quot;Dirty Water Cooling Tower&quot;);
reactor.Attachments.Add(&quot;Unobtanium Heat Sink&quot;);
reactor.Attachments.Add(&quot;Analogue gauges&quot;);
reactor.Attachments.Add(&quot;Sport suspension package&quot;);
 
// Create an instance containing the element
InventoryInstance instance = new InventoryInstance(reactor);
 
// Now add the instance to the inventory list
customHinvMessage.AddInstanceToInventory(instance);
 
customHinvMessage.SendMessage(Sender);
</pre>
</div>
<p>Now when you do this, if you look at MP_Hinv.log on the management point you’ll notice something will be wrong. The MP’s hardware inventory processor will complain about this class with a log line that looks something like this:</p>
<blockquote>
<p>Hinv: class name not found in the mapping table: Contoso_PerpetualMotionReactor&nbsp;&nbsp;&nbsp; MP_HinvEndpoint&nbsp;&nbsp;&nbsp; 4/10/2013 1:44:38 PM&nbsp;&nbsp;&nbsp; 4592 (0x11F0)</p></blockquote>
<p>The reason for this is you can’t just start creating new hardware inventory classes without taking some action on the site server. First you’ll need to create a .MOF file that represents the custom class you’re creating. Here’s one I created that represents the code above:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:5c21b508-2ab7-4508-ada3-463759cefacd" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px"><pre>
//=============================================================================
// SMS_Class_Template must be the parent of every class
//=============================================================================
class SMS_Class_Template
{
};
 
[ SMS_Report (TRUE),
  SMS_Group_Name (&quot;Perpetual Motion Reactor&quot;),
  SMS_Class_ID (&quot;CONTOSO|PERPETUAL_MOTION_REACTOR|1.0&quot;),
  Namespace (&quot;\\\\\\\\.\\\\root\\\\contoso&quot;) ]
class Contoso_PerpetualMotionReactor : SMS_Class_Template
{
    [SMS_Report(TRUE), key]
    String Model;
 
    [SMS_Report(TRUE)]
    UInt32 Version;
 
    [SMS_Report(TRUE)]
    String Attachments[];
};
</pre>
</div>
<p>The next step is to import this MOF file into Configuration Manager. To do this, you need to go to the Administration view in the admin console, go to Client Settings, choose your client settings group, then go to Hardware Inventor, choose Set Classes, and import your mof file:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/4848.image_244AD52C.png"><img title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/8640.image_thumb_717ACEB7.png" width="324" height="353"></a></p>
<p>When you send this inventory a second time, it will get processed successfully by the management point with a line like this in the MP_Hinv.log:</p>
<blockquote>
<p>Hinv Sax: Inserting class instance Contoso_PerpetualMotionReactor, attr=New&nbsp;&nbsp;&nbsp; MP_HinvEndpoint&nbsp;&nbsp;&nbsp; 4/10/2013 2:04:54 PM&nbsp;&nbsp;&nbsp; 4592 (0x11F0)</p></blockquote>
<p>Now if you open Resource Explorer for your system, you’ll see this new data represented for your client:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/3872.image_515FC1FA.png"><img title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/7266.image_thumb_3144B53D.png" width="877" height="316">&nbsp;</a></p>]]></content:encoded>
    </item>
    <item>
      <title>SDK: Using the client messaging SDK to leverage client notification services in ConfigMgr 2012 SP1</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/sdk-using-the-client-messaging-sdk-to-leverage-client-notification-services-in-configmgr-2012-sp1</link>
      <pubDate>Mon, 11 Mar 2013 16:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/2013/03/11/sdk-using-the-client-messaging-sdk-to-leverage-client-notification-services-in-configmgr-2012-sp1/</guid>
      <description><![CDATA[Configuration Manager 2012 SP1 added a new feature called &ldquo;client notification...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small">Configuration Manager 2012 SP1 added a new feature called &ldquo;client notification services&rdquo;. Normally clients send a request to the MP on an interval, but if you&rsquo;re in a situation where you need clients to perform certain actions right away such as perform an anti-virus scan to detect a 0 day malware or request policy right away we now have a persistent network connection to the management point to facilitate this.</span></p>
<p><span style="font-size: small">You can now also take advantage of this functionality with the SP1 release of the client messaging SDK (note: this will only work with a Configuration Manager 2012 SP1 or newer management point). As this is a completely new paradigm for messaging, it doesn&rsquo;t work like traditional request/response functions of the client messaging SDK.</span></p>
<p><span style="font-size: small">To use this facility, you essentially create a client notification session with the management point, and then you subscribe to events that will fire when instructions come from the management point. You respond to those messages asynchronously and then send a &ldquo;response&rdquo; message over the channel saying you handled the request.</span></p>
<p><span style="font-size: small">In order to use the client notification feature you must have an existing SMSID and certificate. See my <a href="https://blogs.msdn.com/b/ameltzer/archive/2012/07/12/sdk-in-depth-sample-on-how-to-use-the-client-messaging-sdk.aspx">past posts</a> on the client messaging SDK for details on how to get this.</span></p>
<p><span style="font-size: small">Here&rsquo;s some sample code on how to set up the session:</span></p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px;padding: 4px;border: 1px solid silver;width: 97.5%;text-align: left;line-height: 12pt;overflow: auto;font-family: 'Courier New', courier, monospace;font-size: 8pt;cursor: text;direction: ltr;max-height: 200px;background-color: #f4f4f4">
<div id="codeSnippet" style="padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">ConfigMgrBgbSession session = ConfigMgrBgbSession.CreateSession(</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">    BgbSessionType.Http, </pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">    <span style="color: #006080">"10.229.77.180"</span> <span style="color: #008000">/* hostname or IP of your management point */</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">    MessageSecurityMode.MixedMode, </pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">    smsId <span style="color: #008000">/* SMSID from client registration */</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">    <span style="color: #0000ff">new</span> ClientVersionV5SP1(), </pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">    cert <span style="color: #008000">/* MessageCertificateX509 derived object */</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">session.BgbMessageReceived += session_BgbMessageReceived; <span style="color: #008000">/* Event that handles messages received from the client notification web service */</span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">session.BgbMessageSent += session_BgbMessageSent; <span style="color: #008000">/* Event that handles messages sent to the client notification web service */</span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">session.KeepAliveInterval = TimeSpan.FromMinutes(15); <span style="color: #008000">/* Interval to send "pings" back up to the client notification web service */</span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">session.OpenSession();</pre>
<!--CRLF--></div>
</div>
<p>&nbsp;<span style="font-size: small">Remember, this is asynchronous so once OpenSession() is called your code will continue. You will handle requests from the client notification web service with the BgbMessageReceived event handler. Here&rsquo;s a sample implementation:</span></p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px;padding: 4px;border: 1px solid silver;width: 97.5%;text-align: left;line-height: 12pt;overflow: auto;font-family: 'Courier New', courier, monospace;font-size: 8pt;cursor: text;direction: ltr;max-height: 200px;background-color: #f4f4f4">
<div id="codeSnippet" style="padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white"><span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> session_BgbMessageReceived(<span style="color: #0000ff">object</span> sender, ConfigMgrBgbSessionEventArgs e)</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">{</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">    Console.WriteLine(<span style="color: #006080">"Received message from client notification of type {0}: {1}"</span>, ((ConfigMgrBgbMessageReply)e.Message).Message, e.Message.Body.Payload);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">    ConfigMgrBgbSynchronousMessageEventArgs configMgrBgbSynchronousMessageEventArgs = e <span style="color: #0000ff">as</span> ConfigMgrBgbSynchronousMessageEventArgs;</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">    <span style="color: #0000ff">if</span> (configMgrBgbSynchronousMessageEventArgs != <span style="color: #0000ff">null</span>)</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">    {</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">        <span style="color: #008000">// Insert code here to act against the notification </span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">        configMgrBgbSynchronousMessageEventArgs.ResponseMessage.ReturnCode = 1; <span style="color: #008000">/* this says that you were successful */</span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">        configMgrBgbSynchronousMessageEventArgs.SessionCallback.SendResponseMessage(configMgrBgbSynchronousMessageEventArgs.ResponseMessage);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">    }</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">}</pre>
<!--CRLF--></div>
</div>
<p><span style="font-size: small">You process the notification request from the client notification web service, then you send a response back saying that you were successful. What follows is sample of this code in action.</span></p>
<p><span style="font-size: small">In the administrator console, I instruct a client notification for &ldquo;Download Computer Policy&rdquo; to be sent to my client (other options may also be available depending on how your site or hierarchy is configured):</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/4744.image_3DCFF371.png"><img title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/0844.image_thumb_649E09B1.png" alt="image" width="810" height="360" border="0" /></a></p>
<p>&nbsp;<span style="font-size: small">You can track the status of your clients through the &ldquo;Client Operations&rdquo; node of the &ldquo;Monitoring&rdquo; page of the admin console. Here we can see the status of this request:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/7701.image_59747F67.png"><span style="font-size: x-small"><img title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/8372.image_thumb_2467F037.png" alt="image" width="830" height="514" border="0" /></span></a></p>
<p><span style="font-size: small">This is not real-time so you will need to re-summarize the page if you want results immediately.</span></p>
<p><span style="font-size: small">Using the sample code in a program, here&rsquo;s what it might look like receiving a message and sending a response:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/8880.image_044CE37A.png"><img title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/1018.image_thumb_7923592F.png" alt="image" width="618" height="206" border="0" /></a></p>
<p><span style="font-size: small">If you resummarize the monitoring page, you&rsquo;ll see that it reflects that the client handled the message:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/8865.image_2B1AF9BA.png"><span style="font-size: x-small"><img title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/8877.image_thumb_38ED3FB5.png" alt="image" width="842" height="353" border="0" /></span></a></p>
<p><span style="font-size: small">You&rsquo;ll notice in the XML blob sent to the code that TaskType was set to 1. This is an instruction to request machine policy. There&rsquo;s 2 other TaskType values: full anti-virus scan (2), and quick anti-virus scan (3).</span></p>
<p><span style="font-size: small">When you&rsquo;re done, you should use CloseSession() to cleanly terminate your session with the client notification web service.</span></p>
<p><span style="font-size: small">By implementing this, your custom client will have all of the instant-response capabilities of a regular client!</span></p>
<p><span style="font-size: small">Bonus trivia: why is the nomenclature &ldquo;BGB&rdquo; used throughout these SDK APIs? The feature was originally known internally as &ldquo;big green button&rdquo;, or &ldquo;BGB&rdquo; for short. The name &ldquo;big green button&rdquo; was to evoke the image of a panicked admin hitting the emergency button to tell all of the clients to do something right away. As for why it was a green button rather than a red button is something that has unfortunately been lost to antiquity. There&rsquo;s still many references to this in log files and even in filenames before settling on the official name of &ldquo;client notification&rdquo;, and the SDK was one of those things that was not changed to reflect the official naming of the feature. <a href="https://blogs.msdn.com/b/oldnewthing/archive/2003/08/27/54712.aspx">It wouldn&rsquo;t be the first time this has happened.</a></span></p>]]></content:encoded>
    </item>
    <item>
      <title>SDK: Creating DDRs on the site server using the client messaging SDK</title>
      <link>https://review.docs.microsoft.com/archive/blogs/ameltzer/sdk-creating-ddrs-on-the-site-server-using-the-client-messaging-sdk</link>
      <pubDate>Mon, 11 Mar 2013 15:48:00 GMT</pubDate>
      <dc:creator><![CDATA[Adam Meltzer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ameltzer/2013/03/11/sdk-creating-ddrs-on-the-site-server-using-the-client-messaging-sdk/</guid>
      <description><![CDATA[Despite its name, the client messaging SDK also has some strictly server side functionality. In its...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small">Despite its name, the client messaging SDK also has some strictly server side functionality. In its original release with the ConfigMgr 2012 SDK, it could write state messages and status messages directly to the inboxes on the site server. In the SP1 SDK, you can now write DDR messages directly to the site inboxes. This is equivalent to the functionality provided by the old <a href="https://msdn.microsoft.com/en-us/library/jj127398.aspx">SmsResGenCtl.dll</a> COM library, but is a fully managed solution that doesn&rsquo;t require any COM registrations or extra libraries.</span></p>
<p><span style="font-size: small">The old library provided the ability to formulate a completely ad-hoc DDR which could be used to extend resource discovery by being able to add resources into Configuration Manager for objects and their properties that aren&rsquo;t natively supported. For example, you could inventory your fax machines, printers, chairs (someone actually asked for this once!), and so on.</span></p>
<p><span style="font-size: small">The class of interest for generating this inventory data is Microsoft.ConfigurationManagement.Messaging.Messages.Server.DiscoveryDataRecordFile.</span></p>
<p><span style="font-size: small">Here is a code sample on how you may inventory a printer using this API:</span></p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px;padding: 4px;border: 1px solid silver;width: 97.5%;text-align: left;line-height: 12pt;overflow: auto;font-family: 'Courier New', courier, monospace;font-size: 8pt;cursor: text;direction: ltr;max-height: 200px;background-color: #f4f4f4">
<div id="codeSnippet" style="padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">DiscoveryDataRecordFile ddrFile = <span style="color: #0000ff">new</span> DiscoveryDataRecordFile(<span style="color: #006080">"Contoso Printersaurus"</span>); <span style="color: #008000">// Agent name is the program that generated the DDR</span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">ddrFile.Architecture = <span style="color: #006080">"Printer"</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">ddrFile.SiteCode = <span style="color: #006080">"NP1"</span>;</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">ddrFile.AddStringProperty(<span style="color: #006080">"Name"</span>, DdmDiscoveryFlags.Key | DdmDiscoveryFlags.Name, 32, <span style="color: #006080">"MyPrinter001"</span>); <span style="color: #008000">// You must have a field defined with Name flag</span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">ddrFile.AddStringProperty(<span style="color: #006080">"Model"</span>, DdmDiscoveryFlags.None, 128, <span style="color: #006080">"Contoso PaperMax 2000"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">ddrFile.AddStringProperty(<span style="color: #006080">"Version"</span>, DdmDiscoveryFlags.None, 12, <span style="color: #006080">"1.0"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">ddrFile.AddStringProperty(<span style="color: #006080">"Location"</span>, DdmDiscoveryFlags.None, 128, <span style="color: #006080">"Third Floor near break room"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">ddrFile.AddDateTimeProperty(<span style="color: #006080">"DateInstalled"</span>, DdmDiscoveryFlags.None, <span style="color: #0000ff">new</span> DateTime(2011, 07, 07));</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">ddrFile.AddStringPropertyArray(<span style="color: #006080">"Capabilities"</span>, DdmDiscoveryFlags.Array, 32, <span style="color: #006080">"Color"</span>, <span style="color: #006080">"Duplex"</span>, <span style="color: #006080">"Scanner"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">ddrFile.AddIntegerProperty(<span style="color: #006080">"RAM"</span>, DdmDiscoveryFlags.None, 64);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">ddrFile.AddIntegerProperty(<span style="color: #006080">"PagesPrinted"</span>, DdmDiscoveryFlags.None, 102);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">ddrFile.AddDateTimeProperty(<span style="color: #006080">"LastPrinted"</span>, DdmDiscoveryFlags.None, DateTime.Now);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white">ddrFile.AddIntegerPropertyArray(<span style="color: #006080">"PaperLevelPercent"</span>, DdmDiscoveryFlags.Array, 100, 75, 0, 0);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">ddrFile.AddStringPropertyArray(<span style="color: #006080">"PaperType"</span>, DdmDiscoveryFlags.Array, 32, <span style="color: #006080">"Letter"</span>, <span style="color: #006080">"Letter Extended"</span>, <span style="color: #006080">"Legal"</span>, <span style="color: #006080">"A3"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: white"><span style="color: #0000ff">string</span> filename = ddrFile.SerializeToFile(<span style="color: #006080">"."</span>); <span style="color: #008000">// Normally you would use SerializeToInbox</span></pre>
<!--CRLF-->
<pre style="margin: 0em;padding: 0px;width: 100%;text-align: left;color: black;line-height: 12pt;overflow: visible;font-family: 'Courier New', courier, monospace;font-size: 8pt;direction: ltr;background-color: #f4f4f4">Console.WriteLine(<span style="color: #006080">"Write DDR to file: {0}"</span>, filename);</pre>
<!--CRLF--></div>
</div>
<p><span style="font-size: small">Pretty simple, right? Basically you define your properties, flags if needed, a maximum length where applicable, and then values. The Architecture field is very important as it will create SMS_R_<em>Architecture</em> resource tables that can be used for collections and query rules. In this sample because the architecture is &ldquo;Printer&rdquo;, a SMS_R_Printer class will be created.</span></p>
<p><span style="font-size: small">The sample here used SerializeToFile to write a file for testing purposes and you&rsquo;d drop this file into your ddm.box inbox on your site server. A better way to do this is to use the SerializeToInbox method that will automatically drop the file into the appropriate inbox.</span></p>
<p><span style="font-size: small">Running this program and dropping the .DDR file into ddm.box will create an inventory record (which can be verified via ddm.log).</span></p>
<p><span style="font-size: small">You can then create a Query (not a Collection since this isn&rsquo;t a System or User resource) against all instances of SMS_R_Printer. I created one that looks like this:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/7331.printer_40E9674B.png"><img title="printer" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/1563.printer_thumb_20CE5A8E.png" alt="printer" width="544" height="460" border="0" /></a></p>
<p><span style="font-size: small">You can then run this query, and see this resource in the admin console:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/4682.image_15A4D044.png"><img title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/67/metablogapi/0572.image_thumb_479C70CE.png" alt="image" width="966" height="128" border="0" /></a></p>
<p><span style="font-size: small">Since this data is all stored in SQL and accessible through the provider you can write reports or use other tools to slice and dice this data in interesting ways.</span></p>
<p><span style="font-size: small">I hope you find this functionality useful!</span></p>]]></content:encoded>
    </item>
  </channel>
</rss>