Generate Hardware Inventory for Simulated Client with 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/.
In this blog: https://blogs.msdn.com/b/minfangl/archive/2012/04/25/step-by-step-on-how-to-create-a-fake-client-using-system-center-2012-configuration-manager-client-sdk.aspx, I have shown how to simulate a client in System Center 2012 Configuration Manager with Client SDK. Now I will give you the code sample to create hardware inventory for the simulated client.
Send a hardware inventory message is pretty much like send an DDR (Data Discovery Record) message. Let’s first revise how we generate the DDR message:
//step 1: new a message type
ConfigMgrDataDiscoveryRecordMessage ddrMessage = new ConfigMgrDataDiscoveryRecordMessage();
//step 2: assign the client info and signing cert
ddrMessage.SmsId = clientId;
MessageCertificateX509Volatile certificate = new MessageCertificateX509Volatile(File.ReadAllBytes("c:\\MixedModeTestCert.pfx"), "sccm" /* sample cert password */)
ddrMessage.AddCertificateToMessage(certificate, CertificatePurposes.Signing);
ddrMessage.Settings.HostName = MPHostname;
//step 3: fill in the ddr message
ddrMessage.ADSiteName = "MyADSite";
ddrMessage.SiteCode = "PE1";
ddrMessage.DomainName = DomainName;
ddrMessage.Discover();
ddrMessage.NetBiosName = ClientName;
// step 4: send the message to the MP (it's asynchronous so there won't be a reply)
HttpSender sender = new HttpSender();
ddrMessage.SendMessage(sender);
To generate hardware inventory message is similar, you’ll also need the four step:
- New a message type
- Assign the client info and signing cert
- Fill in the hardware inventory message
- Send the message to MP.
But for hardware inventory message, you’ll need to fill a lot of information in step 3. So the best practice is to fill in the message with an existing hardware inventory message.
Let’s use the following hardware inventory file:
<?xml version="1.0" encoding="UTF-16"?>
<Report>
<ReportHeader>
<Identification>
<Machine>
<ClientInstalled>1</ClientInstalled>
<ClientType>1</ClientType>
<ClientID>GUID:5F8ACE1E-4DC9-414E-8A82-7EF4C6DBD1B3</ClientID>
<ClientVersion>5.00.7558.0000</ClientVersion>
<NetBIOSName>YWEI2</NetBIOSName>
<CodePage>936</CodePage>
<SystemDefaultLCID>2052</SystemDefaultLCID>
</Machine>
</Identification>
<ReportDetails>
<ReportContent>Inventory\x0020Data</ReportContent>
<ReportType>Full</ReportType>
<Date>20110327235855.000000-420</Date>
<Version>1.0</Version>
<Format>1.1</Format>
</ReportDetails>
<InventoryAction ActionType="Predefined">
<InventoryActionID>{00000000-0000-0000-0000-000000000001}</InventoryActionID>
<Description>Hardware</Description>
<InventoryActionLastUpdateTime>20110228151448.000000+000</InventoryActionLastUpdateTime>
</InventoryAction>
</ReportHeader>
<ReportBody>
<Instance ParentClass="Package" class="Package" Namespace="\\SimulateClient\root\Microsoft\appvirt\client" Content="New">
<Package>
<CachedLaunchSize>3604008</CachedLaunchSize>
<CachedPercentage>100</CachedPercentage>
<CachedSize>44773376</CachedSize>
<LaunchSize>3604008</LaunchSize>
<Name>WnDBG</Name>
<PackageGUID>2F551D7E-2A50-4889-ABC2-D38CA5F73696</PackageGUID>
<TotalSize>44773376</TotalSize>
<Version>4</Version>
<VersionGUID>533C9337-D762-4917-9A37-ACF6DC03F4DF</VersionGUID>
</Package>
</Instance>
</ReportBody>
</Report>
Refer to the below code go generate hardware inventory from this xml sample. You will need to replace the cert file, SMS GUID, etc:
static void SendFullHinv(Guid ClientUniqueId, string MPHostname, string ClientName, string DomainName)
{
//step 1: new a message type
ConfigMgrHardwareInventoryMessage tHINVMessage = new ConfigMgrHardwareInventoryMessage();
//step 2: assign the client info and signing cert
tHINVMessage.SmsId = new SmsClientId(ClientUniqueId);
tHINVMessage.Settings.Security.SigningSmsId = new SmsClientId(ClientUniqueId);
MessageCertificateX509Volatile certificate = new MessageCertificateX509Volatile(File.ReadAllBytes("c:\\MixedModeTestCert.pfx"), "sccm" /* sample cert password */);
tHINVMessage.AddCertificateToMessage(certificate,CertificatePurposes.Signing);
//generate report header
tHINVMessage.Settings.HostName = MPHostname;
tHINVMessage.NetBiosName = ClientName;
tHINVMessage.ReportType = InventoryReportType.Full;
tHINVMessage.DomainName = DomainName;
tHINVMessage.SiteCode = "PE1";
tHINVMessage.SmsId = new SmsClientId(ClientUniqueId);
tHINVMessage.ClientVersion = new ClientVersion("5.00.7711.0000");
//step 3: fill in the hinv message
tHINVMessage.InventoryReport = new InventoryReport();
tHINVMessage.InventoryReport.ReportHeader = new InventoryReportHeader();
tHINVMessage.InventoryReport.ReportHeader.Identification = new InventoryIdentification();
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine = new InventoryIdentificationMachine();
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine.ClientInstalled = true;
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine.ClientType = InventoryClientType.Advanced;
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine.ClientId = new InventoryClientId(new SmsClientId(ClientUniqueId));
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine.ClientVersion = new ClientVersion("5.00.7711.0000");
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine.NetBiosName = ClientName;
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine.CodePage = 437;
tHINVMessage.InventoryReport.ReportHeader.Identification.Machine.LocaleId = 1033;
tHINVMessage.InventoryReport.ReportHeader.Details = new InventoryReportDetails();
tHINVMessage.InventoryReport.ReportHeader.Details.ReportContent = "Inventory\x0020Data";
tHINVMessage.InventoryReport.ReportHeader.Details.ReportType = InventoryReportType.Full;
tHINVMessage.InventoryReport.ReportHeader.Details.ReportTimeString = "20120322145729.366000+000";
tHINVMessage.InventoryReport.ReportHeader.Details.Version = "2.0";
tHINVMessage.InventoryReport.ReportHeader.Details.Format = "1.0";
tHINVMessage.InventoryReport.ReportBody = new InventoryReportBody();
GenerateHinvInstancesFromXml("c:\\Win7A.xml", tHINVMessage);
tHINVMessage.InventoryReport = tHINVMessage.BuildInventoryMessage(tHINVMessage.HardwareInventoryInstances, false);
tHINVMessage.InventoryReport.ReportHeader.Action = new InventoryActionHardwareInventory();
tHINVMessage.InventoryReport.ReportHeader.Action.LastUpdateTime = new DateTime(2012,5,18);
// step 4: send the message to the MP (it's asynchronous so there won't be a reply)
HttpSender sender = new HttpSender();
tHINVMessage.SendMessage(sender);
}
static void GenerateHinvInstancesFromXml(string fullfilepath, ConfigMgrHardwareInventoryMessage tHINVMessage)
{
XmlDocument xdoc = new XmlDocument();
xdoc.Load(fullfilepath);
XmlElement root = xdoc.DocumentElement;
foreach (XmlElement instance in root.GetElementsByTagName("Instance"))
{
InventoryInstanceGeneric inventoryInstance = new InventoryInstanceGeneric();
inventoryInstance.ParentClass = instance.GetAttribute("ParentClass");
inventoryInstance.Class = instance.GetAttribute("Class");
inventoryInstance.Namespace = instance.GetAttribute("Namespace");
inventoryInstance.Content = instance.GetAttribute("Content");
inventoryInstance.RawXml = instance.InnerXml;
tHINVMessage.AddInstanceToInventory(inventoryInstance);
}
}
Note:
- The highlighted parts are necessary and need to happen at the specific order, otherwise you cannot generate the message correctly.
- Check MP log MP_Hinv.log and site server log dataldr.log for any errors.
Comments
Anonymous
July 09, 2012
I had problems using the sample XML until we realized there was a case typo with the Class attribute of the Instance element. class="Package" ...should read... Class="Package"Anonymous
April 27, 2014
MP_HInv reports the following when using this sample HInv Sax: skipping unexpected token at Machine HInv Sax: skipping unexpected token at Machine Any suggestions