Skip to main content

PowerShell + SCCM 2012 R2 : Extending Discovery; Create Custom DDRs


While working on the previous post on exploring Discovery methods with PowerShell I came across this awesome post on creating custom DDRs with PowerShell in ConfigMgr07.


The above post explains how to create custom DDRs using ConfigMgr SDK for ConfigMgr 07.

So I got tempted to immediately try it out in my ConfigMgr12 environment and found out that there exists another cool way shown by Adam Meltzer (using C#) in his blog to create DDRs in ConfigMgr12. So in this post will try to cover :
  • Create DDRs using COM Interface (DLL used : smsrgenctl.dll)
  • Create DDRs using the new DiscoveryDataRecordFile Object Interface (DLL used: Microsoft.ConfigurationManagement.Messaging.dll)
Note : Both the above DLLs are part of ConfigMgr 2012 SDK.

Create DDRs using COM Interface (DLL used : smsrgenctl.dll)

Tried loading the smsrgenctl.dll from PowerShell using Add-Type , System.Reflection.Assembly's LoadFrom Method which is supposed to load the dependencies.



Finally used the resgvr32.exe to load and it did work but it would show sometime that it was success but won't show up the ProgID in my registry


After the DLL is loaded is pretty Straight Forward to follow the post mentioned earlier. Below is the Code which I used it has comments explaining what each line does:
#region Create DDRs using the COM Interface
#load the DLL
& regsvr32.exe 'C:\Program Files (x86)\Microsoft System Center 2012 R2 Configuration Manager SDK\Redistributables\amd64\smsrsgenctl.dll'
$Computer = "DextestMachine1"
#explicitly cast this as a String Array if single element present
[string[]]$IPAddress = "10.1.1.100"
[String[]]$MACAddress = "00:02:A7:B2:23:88"
#create the COM Object
$SMSDisc = New-Object -ComObject SMSResGen.SMSResGen.1
#Specify the Architecture, Name for the DDR and the SiteCode
$SMSDisc.DDRNew("System","myCustomAgent","DEX")
#Add the String Property Netbios Name - (Propertyname,Value,Width,DiscoveryFlag specifying that it is Key[Hex Value])
$SMSDisc.DDRAddString("Netbios Name", $Computer, 64, 0x8)
#Add the String Array Property IP addresses - (Propertyname,Value,Width,DiscoveryFlag specifying it is an Array)
$SMSDisc.DDRAddStringArray("IP Addresses", $IPAddress, 64, 0x10)
$SMSDisc.DDRAddStringArray("MAC Addresses", $MACAddress, 64, 0x10)
#save the DDR to the Desktop
#NOte that the
$SMSDisc.DDRWrite([System.Environment]::GetFolderPath("Desktop") + "\$Computer.DDR")
#now copy this DDR file to your SCCM Server DDM.Box inbox
Copy-Item -path "C:\Users\Administrator\Desktop\DextestMachine1.DDR" -Destination "\\dexsccm\C$\Program Files\Microsoft Configuration Manager\inboxes\ddm.box" -Verbose
#NOTE - Don't get tempted to use the DDRSendToSMS Method on the above COM object it's deprecated now ;)
#endregion Create DDRs using the COM Interface


After this you will see the entry reflect in ConfigMgr Console:




Create DDRs using the new DiscoveryDataRecordFile Object Interface (DLL used : Microsoft.ConfigurationManagement.Messaging.dll )

If you look in the "Redistributables" folder for ConfigMgr 12 SDK there is a dll named 'Microsoft.ConfigurationManagement.Messaging.dll'. Following the post by Adam (which is in C#) I was able to do it in PowerShell. Below is the what the documentation says about the class DiscoverDataRecordFile which will be used:



Note that this supersedes the old COM Method we used to create the DDRs.


This one is actually easy. See the code below (comments explaining each step):

#region Create DDRs Using DiscoveryDataRecordFile Class
#this DLL loads up using Add-Type
Add-Type -Path 'C:\Program Files (x86)\Microsoft System Center 2012 R2 Configuration Manager SDK\Redistributables\Microsoft.ConfigurationManagement.Messaging.dll'
#initialize a new instance of the Object
$DDRFile = New-Object -TypeName Microsoft.ConfigurationManagement.Messaging.Messages.Server.DiscoveryDataRecordFile("TestingDDR")
#By default the Architecture is System which refers to the SMS_R_system Class
#add the Key Property (Netbios Name is the Key Property for the System Architecture)
#AddStringProperty Method Defintion says - Property name, DiscoveryFlags, Width, Value
#You can see the enumeration for the DiscoveryFlags by using : [System.Enum]::GetValues("Microsoft.ConfigurationManagement.Messaging.Messages.Server.DdmDiscoveryFlags")
$DDRFile.AddStringProperty("Netbios Name",'key',64,'DexFakeMachine1')
#add the AD Site Name String Property....have a look at the Method Definitions (use this in your Console For Ex: $DDRFile | Get-Member )
$DDRFile.AddStringProperty("AD Site Name",'None',64,'Dexters LAB')
#Add Array Properties
$DDRFile.AddStringPropertyArray("IP Addresses",'Array',64,[string[]]'10.1.1.99') #Typecast as a string array if one value
$DDRFile.AddStringPropertyArray("MAC Addresses",'Array',64,"00:02:A5:B1:11:68","00:02:A5:B1:11:69")
#After populating the Properties just use the Method SerializeToInbox to send it to the SCCM server for Processing
$DDRFile.SerializeToInbox('DexSCCM.dexter.com') #SCCM Server name is passed if you are not working on it
#endregion Create DDRs Using DataSicoveryRecordFile Class


Now the proof:



So this is how you can extend discovery using PowerShell.....I find this one very cool. Now I can populate a lot of device entries in my SCCM environment for testing.

I happen to be one of the speakers at the First PowerShell Saturday Event in India [Bangalore] (March 8th, 2014) and would be speaking on my ConfigMgr + PowerShell Experiments. If you are around and interested then do drop by.
You can register for PowerShell Saturday Event here (limited seats) --> 
http://pssatindia.eventbrite.com



UPDATE:: There is a cmdlet in the CM2012 R2 PowerShell Module which does this job of creating DDRs for you Import-CMComputerInformation, came to knew about this while reading this post HERE 

Popular posts from this blog

Azure DevOps Tips & Tricks - Find private REST APIs

Original source -  Azure DevOps Tip - Find private APIs Often working with Azure DevOps, I hit a wall trying to automate some tasks but there are no REST API's made public yet. It was one of those task of automating creation of Environments in multi-stage YAML based pipelines in AzDO. Quick research reveals that this has been requested in uservoice  (please upvote). Let's see one of the very simple ways to discover some of these APIs.

Azure + GoLang SDK : Authenticating Part-2

The auth package lives at "github.com/Azure/go-autorest/autorest/azure/auth" In the above package, at the moment I have explored below two functions (my notes): NewAuthorizerFromFile method NewAuthorizerFromEnvironment method (this post)  This function definition looks like below :

Test connectivity via a specific network interface

Recently while working on a Private cloud implementation, I came across a scenario where I needed to test connectivity of a node to the AD/DNS via multiple network adapters.  Many of us would know that having multiple network routes is usually done to take care of redundancy. So that if a network adapter goes down, one can use the other network interface to reach out to the node. In order to make it easy for everyone to follow along, below is an analogy for the above scenario: My laptop has multiple network adapters (say Wi-Fi and Ethernet) connected to the same network. Now how do I test connectivity to a Server on the network only over say Wi-Fi network adapter?