Monday, November 8, 2010

Network Adapter Priority Windows Server 2008 R2

Something cool that I just found out about... How does Windows choose which network to use? Does it do a network test to see which network has the best throughput? No. There may be a preference built in for wired over wireless, maybe. How do you change this? What if I have a preference for one network over another. Perhaps I want to connect via my wireless network over my wired connection. What if, I have RRAS connected to my wireless adapter, and I need that guy to be the preferred connection?
HOW??

Turns out Microsoft hid it from us, sort of... What you do is go to Network and Sharing Center and click on the change adapter settings link. From there, if you have the Desktop Experience installed, you might not have the menu bar running across the top. You need to hit the Alt button on your keyboard in order to get the menu bar to show up. From the Advanced menu option, click Advanced Settings.

What will load is a funky little window with your adapters in the top part, and the bindings associated with the adapters on the bottom. For our purposes, you can ignore the bottom part of the window. We are only concerned with the top part.
In the top part you see all of your network adapters. You will also notice two arrows on the right of the selection window. What you are seeing is the adapter connection priority. The highest priority is on the top, running to the lowest priority on the bottom.
All that you need to do to set an adapter with a higher priority is to highlight the adapter, and click the up arrow. That's it. Simple solution to a difficult problem.

Friday, November 5, 2010

Set Up Hyper-V With an Internal Network

Hyper-V is Microsoft's server virtualization product. Unlike Windows 7's Virtual PC, this product is a true vitalization suite. It allows you to create 32bit and 64bit virtual computers with any OS. This makes it very handy to create a virtual server farm for development or R&D use. Personally I use mine to host development environments for SharePoint 2010, and MOSS 2007.
If you want to create virtual servers that are available on your current network, simply attach your network card to the VM and off you go(more on this later), BUT if you want a private network separate from your public net work, i.e. you want to create a separate domain for testing and dev work, but want to keep your workstation connected to your current domain, it gets a little tricky.
I did my configuration using RRAS, not ICS. For one, RRAS is much more flexible than ICS, for another, RRAS is the professional way to do such a configuration. And I am always the professional. Like that guy in the movie Professional... Except I don't kill people... and I have friends other than a plant... and I don't have a French accent... and I am not being chased by Garry Oldman... and I don't live in New York... Other than that it is just like the movie.

Install Hyper-V
Hyper-V is a Role that you need to add to your host server. So, open your old friend Server Manager and head to the Server Roles section. Check Hyper-V and install.

Configure Networking
Now things get fun. In Hyper-V Manager, click on Virtual Network Manager. Create a new Internal network and give it a meaningful name. That name will become very important, so be sure to name it well. I called mine Hyper-V Internal Network.

What Microsoft has done with Hyper-V is to separate the physical network card completely from the OS. It then creates a virtual switch with several virtual network adapters connected to it. This is kind of complex, and you can go HERE if you want to learn more. What concerns us here is what happens with the Host's network adapters.
Open up Network Sharing Center, then click on Change Adapter Settings. You will notice that there is a new icon there. It will say something like Local Area Connection 2 or some other number. What is important is that the last line in the description, the binding information, should be the name that you gave your virtual network back in the Hyper-V manager.

Configure the Host's Virtual Network Adapter
Right click on the icon representing the Hyper-V virtual network adapter and select Properties. Double click on the v4 network settings.
Setting up the Host adapter is kind of funky compared to normal network set ups. First of all, we will not be putting in a gateway address. The virtual switch will be the gate, and if we specify a gate here, it screws everything up. In addition to this, we will not be putting in any DNS IPs either. Again, the switch will act as the DNS relay. The only thing we need to put in this area is the IP address and mask of the Host on the internal network. This address must be on a different subnet than the subnet that the host is on for the public network.
It makes sense if you think about it. Essentially, you are configuring your server to be a router. Routers need two network cards and need to have each card on a different subnet. Since you are creating a private VLAN, you will need some sort of router or switch to get you to other networks, thus the separate subnets.
So, my public network is, 192.168.107.x, I made my internal network 192.168.2.x.
To reiterate, on the HOST, the virtual adapter settings should just be the IP address and mask of the HOST in the subnet of the internal network.
In my set up my IP is 192.168.2.1, subnet 255.255.255.0.

Install RRAS
Back to the Server Manager for another role install. This time it is the Network Policies and Access Services role. Check that, then select Routing and Remote Access Service. Be sure both boxes underneath the selection are checked. Unless you are familiar with access restrictions, DO NOT install the Network Policy Server. This can mess up your installation if you don't know what you are doing. I didn't need this service, so I did not install it.

