Step by Step on how to simulate a client using System Center 2012 Configuration Manager Client SDK

My colleague Adam has a better series of samples of the Client SDK. You can check these blogs here: https://blogs.msdn.com/b/ameltzer/archive/tags/sdk/.

 

System Center 2012 Configuration Manager SDK RC is now available at: https://www.microsoft.com/download/en/details.aspx?displaylang=en&id=29559

One of the most exciting features of this SDK is the introduction of Configuration Manager Client SDK: Microsoft.ConfigurationManager.Messaging.dll.

“The Configuration Manager Client SDK is an object model and transport for communicating with Configuration Manager site server roles such as the management point for client operations such as registering clients, retrieving policy assignments and bodies, sending inventory, and state/status messages.”

So with it you’re now able to simulate a client to talk with you site servers, send inventory data and state/status messages on behalf of this simulated client. You can leverage it to do performance testing against your hierarchy, fulfill your DB with real client data and showcase the reports to your customers or investigate/troubleshoot the progress of how Configuration Manager site server roles process the messages.

 In this article, I will show you the step by step on how to simulate a client based on the Sample.cs in the SDK.

 Step 1: Create a certificate

Launch a command line window with administrative right and run the following command to create a self-signed certificate:

makecert -len 2048 -sky exchange -a sha1 -sy 24 -pe -r -n CN=”SCCM Test Certificate" -ss “Test Key Store” -sr LocalMachine

Now run certmgr.msc to open the Certificates Manager mmc:

Find the certificate you just created, right click All Tasks -> Export to export it. At the first page, check box “Yes, export the private key”. Go through the rest of the wizard, use all the default settings and save the pfx file to a location. Do remember the password and you’ll need it later.

 

Step 2: Create a project (The full sample code is at the end of this article)

1.       Add reference to Microsoft.ConfigurationManager.Messaging.dll (After install the SDK, it’s located in <installation folder>\Redistributables) and use them

using Microsoft.ConfigurationManagement.Messaging.Framework;

using Microsoft.ConfigurationManagement.Messaging.Messages;

using Microsoft.ConfigurationManagement.Messaging.Messages.Server;

using Microsoft.ConfigurationManagement.Messaging.Messages.StatusMessages;

using Microsoft.ConfigurationManagement.Messaging.Sender.Http;

 

2.       Add a trace listener to view the log created by Microsoft.ConfigurationManager.Messaging.dll

System.IO.FileStream myTraceLog = new System.IO.FileStream("C:\\myTraceLog.txt", System.IO.FileMode.OpenOrCreate);

// Creates the new trace listener.

System.Diagnostics.TextWriterTraceListener myListener = new System.Diagnostics.TextWriterTraceListener(myTraceLog);

Trace.Listeners.Add(myListener);

 

3.       Add App.config configuration file and edit it to set the trace level.

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.diagnostics>

   <switches>

     <add name="Messaging Logging" value="Verbose" />

   </switches>

   <trace autoflush="true" indentsize="3" />

  </system.diagnostics>

</configuration>

 

4.       Create a certificate with the pfx file you created at Step 1.

MessageCertificateX509Volatile certificate = new MessageCertificateX509Volatile(File.ReadAllBytes("c:\\MixedModeTestCert.pfx"), "sccm" /* sample cert password */)

*Here, you can use MessageCertificateX509File to bind to a certificate that is already in the certificate store instead of exporting the certificate with private key.

 

5.       Create a ConfigMgrRegistrationRequest instance and set attributes.

ConfigMgrRegistrationRequest registrationRequest = new ConfigMgrRegistrationRequest();

// Add our certificate for message signing

registrationRequest.AddCertificateToMessage(certificate, CertificatePurposes.Signing);

// Set the destination hostname

registrationRequest.Settings.HostName = MPHostname;

 

registrationRequest.ClientFqdn = ClientName + "." + DomainName;

registrationRequest.NetBiosName = ClientName;

registrationRequest.AgentIdentity = “MySampleApp”;

 

6.       Call RegisterClient function and get SmsClientId.

SmsClientId clientId = registrationRequest.RegisterClient(sender, TimeSpan.FromMinutes(5));

 

7.       After registration finishes, Create a ConfigMgrDataDiscoveryRecordMessage instance and send a DDR message.

ConfigMgrDataDiscoveryRecordMessage ddrMessage = new ConfigMgrDataDiscoveryRecordMessage();

 

// Add necessary discovery data

ddrMessage.SmsId = clientId;

ddrMessage.ADSiteName = "MyADSite";

ddrMessage.SiteCode = "PE1";

ddrMessage.DomainName = DomainName;

 

// Add our certificate for message signing

ddrMessage.AddCertificateToMessage(certificate, CertificatePurposes.Signing);

ddrMessage.Settings.HostName = MPHostname;

 

// Now send the message to the MP (it's asynchronous so there won't be a reply)

ddrMessage.SendMessage(sender);

 

Step 3. Check the result.

1.       After RegisterClient call,

Check MP_CliReg.log:

SMS MP Registration Manager started. MP_ClientRegistration 4/25/2012 1:15:52 AM 3240 (0x0CA8)

 

Check MP_RegistrationManager.log:

Processing Registration request from Client 'test1.cmv58315dom.net' MP_RegistrationManager 4/25/2012 1:15:52 AM 3240 (0x0CA8)

Begin validation of Certificate [Thumbprint D6255A71DA4447E569AAF0FD9581BB54EFDC8624] issued to 'SCCM Test Certificate' MP_RegistrationManager 4/25/2012 1:15:52 AM 3240 (0x0CA8)

