sccm: custom data discovery records (DDRs) using powershell
for anyone who has been creating custom DDRs, this is old hat. for me, I just wanted to prove that it could be done in powershell. apparently no one has tried -- or at least web searching has led me to believe it. :)
$Computer = "MarcusRocks"
$IPAddress = "192.168.0.25","192.168.0.39"
$MACAddress = "00:02:A5:B1:11:68","00:02:A5:B1:11:69"$SMSDisc = New-Object -ComObject SMSResGen.SMSResGen.1
$SMSDisc.DDRNew("System","myCustomAgent","XYZ")
$SMSDisc.DDRAddString("Netbios Name", $Computer, 64, 0x8)
$SMSDisc.DDRAddStringArray("IP Addresses", $IPAddress, 64, 0x10)
$SMSDisc.DDRAddStringArray("MAC Addresses", $MACAddress, 64, 0x10)$SMSDisc.DDRWrite([System.Environment]::GetFolderPath("Desktop") + "\$Computer.DDR")
in sccm 2007, the command to send the DDR to the site server was removed in the sccm sdk redistributable dlls. this isn't a tragedy. it simply means you have to copy the DDR to the <site server>\sms_xyz\inboxes\ddm.box folder yourself. I didn't include that bit in the script since this is just for fun. anyway, once the DDR is processed, this is what you would see:
go discover the world -- or at least your macs and linux machines? :) and you know what I'm thinking? yeah, that's right. get this into opalis. that'll be my next post.
other useful information I learned
$SMSDisc = New-Object -ComObject SMSResGen.SMSResGen.1
to start off on this adventure, I began navigating the sample script provided for creating a DDR [1]. the first thing I did was try to execute the command above. it just spit out this stuff:
New-Object : Cannot load COM type SMSResGen.SMSResGen.1.
At line:1 char:22
+ $smsdisc = New-Object <<<< -ComObject SMSResGen.SMSResGen.1
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotLoadComObjectType,Microsoft.PowerShell.Commands.NewObjectCommand
it took me longer than I will ever admit that I did not have the necessary sccm sdk. after installing it, I tried again and got the same result. it took me longer than the part I will never admit that I had to register the dll. so to reiterate -- download the sdk, then register the dll. after installing the sdk, register smsrsgenctl.dll. it's in this path: <Program Files>\Microsoft System Center Configuration Manager 2007 SDK\Redistributables.
the second hurdle is how do you know which com object to use during the creation of the new object? well, other than the fact that they spell it out for you in the sample script --
Set newDDR=CreateObject("SMSResGen.SMSResGen.1")
-- there really is nothing that stands out. powershell provides some conventions on getting this stuff out, but in actuality, it's nothing more than sifting through the registered classes in the registry. I found something on from tobias weltner [2] that made this way easy. it's a real gem you may want to hang on to:
gci registry::hkey_classes_root\clsid -include progid -recurse | % { $_.getvalue("") } | ? { $_ -like "*SMS*" }
executing this command brings back a set of results like the following...
RsmSink.Notify.1
SMSCliUI.VAppEvents.1
Microsoft.SMS.RCServer.1
Microsoft.SMS.RCLauncher.1
SMSResGen.SMSResGen.1
GPMGMT.GPMStatusMsgCollection.1
SMSCliUI.SoftwareUpdatesEvents.1
Microsoft.SMS.RCAgent.1
Microsoft.SMS.Client.1
ISMSnapin.Snapin.1
SMSCliUI.UIEvents.1
SMSAppPub.1
Microsoft.SMS.DCMSDK.1
SMSCliUI.UIEvents2.1
Microsoft.SMS.Event.1
and there we find the com object we were looking for. now honestly, I'd have been goofing around for awhile trying to figure out which in the list matched. it was helpful though for knowing that I had the dll registered properly!
moving on, now that you have the object, you can bring out the methods.
TypeName: System.__ComObject#{ecb65d0e-b16b-4817-92b0-bf2d9cefb3ac}
Name MemberType Definition
---- ---------- ----------
DDRAddInteger Method void DDRAddInteger (string, int, DDRPropertyFlagsEnum)
DDRAddIntegerArray Method void DDRAddIntegerArray (string, Variant, DDRPropertyFlagsEnum)
DDRAddString Method void DDRAddString (string, string, int, DDRPropertyFlagsEnum)
DDRAddStringArray Method void DDRAddStringArray (string, Variant, int, DDRPropertyFlagsEnum)
DDRNew Method void DDRNew (string, string, string)
DDRSendToSMS Method void DDRSendToSMS ()
DDRWrite Method void DDRWrite (string)
references
[1] http://msdn.microsoft.com/en-us/library/cc142988.aspx
[2] http://powershell.com/cs/blogs/ebook/archive/2009/03/08/chapter-6-using-objects.aspx
Isn't there a method of handling this through the ConfigMgr provider rather than using COM objects?
ReplyDeleteif you can find it, let me know. interested.
ReplyDeleteMarcus, you are a star!!
ReplyDeleteI might beat you however to putting this into Opalis as this is what I was looking for this information for and will be doing it later tonight or tomorrow morning ;)
I'll blog it once done!
looking forward to seeing your work, stevy. thanks for the comment!
ReplyDeleteUsing Orchestrator 2012 RTM
ReplyDeleteI am first trying the code exactly how it is above and i get an error (afterall at this time it is only creating a DDR file on the runbook server, so values are not important at this time)
From a failed test Error Summary Text: Unexpected token 'IPAddress' in expression or statement
you're going to have to give me a little more to go on. i presume the com object is accessible?
Deletehey michael, i just ran into this as well. looks like what you're doing wrong is setting the variable name as $var instead of just var in the published data tab. hope that helps...
DeleteI was unable to create an SMSResGen object in PS x64, make sure you open powershell in x86 mode if you want to use this dll!
ReplyDeletegood observation, matt! i think it's important to note that for orchestrator, you'll have to make sure it launches on x86 as well.
Delete