Configure RRAS
From here you will click on the new role that you installed (Network Policies and Remote Access) and right click on Routing and Remote Access. Select Configure. We are going to create a policy for NAT, so that is the guy we select. The next screen deals with which interface has the Internet. Select your public network interface and select next. Now we select the interface that we want to NAT on. Select the internal Hyper-V interface. That completes the initial configuration. We still have to configure NAT. You thought you were done with that, but you are not!

Configure NAT
Open up RRAS, then IPv4. Click on NAT. Right click on your public interface and select Properties. Click the radio button that says Public interface connected to the Internet. Check the box that said Enable NAT on this interface.
From there go to the Services and Ports tab. Check the box for the the various services that you want to use NAT for. I just want Internet, so I checked Secure Web Server(HTTPS), and Web Server(HTTP). When you check the boxes it will ask you what IP address you want to NAT from. Put in your interface IP address (for me that was 192.168.2.1). Click OK.
Done!

Install VM
From here You want to create your first Virtual Server. Set this up how ever you like it according to your needs. The network adapter that you want to use will be the name of your internal network.
When your OS is done installing, you will notice that it will have an IP address if you have enabled DHCP. This comes from the RRAS server. If you want a static, simply put in your address and mask from the internal network subnet. Your gate will be the Host interface, as will be your DNS servers.

DONE!

How To Set Up Windows Server 2008 R2 As a Kick Ass Workstation

Everybody knows that I am a Microsoft Guy... I make the majority of my money using and developing for their products. That said, they have massively screwed up at times. So badly that I have refused to work on several of their platforms (Windows Me, Windows Vista, Windows 2008). I have to admit Windows Server 2008 R2 is the bees knees. It is everything I have asked for in a modern operating system. This is R2, mind you, not Windows 2008. While a good start that OS wanted to BSOD every few moments... not fun.

Anyway, I like the OS so much that I wanted to use it as the OS on my workstation. Why? You get all of the benefits of 64bit with none of the hangups that Windows XP and Windows 7 seem to have. You get all of the features of a Windows 7 workstation, PLUS IIS 7.5, PLUS Hyper-V, PLUS RRAS, PLUS PLUS PLUS. It is awesome. In the past I have attempted to use a Server OS as my workstation OS, and I always ran in to some sort of hang up, I couldn't game on it, or It wasn't as user friendly, or it lacked some aspect of the workstation OS. Windows Server 2008 has none of those hang ups. It handles hardware, even advanced graphics cards, like a champ, and gives all of the nice to have perks that you are used to in a workstation OS. BUT... You have to work at it. There are lots of stuff you need to do to get the OS like you want it. I am going to go through what I did to get my Windows Server 2008 R2 working on my IBM Lenovo T410.

Install Desktop Experience
First things first... You look at Windows Server 2008 after install, and it looks like well... It looks like a server OS. Where is all of the pretty??? We want themes, and that cool graphical active program selector thing, and rotating background images, and stuff!!! We also want the ability to download and use Active X components as well as other WebDAV and whizbang web stuff. We get all of that by going in to the Server Manager and installing the Desktop Experience feature. It is easy, just check the box.
After installing the Desktop Experience we have all of the stuff right? Nope... That would be too easy. If you want Microsoft's whole new Windows 7 "glass" stuff, they call it "Aero", you need to open up the Services area in the Server Manager and find the Themes service.
After that, simply download the Windows 7 theme of your choice, and you are off to the races... So to speak...

Configure Wireless
A very annoying aspect of installing Windows Server 2008 on a laptop is that you have to jump through hoops to get your wireless network card to work. I must admit that I wasted a lot of time on this issue. I kept thinking that the OS had a problem with the driver. Nope, it liked the driver just fine, you have to install the Wireless LAN Service in order for it to work. Back to the Server Manager and open up the Features area and add the Wireless LAN Service Feature. If you card is installed correctly, immediately after installation is complete, you will see the OS looking for wireless networks.

Configure IE and Web Client Service
IE on Windows Server 2008 R2 is a pain in the neck. Even if you change your security and privacy options, it still complains to you that you are not as secure as you should be. There is a fix for that! You need to change the policy that is complaining.
First turn off IE Enhanced Security by going in to Server Manager. On the very first page is the Server Summary. On that page there is a link that says Configure IE ESC. It is on the right hand side in a box under the Security Information section. Set what you want for your IE annoyances just for users or just for admins. I set both to off. After that you are free to change your security and privacy settings to however you like them. Depending on your settings in IE, you may get a banner warning telling you that your security configuration has left your computer vulnerable. I hate that... So, let's get that changed.

