Using this diagram as an example: when I bring up links A, B and C everything is ok. When I bring up link D, link A is blocked via STP (I think Router B is the doing the blocking as opposed to router A). Router B and D do not have the same VLANs. Router B was the existing core switch while A and C are remote offices connected via dark fiber. Router D was added as purely a storage network core switch and it connects to router A and C via a separate dark fiber connection.

My incorrect assumption in this was I thought that since these links were on a different VLANs that there would not be a loop, but I think the switching sees MAC addresses and not necessarily VLANs.

I want to bring up link D without blocking anything and these are production switches so it makes it a little more difficult (I can do this after hours and not create and problems).

I think I need MSTP or PVST. I also have a mixed environment of Dell and HP switches. Where could I start first to configure this?

STP will always block one route to prevent loops in the network, but this doesn't mean that there isn't a path for all the switches to go on, STP can be turned off to allow what you are asking for, but will bring down the network due to the loop.

Other STP protocols do work on vlans, but again one path will be blocked to prevent loops.

If you are trying to achieve route optimisation, by placing the blocked path in a different location this can be done (On Cisco equipment) by manually setting the Bridge ID (BID)

Let's say you have three switches connected in a ring. Between switch A and B, you use vlans 1 and 2. Between A-C and B-C, you have only vlan 1. The path for vlan 2 between A and B might be shut down. STP, in this case, can't create separate loops for separate vlans.

Per-vlan or multiple STP can do what you want. It does mean that presumed inactive links may be partially active, just not used for forwarding certain traffic. It also means that you may yank one connection (with the vlan you're interested in) and leave it no path to same endpoint through switches without that vlan defined.

My first step would be to define all vlans on all switches and get it working. Then, you can start to research PVST and pare off unwanted links.

Okay, can I get a little clarification here? When you say Router, do you mean that these devices are routing packets and operating at L3? If these are Routers, or L3 Switches using these links only as Router-to-Router connections, then you shouldn't be sending any spanning tree frames between them. If they are Switches, and the actual routing is happening only at the core, then you should be using MSTP or RPVST+.

Spanning tree should be used for your internal network links, from Access to Router, but not Router to Router. On L3 links you should be filtering spanning-tree frames so each Layer 2 domain has it's own router as the root.