The Life and Times of a Dev

Yes, we're really that weird
posts - 189 , comments - 341 , trackbacks - 106

My Links



Tag Cloud


Post Categories



Thursday, November 20, 2014

Testing EntityFramework with Moq

Let’s face it, EntityFramework is a pain to mock.  With few interfaces, testing things that use it can be a real pain.  Here’s a few things I’ve found to make it easier:

  1. Make sure that you have an interface for your DbContext object so that it can easily be mocked.  If you’re doing Database First, be aware that EF 7 will eliminate EDMX support, so welcome to the code first era (I hear you . . .).
  2. Rather than using your Dependency Injector to directly inject an instance of your IDbContext, create a context provider instead.  This will make testing easier since you can easily mock the provider.  Something like IMyContext context = IContextProvider.GetContext(); where IContextProvider is injected.  You can also easily set things like lazy loading and dynamic proxy generation, both of which are useless for anything that doesn’t have direct access to the database.
  3. Make sure you’re using IDbSet<T> instead of DbSet<T>

With all of that in place, you can do some really fun stuff.  Here’s a method that I use to setup a DbSet that is backed by a List, and is attached to the context:

protected Mock<IDbSet<T>> SetupDbSet<T>(IList<T> dataSource, Mock<IMyDbContext> context) where T : class
    Mock<IDbSet<T>> set = new Mock<IDbSet<T>>();

    set.As<IQueryable<T>>().Setup(drs => drs.Provider).Returns(dataSource.AsQueryable().Provider);
    set.As<IQueryable<T>>().Setup(drs => drs.Expression).Returns(dataSource.AsQueryable().Expression);
    set.As<IQueryable<T>>().Setup(drs => drs.ElementType).Returns(dataSource.AsQueryable().ElementType);
    set.As<IQueryable<T>>().Setup(drs => drs.GetEnumerator()).Returns(dataSource.AsQueryable().GetEnumerator());

    set.Setup(s => s.Add(It.IsAny<T>())).Callback<T>(dataSource.Add);
    set.Setup(s => s.Remove(It.IsAny<T>())).Callback<T>((i) => dataSource.Remove(i));

    Type type = typeof(IDbSet<T>);
    Type contextType = typeof(IMyDbContext);
    var parameter = System.Linq.Expressions.Expression.Parameter(contextType);
    PropertyInfo info = contextType.GetProperties().First(pi => pi.PropertyType == type);
    var body = System.Linq.Expressions.Expression.Property(parameter, info);
    dynamic func = System.Linq.Expressions.Expression.Lambda(body, parameter);

    context.SetupProperty<IDbSet<T>>(func, set.Object);

    return set;

With that method, all you need to do is the following:

IList<MyEntity> myEntities = new List<MyEntity>();

// add entities

this.SetupDbSet(myEntities, mydbContextMock):


With those two lines of code, you’ll have mocked data in your context wherever it’s needed and be able to easily get to the changes made to the dbset.


Posted On Thursday, November 20, 2014 4:06 PM | Comments (0) |

Working with Hardware

I’m working on a hardware project that involves software controlling motors, grippers and the like.  I can’t go into details on the project, but it’s quite a bit of fun.

I’ve learned a really important design principle for hardware interaction.  I’m sure some of you that have more hardware experience than I do will simply say, “duh”, but I had to learn the hard way.

In version one, I made good objects for all of the components and then tied them together into a single device.  They had base classes and such, good OO techniques.

It ended up being a pain in the kiester!  Who would have thought!

A far better pattern to follow is the Actor pattern.  Basically, you have a central state manager (ActorManager) that is responsible for giving each Actor (i.e. software addressable component) a chance to do its thing.

Each actor has access to a central state repository, and is responsible for writing it’s state to that repository as well.  If it cares about another component, it looks in state for the information it needs, otherwise it does its thing and moves on.

As an example, suppose you have three axis on a gantry (X, Y, Z), and these axis have to move in such a way that they don’t collide in their container.

With a top down approach, like the first revision, the device has to talk to x, y, and z and do a bunch of work to determine if they’re in a state where they can move, if they’re going to do something bad, etc.

With the actor pattern, if X needs to know if Z is in a good position, it looks in state for Z’s position.  If z isn’t in a good position, it does nothing, or if it’s in a good position, it moves.  Simple.  Y on the other hand, doesn’t care where Z or X are, so it can just move and does so.  Z is the same.  Simple.