Disable Security Warnings in IE
You will need to open up the Group Policy Editor (gpedit.msc, from run in the start menu, or somewhere else). From there go to:
Local Computer Policy
Computer Configuration
Administrative Templates
Windows Components
Internet Explorer
Double-click on “Turn off the Security Settings Check feature” and set it to Enabled. Done!

Monday, November 1, 2010

Dynamic List

I needed to create a method that would take any type, and return a List of that type. The catch was I didn't know what type T would be. How to get that done?

Like this:
1:  private object CreateList(Type type){
  
2:   System.Collections.IList lst = (System.Collections.IList)Activator.CreateInstance((typeof(List<>).MakeGenericType(type)));
  
3:  return lst;
  
4:  }  

Your calling code will need to cast the return correctly, but that one line will get you your dynamic typed list.

Thursday, October 28, 2010

SharePoint Explorer View, Windows 7, and the WebDAV Redirecter

Nothing is more frustrating than having something work on one computer, then not working on another... Some of this is to be expected, especially when upgrading Operating Systems, but with server based products, you expect most clients to act the same way. They are, after all, connecting to a program on another computer.

My frustration was the Explorer View in SharePoint. This view is a great tool for uploading lots and lots of files to a document library. It is also a great tool to show users that are used to having their documents on a file share. This view gives them a nice warm fuzzy that things aren't changing that much for them.

What I found was that in Windows XP IE 8, I could open the Explorer View just fine, however when I walked over to my Windows 7 IE 8 box, no dice. What the...

What I found was this. Microsoft changed how they handled various functions that are allowed to access to the Operating System. WebDAV being just one such function. It is important to note that SharePoint has its own WebDAV functions separate from IIS' WebDAV. More on that later.
In Windows 7 the WebDAV Redirecter Service must be turned on in order for SharePoint WebDAV to have access to Windows Explorer. If the service is not on, you either get an error saying that your browser doesn't support Explorer View, or, most frustrating of all, nothing happens. Flip on the Web Client Service, and you should be good to go.
Yeah, I realize that the service name is Web Client Service, and that the process is called WebDAV Redirecter. I don't know why. Microsoft is funny like that.

So, say you are setting up your server for a new SharePoint implementation, and you want to use the Explorer View for your document libraries. What do you do? Ignore WebDAV. Seriously. On both IIS 6 and IIS 7/7.5 servers, do not enable or install the WebDAV features. Windows 2003 will work regardless of it being enabled, but installing it on Windows Server 2008 will break Explorer View. So it is just good practice to leave WebDAV off of the box entirely. Why enable something that has to be patched, updated, and monitored if you are not using it?

Friday, October 22, 2010

Presence in SPGridView MOSS 2007

A company I work for will be incorporating Windows Communicator with their VOIP and IM system.
We also have a web based Corporate Directory application.
Wouldn't it be nice, someone thought, if we could put the Windows Communicator Presence Indicator in to our Corporate Directory?
The Corporate Directory is currently a SharePoint Data View Web part. Adding Presence would require custom development.
Off I go.

The first issue I ran in to was that there is some debate on how to get Presence information in to SharePoint (MOSS) 2007, some blogs say to use the IMNRC java script, while others say to use the imnmark image with a IMNImageOnClick java script event.
Confused? Me too. The problem is that Microsoft left the old way to do Presence in to the new version of SharePoint, so what would work in 2003:


<span><img border=\"0\" height=\"12\" src=\"/_layouts/images/imnhdr.gif\" onload=\"IMNRC('"you@domain.com"')\" ShowOfflinePawn=\"1\" alt=\"\" id=\"user_presence_icon\"/></span>


will work in 2007, but the way Microsoft does Presence in 2007 is with the anchor and image tags:


<a href="javascript:" onclick="IMNImageOnClick();return false;" class="ms-imnlink"><img title="" alt="No presence information" name="imnmark" border="0" valign="middle" height="12" width="12" src="/_layouts/images/blank.gif" sip="you@domain.com" id="imn1,type=sip" ></a></span>


