Tuesday, November 18, 2008

Lists for Lists

It's almost there. I did decide to change my code and dump the XML Post that I processed keyword info from. Instead, I now process from a list named _Keywords. To make things even easier, I created a list definition that already has all of the fields setup, so you just create your Keyword list and populate it with keywords. I've got another bug or two to work out, and I'm going to add a keyword definition property of "Overwrite" (append will take priority, in case some idiot sets both), but it's coming along great. So well, in fact, that I deployed it to my main Sharepoint server.

My workflows are working quite well. I was going to try doing them in Visual Studio, but it seems way too complicated. I did find this:
Essential Workflow Tools for SPD

which answered one nagging problem I had with doing the Workflow in Sharepoint Designer--being able to generate an email from someone other than the system account. If you do Workflows in SPD, you need this.

Tuesday, November 11, 2008

I'm having one of those epiphany days

I can't remember the last time I was this excited about a technology. My keyword processing list is working very well. I've even come up with an enhancement to it that I will hopefully be able to do tomorrow--why bother storing the keyword definitions in a list item (and parse them as XML) when I could use...wait for it...Another list? I still don't know how to add a property to a list, so it'll mean hard coding a list name (probably _Keywords), but it'll give me more flexibility, as well as the ability to lock security down even tighter.

But that's not what has me so excited. I've got my Supportcenter lists working. Supportcenter is made up of two lists (both of them are Keyword Processing lists). One list is the main "Issues Log" list, and the other is a "Issues Detail" list. From a 10,000ft perspective, you log the main issue in the Issues Log, and then any detail (actions, emails, etc.) goes into the Issue Detail list. But the goal is to make this system email enabled, so the users only have to email their issues, rather than manage them on a web interface. That's where workflows come in.

Note: Workflows come in only after you install the infrastructure update and set a property as detailed in Microsoft KB 953289. Sharepoint SP1 broke the ability for workflows to automatically start from list items created via email.

I started thinking logically--have the emails come into the Issues Log list, and have that list determine if it's an open issue (meaning that the item should be moved to the Detail list) or if it's new. But that meant that anyone subscribed to get alerts to the Issues Log list would be notified for every message. So I had to stand on my head to see the answer.

Emails from clients will come into the Detail list. This list processes for keyword "CaseID", and if it exists, it fills the CaseID field. It then looks up the client and who is responsible for the Case from the Issues Log and notifies just that person and/or the client (it will not notify the person that created the item). The magic happens when an item gets created *without* a CaseID.

Then, the workflow takes the list item and moves it (actually, it copies it and then deletes it) to the Issues Log list. The Issues Log has it's own new item workflow. When and Item is created, it fills the CaseID field with the value of the list item ID (always unique). It then modifies the subject line of the item to append [CaseID:].

Another workflow exists for the Issues Log that runs when an item is modified; if, after modification, CaseID no longer equals the list item ID, it assumes that the entry is actually a followup detail for an existing case, and so it moves the item to the Details list (triggering the "new item" workflow in that list; thankfully Case ID is set now). If CaseID still equals the item ID, then it looks to see if an IT representative has taken responsibility for the item (the ResponsibleIT field). If so, it creates an entry in the Detail list (which, for those of you playing at home, will notify the client and/or the responsible IT person) saying that the Case has been assigned. It also changes the status of the Case in the issues log to "In Process".

I'll probably have a few more workflows in this mix, but that's the general overview of it all.

Sunday, November 09, 2008

Recycle OWSTimer too!

I've been back to working on my keyword processing sharepoint list (coming along quite well, BTW). The main goal of this list is to be able to take a list entry that was emailed in and automatically fill in column values for that item. Since sharepoint scans for inbound emails once a minute, though, to speed testing I put list items in using the web interface. Everything was working great, so I decided to start trying it with emails.

Now, a little background on the list--I don't know how (or if it's even possible) to add custom properties to my list. The only centralized place that I could figure out to store my keyword definitions is in a list entry with a specific subject. (If anyone knows a better way, please let me know.) Since I didn't want to be troubleshooting my CAML queries at the same time, I just put the keyword definitions for testing right into the code. Once I got the actual processing code working, I changed the code to start pulling from a list entry with a title of "KEYWORDXML".