Objects are still involved, they’re just much more loosely coupled.

Posted On Thursday, November 20, 2014 12:44 PM | Comments (0) |

Wednesday, November 7, 2012

Remote Desktop Connection Manager

For years, I’ve been using the “Remote Desktops” mmc plugin to manage servers in our infrastructure.  I’ve upgraded to Windows 8 and Remote Desktops is nowhere to be found!  I search and searched and came across a forum listing saying “Why don’t you just use Remove Desktop Connection Manager?”

I downloaded it and started using it and its WAY better than Remote Desktops!  I’m glad they took it out and I discovered this tool.  I wish I had discovered this two years ago!

Technorati Tags:

Posted On Wednesday, November 7, 2012 9:16 AM | Comments (2) |

Tuesday, October 23, 2012

Directory Synchronization

We’re using federated security with Office 365 and everything was running swimmingly and then I started getting the following error when trying to synchronize security information:

“An unknown error occurred with the Microsoft Online Services Sign-in Assistant. Contact Technical Support.”

Great.  Very descriptive.  In the event viewer, you get a bit more detail:

GetAuthState() failed with -2147186688 state. HResult:0. Contact Technical Support.  (0x80048831)

If you do some searching, you’ll find that there are a couple of MSDN articles about this error.  In KB2502710 you’re told to reinstall sign in assistant.  This one requires a reboot.  In KB2517393 you’re told to make sure that your proxy settings are working correctly.  I’m not using a proxy and everything was set up right.

Rather frustrating and I couldn’t figure out what was going on.  What finally keyed me in was the error number being presented.  Rather than 80048800, which is listed in the second article, I was getting 80048831.  I did a quick search and found something that was seemingly unrelated here.  Could it really be so simple as the password having expired for my synchronization user?

Turns out, it was that simple.  Once the password was reset and reentered, everything worked great again.

Since this isn’t a user that humans use, I also don’t want the password to expire.  You can find the instructions for that (use Set-MsolUser –UserPrincipalName <user ID> –PasswordNeverExpires $true) here.

Technorati Tags:

Posted On Tuesday, October 23, 2012 10:12 AM | Comments (2) |

Thursday, September 27, 2012

On iOS 6

“Introducing Windows ME, reimagined as iOS6 and by Apple!”

Remember, it just works, and when it doesn’t, you’re holding it wrong.

Posted On Thursday, September 27, 2012 10:56 AM | Comments (0) |

Thursday, August 16, 2012

Well That Was Fun (The wrong way to migrate mailboxes in Office 365)



First, I want everyone know know that this was a self-inflicted problem.  I thought I knew what I was doing, but really didn’t know.  I do wish that there were warnings letting you know you were about to ruin your life, but there isn’t, so this is an easy mistake to make.

Our company is moving to office 365 from Exchange 2010.  We want to keep a local on premise version for various reasons, so we’ve set up a hybrid exchange configuration.  We tested it by moving a couple of mailboxes over and everything appeared to be working great.

However, the person helping me quit his job at the company we were outsourcing our IT stuff to.  I thought I knew what he had done, but didn’t.

Here’s our configuration:

  1. Exchange 2010
  2. Office 365
  3. Federated Security for Single Sign On
  4. Active Directory Synchronization

The big mistake that I made was when we were ready to move mailboxes to the cloud, I used the Email Migration tool in the Office 365 Tenant Portal.  If you have a HYBRID exchange configuration with with active directory synchronization, DO NOT USE THE E-MAIL MIGRATION image BUTTON!!! You’ll be hosed if you do.  Instead, use the Remote Move Request feature of EMC or powershell.

Note that the pain will be somewhat mitigated if you leave your MX records pointing at your on premise server, since all mail will continue to be delivered to your on premise server.  However, if you moved it, like I did, you have more work.

Here’s some of the symptoms that you did the wrong thing:

  1. Archive folders (personal archives) don’t appear to have migrated.
  2. Users can log into both and access outlook AND your on premises OWA site, and both still work.
  3. Autodiscover sends people, seemingly at random, to your on premise server and to the office 365 servers.
  4. You have mailboxes for users on both your on premise servers and in office 365.