Great! It works for just one user, with their email address hard coded. The problem is that I have lots of users, and everything is stored in a database.
Easy!, you say, Just use a GridView and put that stuff in there!! Sounds good, but SharePoint always has a way of messing with us. The SharePoint version of a GridView is the SPGridView. It is just like a GridView, only harder. In SharePoint you do nearly everything in the code. It sucks. Personally, I like the ability to use the Design tap of Visual Studio it lets me know what I have going. So, I tend to use User Controls so that I can see what is going on. Only that does not really apply here.
Anyway, typically what you would do in ASP.NET programming would be to drop a GridView on a page and set up your fields. Because we are using some HTML you will need to create some template fields. Generally looks like this:


<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>


No problem! Except that we are in SharePoint and we have to do all of that in code...

This is where it really gets sticky. You will notice that the Template Field is called as a control. That means that it is a part separate from the GridView. That makes your life in SharePoint difficult.

As Oscar Medina details in his awesome blog post SPGridView - Using a custom TemplateField to add a Checkbox Column you can declare a Template Field inside your SPGridView, but you will need to create a class for your Item Templates.

A class that inherits from ITemplate, and you will need to override the InstantiateIn method in order to stick your stuff in.

During my very frustrating trial and error period, I found that the best way to get the Presence stuff to work is to use the new 2007 method, but convert all of that HTML in to ASP.NET controls. The ITemplate object likes those better. So what I ended up doing was creating two Literal Controls for the span tags, a Hyperlink Control for the anchor, and an Image control for the image. I used the Attributes.Add for all of the extra stuff in the anchor and the image tags that is not supported in the normal control.
So your code from above now becomes:


LiteralControl lc = new LiteralControl();
lc.ID = "lcSpan1";
lc.Text = "";


HyperLink hypLink = new HyperLink();
hypLink.Attributes.Add("onclick", "IMNImageOnClick();return false;");
hypLink.CssClass = "ms-imnlink";
hypLink.NavigateUrl = "javascript:";


System.Web.UI.WebControls.Image imgPresence = new Image();
imgPresence.Attributes.Add("name", "imnmark");
imgPresence.Attributes.Add("id", "imn1,type=sip");
imgPresence.ImageUrl = "/_layouts/images/blank.gif";
imgPresence.Attributes.Add("sip", "you@domain.com");
imgPresence.ID = "imgPresence";


LiteralControl lc1 = new LiteralControl();
lc1.ID = "lcSpan2";
lc1.Text = "
";


Sweet huh? Again, it works great for hard coding a single user to a Presence indicator. We don't want that. We want something we can stick in to a SPGridView to display a whole bunch of people. Here we go.

First you need to set up your data source. I like to use DataTables.


DataTable DT = new DataTable("Data");
DT.Columns.Add("Name");
DT.Columns.Add("Position");
DT.Columns.Add("Presence");
DataRow row = DT.NewRow();
row["Name"] = "Natto Ninja";
row["Position"] = "Goofball";
row["Presence"] = "nattoNinja@domain.com";
DT.Rows.Add(row);

row = DT.NewRow();
row["Name"] = "Megan Fox";
row["Position"] = "Megga Hottie";
row["Presence"] = "iamhot@domain.com";
DT.Rows.Add(row);

row = DT.NewRow();
row["Name"] = "Al Sharpton";
row["Position"] = "King of the Goofballs";
row["Presence"] = "KOG@domain.com";
DT.Rows.Add(row);


DataTables are fun. Now we need to create our SPGridView. There are a couple of different ways to do this, if you are using a control, you can use Ted Pattison's approach or you can just create it in the code. Calling it in the code makes it tougher for you to place on the page, but Pattison's approach requires you to create a code behind (not a code beside, very important distinction. If you don't know the difference you need to read Pattison's article). At any rate you have to create the grid.


SPGridView grdSPGrid = new SPGridView();
//Createyourfields
SPBoundFieldfldName=newSPBoundField();
fldName.HeaderText="Name";
fldName.DataField="Name";
grdSPGrid.Columns.Add(fldName);

SPBoundFieldfldPosition=newSPBoundField();
fldPosition.HeaderText="Position";
fldPosition.DataField="Position";
grdSPGrid.Columns.Add(fldPosition);

TemplateFieldfldPresence=newTemplateField();
fldPresence.HeaderText="Presence";

//Call your class that creates your Item Template
fldPresence.ItemTemplate=newGridViewTemplate("Presence");

grdSPGrid.Columns.Add(fldPresence);

//Call the method that inserts your row information in to your image control
grdSPGrid.RowDataBound+=newGridViewRowEventHandler(grdSPGrid_RowDataBound);