Now, back to the story. I sent in an email, and it seemed to work. One of the options in the definition for each keyword is whether or not the keyword should be removed from the title. I had one removing, and one staying. I decided to try pulling both, because it it more difficult than it sounds. :) I emailed in a post, and only one keyword was removed. I posted on the web interface, and both were removed. I kept dorking with it, ultimately removing my "KEYWORDXML" post to see that, with the web interface, it didn't process any keywords in the title. If I emailed, it still processed them in the same way that it did when I started testing. What is going on?

It finally hit me. After every deploy, I would do an IISReset, or else the web interface wouldn't start using the new code. I looked at the sharepoint log, and it turns out that, while w3wp.exe was processing the stuff I did on the web interface, owstimer.exe was processing anything emailed in. Turns out I need to reset the Sharepoint Timer interface as well--the timer was still using the *original* code that I had published, with the keyword definitions embedded into the code.

Friday, November 07, 2008

Offering Remote Assistance, Part 3

I decided to go with the registry update. Yeah, it opens a security hole, but I can keep that from becoming an issue at the firewall level.

I've got three aspx pages all total. The first I mentioned already--the login script uses wget.exe to pass the appropriate information (user, workstation name, IP) to the webpage, and the page saves that to the database. I save a new record on each login, so I can compile historical information.

The second aspx page is a very minimal page. It has a dropdown list of users and a button to offer remote assistance to that user. Selecting a user and clicking the button generates a startup script when the page reloads; the script just opens the hcp page that takes an IP as a parameter. The built URL includes the IP looked up in the database for that user's most recent login.

The third aspx page is for IT use only; selecting a user provides a link to start remote assistance, a link to open the user's C$ drive, and a table of all logins in the past 7 days for that user. In the next revision, I plan to allow the end user to click on an item in that table, and update the links to connect to that workstation.

Tuesday, November 04, 2008

Offering Remote Assistance Part 2