As soon as you realize what you’ve done, you’ll want to crawl under a rock and die.  There is NO easy solution.  After many hours on the phone with Microsoft Tech Support, here are the steps you need to take to recover:

  1. Ensure that you have Rollup 3 for service pack 2 installed on your on premises internet facing hybrid server.
  2. If you’ve moved your MX record, MOVE IT BACK! Smile  Seriously, you’ll have to send it back to your on premise server.
  3. If you moved your MX record, you’ll need to export all new mail that is in office 365 into PST’s.  THIS IS REALLY IMPORTANT!  YOU’RE ABOUT TO PERMENENTLY DELETE DATA! 
    1. To do this, grant a NON-FEDERATED user (and admin user) full access to the mailboxes.  You can do this using EMC’s Manage Full Access permission, or by using a powershell script to do the same.  You’ll need to create the user in office 365.
    2. Set up an outlook profile (I set up an entire VM) and connect it to the user in step one.
    3. Wait forever for the mail to synchronize down to the outlook profile (you probably want to avoid Cached Exchange Mode).  If you’ve got lots of mail, you’re going to have to do this in groups.
    4. Using outlook, export the new mail to a pst (file, open, import, export to file, outlook pst, select the top level mailbox, put a filter in, change the filename to the name of the mailbox, no password, export . . . and yes, that was from memory . . .)
      1. I’d name the file after the user whose mailbox you’re exporting
    5. After PST creation, create a new profile (control panel, Mail, Show Profiles) for an on premise user THAT DOES NOT HAVE A 365 MAILBOX.  Again, you’ll probably need to create the user.
    6. Import the PST’s into the appropriate location in outlook (File, import, import from a file, outlook data file (.pst), select the pst file to import, select the appropriate mailbox from the dropdown list).
    7. Wait forever for mail to sync (you’ll probably want to avoid Cached Exchange Mode).
    8. You’re done.  Wasn’t that fun?
  4. Next, deactivate active directory synchronization in the Office 365 portal and then wait for up to 72 hours for it to complete.  Yup, 72 hours . . . sucks to be you right now.  (It actually took about 7 hours.  I’m not sure if MS made it happen faster because I was already in the tech support queue or not)
  5. Once deactivation is complete, delete the offending users and mailboxes.  You may need to use the Remove-Mailbox powershell command in remote powershell to get rid of the offending mailboxes. (See the additional details below)
  6. Once the users are gone, turn Active Directory synchronization back on and synchronize.
    1. This may take up to 24 hours.
  7. Move the mailboxes the RIGHT way using EMC and Remote Move requests.

I’m at Step 4 right now.  If anything else exciting comes up, I’ll update this post.  I couldn’t find many posts on this “fun” so I thought I’d create one.  I guess others are just more experienced than I am. Smile



So step 5 needs way more detail.  After several more hours on the phone with Microsoft Support, we ended up doing the following to get rid of the bad mailboxes:

Did I mention that by following these steps you’re going to lose data if you don’t have it backed up?

  1. Remove the mailboxes using whatever means you desire (powershell, whatever, doesn’t really matter), which will also delete the users from the system
    1. At this point, you can still recover the users.  If you turn on ADSynch, the users will recover and be re-associated with the deleted mailboxes, which leaves you back where you started.
  2. Using remote powershell for microsoft online, get a list of all online users using the get-msolUser | fl DisplayName, ObjectId command
  3. One by one, delete the users from office 365 using Remove-MSOLUser –ObjectId {Guid from step 2}
    1. If you don’t want to permanently delete your users, you’ll need to get to the operations level at Microsoft.  Yeah, not much you can do about it.
  4. Once the users are deleted that have the duplicate mailboxes, flush the recycle bin using the following command:  Get-MsolUser –ReturnDeletedUsers | Remove-MsolUser –RemoveFromRecycleBin –force
  5. Once this is done, re-enable active directory synchronization, synchronize and your done.  Easy, no?


This link might be helpful.  It talks about how to delete a user even with ADSynch turned on.


BIG Props to FP from Microsoft Support.  Without him I’d have been sunk!

Technorati Tags:

Posted On Thursday, August 16, 2012 8:54 AM | Comments (0) |

Wednesday, July 11, 2012

Reading Credit Card Data from a MagTek Card Swipe Device

Sometimes as developers we’re spoiled by third parties that do a lot of the heavy lifting for us.  However, sometimes we’re NOT spoiled and we have to get our hands dirty.

Today, I spent much of the day getting my hands dirty.  I’m working on a project that uses a MagTek credit card swiper and all MagTek provides you in terms of dlls is a c++ dll and an ActiveX dll.  What fun is that?  I wanted to avoid com interop (no, I don’t have a good reason) and write a C# class that handled talking with their C++ dlls directly.