//Bind the the DataTable to the SPGridView
grdSPGrid.DataSource=DT.DefaultView;
grdSPGrid.DataBind();


You will notice the place where I call a class to get my Item Template going. It is in that class where I create my objects that will become my Presence indicator.
Here is that class:


public class GridViewTemplate : ITemplate
{

private string columnName;

public GridViewTemplate(string colname)
{

columnName = colname;
}

public void InstantiateIn(System.Web.UI.Control container)
{

LiteralControl lc = new LiteralControl();
lc.ID = "lcSpan1";
lc.Text = "";
container.Controls.Add(lc);

HyperLink hypLink = new HyperLink();
hypLink.Attributes.Add("onclick", "IMNImageOnClick();return false;");
hypLink.CssClass = "ms-imnlink";
hypLink.NavigateUrl = "javascript:";
container.Controls.Add(hypLink);

System.Web.UI.WebControls.Image imgPresence = new Image();
imgPresence.Attributes.Add("name", "imnmark");
imgPresence.Attributes.Add("id", "imn1,type=sip");
imgPresence.ImageUrl = "/_layouts/images/blank.gif";
imgPresence.ID = "imgPresence";
container.Controls.Add(imgPresence);

LiteralControl lc1 = new LiteralControl();
lc1.ID = "lcSpan2";
lc1.Text = "
";
container.Controls.Add(lc1);


}

}


That builds our template field. Now for the last little piece. There has to be a way to insert the data from the DataTable in to a variable that we can set in to the image control.
To do that, we need to go in during the data binding of the SPGridView. Which is why I have this line in the code that creates the grid:


grdSPGrid.RowDataBound+=newGridViewRowEventHandler(grdSPGrid_RowDataBound);


That guy calls this method in the same class:


void grdSPGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string row = "";
//Find the row with the data
DataRowView rowView = (DataRowView)e.Row.DataItem;
row = rowView["Presence"].ToString();
//Create a new image control and cast it as the control in the grid
System.Web.UI.WebControls.Image imgPresence =
(System.Web.UI.WebControls.Image)e.Row.FindControl("imgPresence");
imgPresence.Attributes.Add("sip", row);

}


}


That is all there is to it! It took me nearly a week to figure all of this stuff out. It was a lot of fun finding the right events, and creating the proper event handlers and stuff.

In case you are confused, the code that creates the SPGridView and the code that does the special binding all should be in the same class. The class that creates the ItemTemplate can be in a separate class file, or just as another class in the same class file as your other class.
Hope this helps some people.

Many thanks to Oscar Medina and Ted Pattison. Their posts really helped be out, and I surely would not have gotten my grid to work without them.

Thursday, October 7, 2010

SharePoint Template Gotchas

I am having to do a lot of simple web part movement and site design stuff lately and I ran across some issues that threw me...

In the past, I have created a site and configured the basic web parts that I wanted set up the primary pages generically and configured everything the way I wanted to see it anytime I created a new sub site. I would then go to the Site Settings and to Look and Feel then save the site as a template. Anytime I wanted my generic site look, I would simply create a new subsite with this template. Easy peasy.

This time I was working on a Publishing Site that would need several sub sites that would all have the same basic properties, lists, and web part views. I created the first site, clicked on up the Site Settings, looked over at Look and Feel and... Nothing. No Save Site as a Template link. What the...?? I stated going through the site features and even in to Central Admin to see if I had all of the Farm Features active that I needed to be active. No Dice.

It turns out that Publishing Sites can not be saved as templates. Bummer.

SharePoint being SharePoint, many times you can do things you are not supposed to do if you know how to use the forms and other features, I decided to poke around to see if I could get things to work the way I wanted to. The first thing I found was that if I deactivated the Publishing features, I could save the site as a template, create a new site, then activate the Publishing features at that time... This would do what I wanted... kind of. I wanted a better solution, so I tried a trick that I learned to do when I had a number of web parts that I wanted to delete from a page, to grab the actual template save application page URL and append that on to my publishing site URL to see if I could get it to save the template as I wanted it.

The URL of the save as a template application page is: _layouts/savetmpl.aspx. So my site URL: http://MOSS2007/TemplateSite became http://MOSS2007/TemplateSite/_layouts/savetmpl.aspx
To my wonder and surprise the application page popped up and I was able to save the site as a template. I created a new site using this template, and it worked like a champ.
Turns out my buddy Shane Young already had this figured out way back when. Go figure...