After pouring through the stuff in the previous post, the best solutions seems to be a new file I totally scammed from one of the web pages (http://www.lansweeper.com/forum/yaf_postsm3186_Offer-Remote-Assisstants-for-Custom-Action.aspx). But before talking about that, let's talk about how Offer Remote Assistance actually works.

If you go into Start, Help and Support, you're actually running helpctr.exe. Helpctr.exe is actually a web browser. It's a special web browser, though...to put it bluntly, it is a web browser that has no security whatsoever. The "Offer Remote Assistance" page (accessible in "Help and Support" by going to "Use Tools to view...") is nothing more than an HTML page. You can access it directly using this URL:

hcp://cn=microsoft%20corporation,l=redmond,s=washington,c=us/Remote%20Assistance/Escalation/Unsolicited/unsolicitedrcui.htm

The page has a lot of scripts and an instance of the actual Remote Assistance ActiveX control. But you'll note that you don't get prompted to allow it to use the control--it just does.

Help and Support is actually just a library of HTML files. Some of them take parameters. Back when XP originally came out, someone figured out that you could put a link (like the one above) on a web page, get someone to click it, and do all sorts of nasty things--even with the files already built into Help and Support.

Microsoft's fix to this was to change the way the HCP protocol was registered. Clicking an HCP:// link just fires up helpctr.exe and passes it the URL with the -URL parameter of the program. Now, they've added a "-FromHCP" parameter to the program as well, and the setup in the registry passes this parameter. What this does is prevents helpctr.exe from processing anything in the querystring of the URL; instead, if the URL has a querystring, helpctr.exe opens and just displays an error. To open an hcp link with a querystring, you have to fire off helpctr.exe manually, using the following command (I'm just taking the url from above, obviously there's no query string on this one):

%windir%\PCHEALTH\HELPCTR\Binaries\HelpCtr.exe -url hcp://CN=Microsoft%20Corporation,L=Redmond,S=Washington,C=US/Remote%20Assistance/Escalation/Unsolicited/UnsolicitedRCui.htm

If you just click an hcp:// link, Windows actually fires off this command:

%windir%\PCHEALTH\HELPCTR\Binaries\HelpCtr.exe -FromHCP -url hcp://CN=Microsoft%20Corporation,L=Redmond,S=Washington,C=US/Remote%20Assistance/Escalation/Unsolicited/UnsolicitedRCui.htm

OK, now with all that talk, what's the problem? Obviously I found a great replacement htm page for Remote Assistance that I can pass a parameter to. The problem is that I want to just put a link within my web page that will fire up this htm file with a query string. But the -FromHCP parameter will make that error out. So now I have two choices:

1. Create an ActiveX control of my own that I can have users install that will fire up the full command line to helpctr.exe
2. Modify my user's registration for HCP to remove the -FromHCP parameter

Both are ugly. #1 is more difficult to support and roll out, and #2 is a security risk. I'm leaning towards #2, but it means that I need to modify our firewall to ensure that any page that contains an HCP link gets blocked.

Programatically offering Remote Assistance

I needed to shift gears a little bit today; I'm having more and more need of giving people outside of IT the ability to offer remote assistance to other users. Since the Offer Remote Assistance tool requires a workstation or IP, and I've got too many workstations to know by heart (I used to know all of them), I've got our login script writing out a text file for each user when they log in. When I need to connect to a user, I open their text file, get their IP, and connect to it.

Kinda complicated for your average user, though. So today I wrote a small ASP.NET application that writes out a database record when the user logs in. My goal is to then have another part of this application be an interface that a user can go to, select a remote user to connect to, and have the application do the rest of the work. The critical piece of this is being able to programatically start up remote assistance and feed it an IP address.

I looked into this back in May, but I didn't keep any notes. So the main point of this post is to store links that might be valuable, and possibly a solution if I come acrossed it. First, the best Google string seems to be "unsolicited remote assistance pass parameter". Some of the links that come back that look useful are:

http://blog.netnerds.net/2006/12/ra-pass-workstation-and-username-parameters-to-offer-remote-assistance/
http://msdn.microsoft.com/en-us/library/ms811079.aspx
http://www.joatit.com/wordpress/?p=53

There is probably other good information, but now, if I wind up getting sent off in another direction, I can come back here and start again.

Monday, November 03, 2008

Creating a Sharepoint List, Try 1

There seems to be a real lack of information on how to create a new sharepoint list in VB. Lots of examples in C#, but nothing in VB. And even for those of us that speak both languages and can usually translate back and forth, there seems to be a lack of useful "10,000 ft" information. I've been doing a lot of little test Sharepoint objects, and it seems like I'm constantly running into publish errors because my new item is still named "ListDefinition1" at some place that matters.

So here's how I do it. I'm going to update this post as I find glaring errors (as I'm sure I will).

Create a new Sharepoint List Definition project, and give it a decent name. Note that you do need the Visual Studio Sharepoint project templates for this (although, if you are pretty good at .NET, you can probably develop them from scratch...I'm not good at .NET, though).

Select your base list definition. I always add with event receiver (why develop a new object if it can't handle any events?), but I don't check the "Create an instance". I'm not sure what that one does, actually. I tend to develop off of the Announcements base class, since it's basic and handles inbound email.

At this point, it seems to still be named "ListDefinition1" in some places. Next I change all of these that I can find: the folder in the project, the schema.xml file, and the listdefinition.xml file. I don't know if I'm allowed to change the names of all of the files that are named pretty generically, but they don't have "ListDefinition1" in the name, so I don't worry about them. I'm also not sure about the Public Class definitions for the event receivers; it looks like I can change them, so I go ahead and change them.

There's another thing I ran into, I think only with webparts, though. The template includes references to MOSS DLLs. I'm not made of money, so I only have WSS. These references can be easily pulled; there's plenty of information out there on how to do this. Just google the error you get when you try to build.

That should be it. It's all those name changes that get you. But I'll update this if (when) I find errors to my methodology.