Skip to main content

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:

image

 

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)

 

as you can see, you now have methods available that are described in the sdk!  awesome.

 

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

Comments

  1. Isn't there a method of handling this through the ConfigMgr provider rather than using COM objects?

    ReplyDelete
  2. if you can find it, let me know. interested.

    ReplyDelete
  3. Marcus, you are a star!!

    I 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!

    ReplyDelete
  4. looking forward to seeing your work, stevy. thanks for the comment!

    ReplyDelete
  5. Using Orchestrator 2012 RTM
    I 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

    ReplyDelete
    Replies
    1. you're going to have to give me a little more to go on. i presume the com object is accessible?

      Delete
    2. hey 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...

      Delete
  6. I 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!

    ReplyDelete
    Replies
    1. good 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

Post a Comment

Popular posts from this blog

how to retrieve your ip address with powershell...

update: this is how it’s performed in powershell v3 as demonstrated here.(get-netadapter | get-netipaddress | ? addressfamily -eq'IPv4').ipaddress update: this is by far the easiest.PS C:\temp> (gwmi Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -ne $null }).ipaddress
192.168.1.101
are you laughing yet?  i know you probably find this topic amusing.  it's really interesting though.  whenever you get over it, i'll do this in the standard cmd.exe interpreter and then in powershell to show you what kind of coolness powershell does.done?  okay, good.  this is an interpretation of a demo that bob wells did at our smug meeting.  hope you like it.i should tell you, it's not as simple as the title would lead you to believe.  i like doing that little slight-of-hand thing since it gives the impression that i'm painting a very easy target on my back for your criticism (though it's probably true in other ways)!  the idea is that we want to retrieve just the ip ad…

understanding the “ad op master is inconsistent” alert

i use the term “understanding” loosely.  this is by far no definitive guide on this particular alert, just a few things i have picked up in my attempt to understand it.let’s look at the context of the alert:The Domain Controller's Op Master is inconsitent. See additional alerts for details.
first of all, it gives very little information.  the only particularly useful detail is that it indicates which server is having the issue.  other than that, just a spelling error as there are no additional critical alerts to look at for details.this rule, as you know, comes from a sealed mp.  therefore, we can’t modify anything in it except the overrides.  the couple i’ve tinkered with are:interval (sec) log success event to begin with, interval (sec) is just set way too high.  the default is 60 seconds.  why on earth would anyone want to know that your op master consistency may be off, every minute?  actually, i could think of a few reasons, but really, it’s overkill.  the way the script works…

sccm: content hash fails to match

back in 2008, I wrote up a little thing about how distribution manager fails to send a package to a distribution point. even though a lot of what I wrote that for was the failure of packages to get delivered to child sites, the result was pretty much the same. when the client tries to run the advertisement with an old package, the result was a failure because of content mismatch.I went through an ordeal recently capturing these exact kinds of failures and corrected quite a number of problems with these packages. the resulting blog post is my effort to capture how these problems were resolved. if nothing else, it's a basic checklist of things you can use.DETECTIONstatus messagestake a look at your status messages. this has to be the easiest way to determine where these problems exist. unfortunately, it requires that a client is already experiencing problems. there are client logs you can examine as well such as cas, but I wasn't even sure I was going to have enough material to …