Thursday, December 25, 2008

Time for heat tape again...but should I use RG6?

Our attic is insulated as much as physically possible. But since the attic is living space, we still lose a lot of heat through the roof. Grand Rapids has gotten something like 3 foot of snow in the past two weeks, and that means that there is one thing on my mind--ice dams.

I've discovered something, though--the heat loss isn't nearly as bad as I once believed. I need to get some expanding foam to fill a couple of holes that I realized heat is oozing through, but when you get right down to it, our problems are less heat loss and more roof design. Our roof is a gable design that, if you look at it from the top, is essentially a + sign. That means 4 giant valleys in the roof. The ice dam problem is primarily in the valleys--but the valleys are so large that they collect water from a good portion of the roof. The dams build out from the end of the valley. That means that I don't need to address the entire roof--I need to address the valley.

I learned this from what might wind up being a potential solution--our new HD Satellite dish. The new dish had to be roof mounted, rather than wall mounted like our old dish. So there are cables coming down the roof from the dish, across the facia, and back into the house. And it turns out that the ice dam on that part of the house stops at the cable.

I don't know the specifics of the electrical properties of satellite cable. But it appears that the current on the wires are generating a little bit of heat. Just enough heat to melt the ice as it reaches that point of the roof and lets the moisture flow off of the roof. The fact that the dam stops at that point reassures me that the whole roof isn't melting--just selected areas. But, more importantly, if the low voltage current on the RG6 is generating a little bit of heat, that means that it might be useful as heating tape.

Heating tape is expensive, and you've got to get an electrical power source for it. RG6 isn't nearly as expensive, and being a low voltage source, I don't have nearly the concerns of getting power to it. But the best part is that I might not have to pay for the power at all--maybe the cable company already is.

Here's my theory--if the satellite cable is generating heat, perhaps the cable TV wire might as well. The cable company is already providing a current to my house--the signal is filtered (since I don't subscribe to cable) but the connection is there. And if the power provided by the cable company is similar to the satellite signal, then it should work just as well.

I'll need to test it. My plan is to get a length of cable (probably 20-30ft; I think I've got a scrap chunk that size already) and bring it to outdoor temperature before I begin testing. I'll then put the cable on the snow without anything hooked to it. In theory, it should just sit there. I'll then attach it to the CATV block on the outside of the house and compare the results--if my hypothesis is right, it should melt through the snow. If it does, then I just need to arrange a length in each of the valleys. If it doesn't work, I'll need to connect some sort of terminator to the end of the cable; a full circuit may be needed.

The other two possible explanations for the satellite cable working are 1. The satellite system's electrical properties are different. If this is the case, I may still be able to use the cable, and just power it from a satellite receiver (I've got a couple of old ones). The final possibility is that the cable is actually acting as a conductor from the inside of the house--if that's the case, then I don't even need a power source--I just need a long enough length of cable inside of the house to provide heat to the length outside of the house.

I'll post back when I have done some testing.

Monday, December 08, 2008

Everything I need to know about Sharepoint...

When I first started playing with it earlier this year, I was still thinking in the mind of a web designer. "Don't worry about content--build the design." I've done a 180; now I couldn't care less about the design. Everything needs to be about content, content, content.

I'm beginning to think that Content Types are the real key to Sharepoint. Even if you don't really "use" content types, you still use them. Every list uses a default content type. Content types have been really easy for me, as an Object minded developer, to pick up. You've got something that has properties, methods, and events. It inherits from it's base class. It can be a base class.

My new rule is that the most important thing to do when beginning to work with a department on an Intranet presence is to sit with them and define content types. Defining content is all about defining what properties need to go along with that piece of data. People seem to best understand this when I say that we use these properties to search, filter, and report on the data.

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.

Monday, October 27, 2008

Sharepoint Lists--gotta keep remembering that this is object oriented...

I've been pounding my head against a wall on this Sharepoint List idea I mentioned a few posts ago. And then, tonight, while, um...on the comode...I had an idea.

All of this stuff is now object oriented. VB is OO, all of the stuff in Sharepoint is OO. I've been thinking in terms of flat development, though, trying to make a project that is generic while also having all of the features I want. Silly programmer.

So, new plan--the sublist stuff will come in the second generation object. First generation will focus solely on keyword processing. Ultimately, the entire goal of a keyword is to drop a value into a list item field. The XML layout for the keywords should contain the keyword name, the column that the value will go into, and a datatype (for validation). I may add one or two things to that list as I work, but that's pretty much it. Then gen 2 can handle processing to sublists based on field values, rather than having it worry about keyword processing as well.
ASP.net Application generating "Parser Error", and unable to find it's underlying object?

This is one of those things that is talked about heavily online--but I hadn't found anything to fix my specific problem. I had a working application that I was able to publish to my development box without any difficulty. I'm just starting to play with web applications, and I can't see to publish to my application server yet, so I took the final product and copied it to it's own folder under wwwroot on the app server.

Every time I went to the app, it said that it couldn't load it's base object. The application DLL was in the application's BIN folder, and I knew it worked. All of the posts I found referring to the error were essentially the equivalent of "Well, did you turn it on?" I was looking for something a little more intelligent.

It turns out that, if you don't use Publish, you have to create the application as well as the folders. Go into IIS Management, find your folder, right click it, and click Properties. Odds are, "Application Name" is set to Default Application, and it's grayed out. Click the Create button, and it will create a new application (named for the folder). This will cause IIS to look in that folder's BIN folder for the DLL, like it's supposed to.

Saturday, October 25, 2008

Tried to update our oldest SQL 2005 box to SP2 this morning, and the update of the database and analysis services failed. Nothing too obvious in the log. During the middle of the SP install, I got this error twice:

Installation of KB921896 Failed.

I'll spare everybody the hour or so of blog reading; here's what I ultimately found:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=378205&SiteID=1

This server was originally just a member server, but I upgraded it to a Domain Controller (long time ago, back when I had very limited server resources). The security groups that the post at microsoft.com refers to were deleted at DC Promotion. Removing the registry entries mentioned in the post worked great.

Saturday, October 04, 2008

Huh, they haven't deleted this thing yet. OK, so here's my big "what if" project right now. I'm starting to hit Sharepoint pretty heavily for work, and I want to do a big whiz-bang thing to show management so they realize the benefits. I also want to start tracking support calls better.

So, in a nutshell, here's the plan: Create a list on a sharepoint site that will receive all of our support emails and voicemails. Have this list use the ID number of the list entry as a case number, and have the list use keywords included in the posting to set various items (like responsible IT person, issue types, etc.).

Then, have another list that contains the work detail for each case. I'm thinking that I can put logic into the first list so that, if a posting comes in that has a case number keyword embedded in it, it can move the entry to the secondary list as a piece of detail for that case.

I'm playing around with event receivers for lists (I'm using the announcement list right now--seems simplest), but I'm missing one somewhat important piece. The primary list will need to have a reference to the secondary list in some way. I figured I'd just use Visual Studio to create a new list type based off of Announcement, but all I can do with that is add columns to the list. I haven't found yet if I can add properties to the list itself. So if anyone knows how to do that, let me know--otherwise my workaround will be to put one entry into the list (expire it, since I'm using the announcement list and it won't show up on most views if it's expired) that has keywords for the name of the secondary list, as well as any other "List wide" properties I need.