Completed validation of Certificate [Thumbprint D6255A71DA4447E569AAF0FD9581BB54EFDC8624] issued to 'SCCM Test Certificate' MP_RegistrationManager 4/25/2012 1:15:52 AM 3240 (0x0CA8)

MP Reg: DDR written to [C:\sms\inboxes\auth\ddm.box\regreq\UQZ00TIW.RDR] for Client [GUID:E10E9679-9F8D-477B-825C-A5F220952B27] with Certificate Thumbprint [D6255A71DA4447E569AAF0FD9581BB54EFDC8624] MP_RegistrationManager 4/25/2012 1:15:52 AM 3240 (0x0CA8)

MP Reg: Processing completed. Completion state = 0 MP_RegistrationManager 4/25/2012 1:15:52 AM 3240 (0x0CA8)

 

2.       After ddrMessage.SendMessage call;

Check MP_Ddr.log:

Mp Message Handler: copying attachment to C:\sms\inboxes\auth\ddm.box\DdrAttachmentPC6MDZ65.xml MP_DdrEndpoint 4/25/2012 1:49:01 AM 5064 (0x13C8)

Inv-Ddr Task: processing xml file "C:\sms\inboxes\auth\ddm.box\DdrAttachmentPC6MDZ65.xml" MP_DdrEndpoint 4/25/2012 1:49:01 AM 5064 (0x13C8)

Full report from client test1, action description = Discovery MP_DdrEndpoint 4/25/2012 1:49:01 AM 5064 (0x13C8)

Ddr Task: Translate report attachment to file "C:\sms\inboxes\auth\ddm.box\TGWYD9X7.DDR" returned 0 MP_DdrEndpoint 4/25/2012 1:49:01 AM 5064 (0x13C8)

 

Now open the Configuration Manager Console, you should be able to see this client.

 

Notes & Tips:

1.       If you use the same certificate to register the second time with a different name, it will still be regarded as the same machine and update that record. The certificate is always a unique identifier for the client (unless you’re using an ISV proxy client certificate)

2.       You can save the SmsClientId returned by the RegisterClient() function. So later, you can send messages on name of this simulating client. If you lose it, you can always re-register to get it with the same certificate.

3.       The DDR message is a little tricky. It will get the inventory information on the machine you run this program. You can call .Discover() method to discover everything locally from standard WMI.

If you are interested in the client SDK and are searching for more code samples, please do let me know what scenario you are looking for.

 

Source Code:

using System;

using System.Text;

using System.IO;

using Microsoft.ConfigurationManagement.Messaging.Framework;

using Microsoft.ConfigurationManagement.Messaging.Messages;

using Microsoft.ConfigurationManagement.Messaging.Messages.Server;

using Microsoft.ConfigurationManagement.Messaging.Messages.StatusMessages;

using Microsoft.ConfigurationManagement.Messaging.Sender.Http;

using System.Diagnostics;

 

 

namespace SimulateClient

{

    class Program

    {

        static void Main(string[] args)

        {

          

            // Creates the text file that the trace listener will write to.

            System.IO.FileStream myTraceLog = new System.IO.FileStream("C:\\myTraceLog.txt", System.IO.FileMode.OpenOrCreate);

            // Creates the new trace listener.

            System.Diagnostics.TextWriterTraceListener myListener = new System.Diagnostics.TextWriterTraceListener(myTraceLog);

            Trace.Listeners.Add(myListener);

 

            string DomainName = "cmv58315dom.net";

            string MPHostname = "cmv58317.cmv58315dom.net";

            string ClientName = "test2";

 

            SimulateClient(MPHostname, ClientName, DomainName);

 

        }

 

        static void SimulateClient (string MPHostname, string ClientName, string DomainName)

        {

            HttpSender sender = new HttpSender();

 

            // Load the certificate for client authentication

            using (MessageCertificateX509Volatile certificate = new MessageCertificateX509Volatile(File.ReadAllBytes("c:\\MixedModeTestCert.pfx"), "sccm" /* sample cert password */))

            {

                // Create a registration request

                ConfigMgrRegistrationRequest registrationRequest = new ConfigMgrRegistrationRequest();

 

                // Add our certificate for message signing

                registrationRequest.AddCertificateToMessage(certificate, CertificatePurposes.Signing);

 

                // Set the destination hostname

                registrationRequest.Settings.HostName = MPHostname;

 

                // Discover local properties for registration metadata

                registrationRequest.Discover();

 

                registrationRequest.ClientFqdn = ClientName + "." + DomainName;

                registrationRequest.NetBiosName = ClientName;

                registrationRequest.AgentIdentity = "MySampleApp";

 

                // Register client and wait for a confirmation with the SMSID

                SmsClientId clientId = registrationRequest.RegisterClient(sender, TimeSpan.FromMinutes(5));

 

                // Send data to the site

                ConfigMgrDataDiscoveryRecordMessage ddrMessage = new ConfigMgrDataDiscoveryRecordMessage();

 

                // Add necessary discovery data

                ddrMessage.SmsId = clientId;

                ddrMessage.ADSiteName = "MyADSite";

                ddrMessage.SiteCode = "PE1";

                ddrMessage.DomainName = DomainName;

 

                // Now create inventory records from the discovered data (optional)

                ddrMessage.Discover();

 

                // Add our certificate for message signing

                ddrMessage.AddCertificateToMessage(certificate, CertificatePurposes.Signing);

                ddrMessage.Settings.HostName = MPHostname;

 

                // Now send the message to the MP (it's asynchronous so there won't be a reply)

                ddrMessage.SendMessage(sender);

 

            }

        }

    }

}