SharePoint is sometimes a riddle, wrapped in a mystery, surrounded by an enigma. And even more so when you get stuck trying to do something, hoping the system will tell you how, only to stumble onto an undocumented command line switch that does what you need.
Enter the super-secret-that-everyone-knows-about “deleteconfigurationobject” parameter in stsadm.exe.
Go ahead. Enter this in your console.
1: stsadm -help deleteconfigurationobject
And rather than getting the usage screen (meaning you entered a parameter that the program didn’t understand) you get this:
1: stsadm.exe -o deleteconfigurationobject
2: -id <objectId>
Woah. That wasn’t in the usage screen when you enter stsadm.exe by itself. Nor is it in the documentation for stsadm.exe on TechNet here.
This is what is known in the software world as an “undocumented feature”. Meaning something you can use, invoke, etc. but it’s not documented so it’s not guaranteed to be there tomorrow.
Okay, armed with the knowledge this bad boy exists, what would I do with it?
In my situation, I’m working on custom timer jobs. Andrew Connell recently wrote some great blog entries and MSDN white papers on custom timer jobs and Gary Lapointe recently had a posting about deploying files not handled by the WSP schema for you.
Basically if you want to run something on a regular basis you can create a custom timer job, register it, and have the OWSTIMER.EXE service take care of it for you. This beats the pants off of having to write a console application then setting it up on the Task Scheduler because you have immediate access to the SharePoint site structure to do updates or what have you. For example, rather than calling out to a weather web service for every user or having to deal with caching information, I created a timer job that did it for me and let my web part simply read from a sanitized SharePoint list on the site for the local weather. This required some hourly updates to the list which I did via a custom timer job. Again, check out AC’s article(s) on the subject and you can’t go wrong.
However, there are times that things go wrong. Very, very wrong. Like tonight. I had created some timer jobs but foolishly ripped out the default constructor (which is required for serialization/de-serialization). Bad Bil. This caused me no end of grief when I tried to remove the jobs since de-serialization failed, the jobs threw exceptions during feature de-activation and never got deleted.
What I ended up with was this:
The names of the custom jobs are obfuscated here, but the two job names at the bottom of the image (pixelated out) are the same job name but with different instance IDs.
In the Central Admin screen, you can view the job definition and even disable jobs but there’s no where to delete a job definition. There’s even a CodePlex project here for doing custom job manipulation (very handy if you want to quickly reschedule a job) but alas, there’s still no delete feature.
Update: I did find a project here on CodePlex that’s specifically made for manipulating timer jobs and does (based on the screenshots) allow deletion. Grab it and install it if you don’t want to do the manual steps below!
I thought I was going to have write a cruddy console app to find the job and delete it via the API. That’s until I found this forum post on the interweb. It hinted at a command line operation for stsadm.exe called deleteconfigurationobject. Like the forum post says, go into Central Admin to find your jobs and hover over the job name. Then select the shortcut and paste it into Notepad or something. You’ll get something like this:
Note the Id after the JobId parameter. The dashes are encoded and show as “%2D”. Simple change them to a real dash and strip away the rest to get this:
This is the GUID for the job timer that we want to delete.
Now go to a command prompt and enter the secret deleteconfigurationobject operation using the GUID for your job as the id:
1: stsadm -o deleteconfigurationobject -id bf166029-7c99-49cc-9ade-45586487c20c
3: Operation completed successfully.
Voila! Rogue job timer gone away! Poof.
Daniel Bugday, you made my day! I’m sure there are other configuration objects you might need to delete that have no user interface anywhere in SharePoint that might be used with this command.
Like I said, caveat emptor. This is an undocumented feature and maybe a simple oversight or potentially not something meant for end-users. Thus Microsoft may choose to remove it in the next version or change it’s behavior or turn it into a newt. Don’t bet the farm on this command (but it’s nice to know it’s there isn’t it?).