This ended up being a good lesson in P/Invoke and how to deal with unsafe (I’m guessing strcat) code in a dll that I don’t control.

1207 lines of code (and comments) later, I have the final result completed.  I’m not going to post the entire post, since it would be WAY to long, but here are the key bits:

Here’s the dll imports you’ll need:

/// <summary>
///   Clears the data buffer
/// </summary>
private static extern void MTUSCRAClearBuffer();

/// <summary>
///   Opens the MTUSCRA Device
/// </summary>
/// <returns> A uint that is an <see cref="ErrorValuesEnum" /> </returns>
private static extern uint MTUSCRACloseDevice();

/// <summary>Gets the card data from the reader.</summary>
/// <param name="cardData">The card data structure for holding the card information. </param>
/// <returns>A uint that is an <see cref="ErrorValuesEnum"/> </returns>
private static extern uint MTUSCRAGetCardData(ref MTMSRDATA cardData);

//// This has been removed because it requires unsafe code.
/////// <summary>Gets the card data delimited by the provided string.</summary>
/////// <param name="data">The string result that will be sent back. </param>
/////// <param name="delimiter">The delimiter for the string </param>
/////// <returns>A uint that is an <see cref="ErrorValuesEnum"/> </returns>
////private static extern unsafe uint MTUSCRAGetCardDataStr(byte* data, string delimiter);

/// <summary>Opens the MTUSCRA Device</summary>
/// <param name="deviceName">The name of the device to open </param>
/// <returns>A uint that is an <see cref="ErrorValuesEnum"/> </returns>
private static extern uint MTUSCRAOpenDevice(string deviceName);

/// <summary>Opens the MTUSCRA Device</summary>
/// <param name="command">The command to send </param>
/// <param name="commandLength">The length of the command sent. </param>
/// <param name="result">The result of the command </param>
/// <param name="resultLength">The length of the result. </param>
/// <returns>A uint that is an <see cref="ErrorValuesEnum"/> </returns>
private static extern uint MTUSCRASendCommand(string command, uint commandLength, ref string result, ref uint resultLength);

/// <summary>
/// Raised when the card state data changes.
/// </summary>
/// <param name="callBack">The call back for card data state changing.</param>
private static extern void MTUSCRACardDataStateChangedNotify(CardDataStateChangedCallBack callBack);

/// <summary>
/// Raised when the device state changes
/// </summary>
/// <param name="callBack">The call back for card data state changing.</param>
private static extern void MTUSCRADeviceStateChangedNotify(DeviceStateChangedCallBack callBack);

/// <summary>
/// Gets the current device state.
/// </summary>
/// <param name="deviceState">The device state</param>
private static extern void MTUSCRAGetDeviceState(ref uint deviceState);

/// <summary>
/// Gets the current data state.
/// </summary>
/// <param name="dataState">The data state</param>
private static extern void MTUSCRAGetCardDataState(ref uint dataState);

/// <summary>
/// Gets the cproduct id of the card reader.
/// </summary>
/// <param name="productId">The product id</param>
private static extern void MTUSCRAGetPID(ref uint productId);

You’ll need a couple of delegates as well:

/// <summary>
///   A delegate for handling the card data state callback.
/// </summary>
/// <param name="dataState"> The data state </param>
private delegate void CardDataStateChangedCallBack(uint dataState);

/// <summary>
///   A delegate for handling the device state callback.
/// </summary>
/// <param name="deviceState"> The device state </param>
private delegate void DeviceStateChangedCallBack(uint deviceState);

And then you’ll want to wire those up like so:


this.CardDataStateChanged = new CardDataStateChangedCallBack(this.OnCardDataStateChanged);
this.DeviceStateChanged = new DeviceStateChangedCallBack(this.OnDeviceStateChanged);


And finally, you’ll want the Struct that you’ll need to use to get the card data:

public struct MTMSRDATA
    /// <summary>The default data size for tracks.</summary>
    private const int DEF_MSR_DATA_LEN = 256;

    /// <summary>The card data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN * 3)]
    public string m_szCardData;

    /// <summary>masked card data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN * 3)]
    public string m_szCardDataMasked;

    /// <summary>Track 1 Data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szTrack1Data;

    /// <summary>Track 2 data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szTrack2Data;

    /// <summary>Track 3 data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szTrack3Data;

    /// <summary>Masked track 1 data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szTrack1DataMasked;

    /// <summary>masked track 2 data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szTrack2DataMasked;

    /// <summary>masked track 3 data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szTrack3DataMasked;

    /// <summary>MagnePrint data.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szMagnePrintData;

    /// <summary>Card encode type.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szCardEncodeType;

    /// <summary>MagnePrint Status.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szMagnePrintStatus;

    /// <summary>DUKPT Session ID.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szDUKPTSessionID;

    /// <summary>Device Serial Number.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szDeviceSerialNumber;

    /// <summary>DUKPT Key Serial Number.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szDUKPTKSN;

    /// <summary>First Name from Track 1.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szFirstName;

    /// <summary>Last Name from Track 1.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szLastName;

    /// <summary>PAN from Track 2.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szPAN;

    /// <summary>The Expiration Month.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szMonth;

    /// <summary>The Expiration Year.</summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DEF_MSR_DATA_LEN)]
    public string m_szYear;

    /// <summary>Reader product ID.</summary>
    public uint m_dwReaderID;

    /// <summary>MagnePrint length.</summary>
    public uint m_dwMagnePrintLength;

    /// <summary>MagnePrint Status.</summary>
    public uint m_dwMagnePrintStatus;

    /// <summary>Track 1 data length.</summary>
    public uint m_dwTrack1Length;

    /// <summary>Track 2 length.</summary>
    public uint m_dwTrack2Length;

    /// <summary>Track 3 length.</summary>
    public uint m_dwTrack3Length;

    /// <summary>Track 1 length masked.</summary>
    public uint m_dwTrack1LengthMasked;

    /// <summary>Track 2 length masked.</summary>
    public uint m_dwTrack2LengthMasked;

    /// <summary>Track 3 length masked.</summary>
    public uint m_dwTrack3LengthMasked;

    /// <summary>Card encode type.</summary>
    public uint m_dwCardEncodeType;

    /// <summary>Track 1 decode status.</summary>
    public uint m_dwTrack1DcdStatus;

    /// <summary>Track 2 decode status.</summary>
    public uint m_dwTrack2DcdStatus;

    /// <summary>The m_dw track 3 dcd status.</summary>
    public uint m_dwTrack3DcdStatus;

    /// <summary>Card swipe status.</summary>
    public uint m_dwCardSwipeStatus;

Hopefully, this will help you get started and will save you some time.  I know it would have saved me quite a bit!

Good luck!

Technorati Tags: ,,

Posted On Wednesday, July 11, 2012 5:25 PM | Comments (4) |

Monday, July 2, 2012

Easy Scaling in XAML (WPF)

Ran into a problem that needed solving that was kind of fun.  I’m not a XAML guru, and I’m sure there are better solutions, but I thought I’d share mine.

The problem was this:  Our designer had, appropriately, designed the system for a 1920 x 1080 screen resolution.  This is for a full screen, touch screen device (think Kiosk), which has that resolution, but we also wanted to demo the device on a tablet (currently using the AWESOME Samsung tablet given out at Microsoft Build).  When you’d run it on that tablet, things were ugly because it was at a lower resolution than the target device.

Enter scaling.  I did some research and found out that I probably just need to monkey with the LayoutTransform of some grid somewhere.  This project is using MVVM and has a navigation container that we built that lives on a single root view.  User controls are then loaded into that view as navigation occurs.

In the parent grid of the root view, I added the following XAML:

            <ScaleTransform ScaleX="{Binding ScaleWidth}" ScaleY="{Binding ScaleHeight}" />

And then in the root View Model, I added the following code:

/// <summary>
/// The required design width
/// </summary>
private const double RequiredWidth = 1920;

/// <summary>
/// The required design height
/// </summary>
private const double RequiredHeight = 1080;
/// <summary>Gets the ActualHeight</summary>
public double ActualHeight
        return this.View.ActualHeight;

/// <summary>Gets the ActualWidth</summary>
public double ActualWidth
        return this.View.ActualWidth;

/// <summary>
/// Gets the scale for the height.
/// </summary>
public double ScaleHeight
        return this.ActualHeight / RequiredHeight;

/// <summary>
/// Gets the scale for the width.
/// </summary>
public double ScaleWidth
        return this.ActualWidth / RequiredWidth;

Note that View.ActualWidth and View.ActualHeight are just pointing directly at FrameworkElement.ActualWidth and FrameworkElement.ActualHeight.

That’s it.  Just calculate the ratio and bind the scale transform to it.

Hopefully you’ll find this useful.

Update (7-2-2012):

Note that I tried a ViewBox before, but it didn’t work because of the navigation.  Basically, we needed the following structure in the grid:

                        <ColumnDefinition Width="1920"/>
                        <ColumnDefinition Width="1920"/>
                        <ColumnDefinition Width="1920"/>

The first column is the Last Screen.  The second column is the Currently displayed screen, and the last column is the “Next” screen.  When moving next, the “next” screen is loaded into the last column, then the animation is fired to slide in the screen, and then the current panel has the current view replaced and is refocused without animation.  Navigating back is similar in flow.

The total screen space isn’t consumed by the navigation grid.

When using a ViewBox, the entire 5760 pixels are compressed into the available screen space.  A picture would make this more clear, but I can’t show that without revealing stuff you shouldn’t know. Smile

Basically, I needed a single column of the grid to be scaled, not the entire grid, which is what my solution does, where the viewbox attempts to scale everything.

Make sense?

Technorati Tags: ,

Posted On Monday, July 2, 2012 4:29 PM | Comments (3) |

Wednesday, March 21, 2012

Why I LOVE Dell

We recently ordered a laptop for an employee.  It was delivered yesterday and we realized it had no web cam and wasn’t the 1080p resolution.  He wasn’t happy.

So, this morning, I sent an e-mail to our rep and asked him what we could do.  Within an hour or two, he called me, arranged a replacement laptop with the corrected specs, set up a return and had everything arranged and charged us only for the difference.  No pain, no silly questions.  We won’t loose use of the laptop either.  The return and the new laptop will overlap so that we can just pack up the old laptop in the box of the new one, slap some labels on and away we go.

This has been my experience with Dell over the past 10 years.  Their corporate service has always been fantastic, and it’s made me a huge fan.  Keep up the good work, Dell!

Technorati Tags:

Posted On Wednesday, March 21, 2012 11:21 AM | Comments (3) |

Tuesday, February 21, 2012

Converting Hyper-V to VMWare

Our company is standardizing on VMWare for a number of reasons.  I won’t list them here, but wanted to write about a problem that I had using VMWare Standalone Converter version 5.0 to convert Hyper-V virtual machines.

There were four problems:

  1. The converter needs to be run as an administrator
  2. You have to be connected to localhost or you’ll be prompted to install the standalone agent first
  3. Domain credentials don’t work as expected
  4. You need to give explicit permissions to Everyone the directory where the virtual machines are stored

Running as an Administrator

The first problem is the easiest to figure out what’s going on.  Basically, when you run it, you get the error:  A general system error occurred:  Crypto Exception: error:02001005Confused smileystem library:fopen:Input/output error:unable to load C:\ProgramData\VMWare\VMware vCenter Converter Standalone\ssl\rui.crt


Easy to fix, just run as an administrator.

Connect as LocalHost

If you try to connect to the full domain name of the machine when you’re running the converter from the hyper-v machine, you’ll be prompted to install the Standalone agent, which will promptly fail because another version is already installed.  It’ll look something like this:


The fix to this is easy to.  Just connect as localhost.

Domain Credentials Don’t Work

This one is tougher to figure out because basically, you get no help understanding what the problem is.  What happens is that you’re able to connect to Hyper-V and see a list of the machines, but when you select ANY machine on the server, you get the error:

Unable to obtain hardware information for the selected machine. 


This one is a pain.  Basically, the solution to this is to create a new local user and make them part of the Administrators group.  Then, you’ll need to log in on the machine using that user name and use that user name for the permissions when connecting to the Hyper-V.

Once you’ve done that, you’ll think that you can get past this error, but then you run into issue #4.

Changing the Directory Permissions

In our case, our vms were stored in f:\VirtualMachines.  You’d think that a domain admin/admin would have the ability to read information from anywhere but something that the standalone converter is doing prevents it.  You’ll get the same error as above in #3.  The fix to this is to make sure that “Everyone” has full control permissions to the directory where your files are stored and all of the sub directories.  I also did the same through the share, but I’m not sure if that was needed or not.


After addressing all of these items, we’re converting quite happily.  Hopefully, this will help you as well.

Technorati Tags: ,

Posted On Tuesday, February 21, 2012 6:24 PM | Comments (2) |

Powered by: