Migrate Mindtouch to Hyper-V

My Mindtouch Core wiki VM was originally running on VMWare server a long time ago. I needed to migrate this to Hyper-V so that I could decommission my use of VMware.

I originally wrote this post more than 2 years ago, but am publishing it now in case someone finds it useful.

 

Used vmdk2vhd to convert the disk to VHD file.

After transferring and booting, it failed.

Used these instructions to assist in fixing: http://itproctology.blogspot.ca/2009/04/migrating-debian-from-vmware-esx-to.html

mount -t ext3 /dev/hda1 /root

vi /root/etc /fstab

change sda1 to hda1

vi /root/boot/grub/menu.lst

change sda1 to hda1

Then added a Legacy Network adapter

Then followed these instructions to install Hyper-V integration services

http://www.r2x2.com/install-hyper-v-integration-services-on-debian-5-x/

Autodesk 2014 deployment

One of the other major deployments I’ve done recently has been a refresh of all our Autodesk products to the 2014 version. In scope this was smaller than my Office 2013 deployment, however it was much more complicated.

 

First, I created Active Directory groups to contain the computer accounts of workstations needing a product. For example, a group for AutoCAD 2014 Network license containing computer accounts that required it for installation.

These groups were then targeted with Group Policy Objects which set a scheduled task to run the installation script at 3:00am. Due to the size of the installation, I don’t want to have this run as a startup script.
Next I needed to create the installation script.

To start, I created an Autodesk deployment through Setup.exe. This is typically how standardized installations of Autodesk products are performed, but usually aren’t enough to have a user fully set up.

I began with a deployment of Infrastructure Design Suite Premium (IDSP) since it was 40GB and contained the install files for every ‘lower-tier’ product we were going to install. This way you can use a single source of installation files but multiple configured deployments.

Once the deployment package was created, I put it into a VBS script with a WHOLE lot of other logic.

My installation script can be downloaded here: AutoCAD_2014_Network_Install(rename to .vbs)

The Uninstall Products script can be downloaded here: UninstallProducts(rename to .vbs)

The Copy Fonts script can be downloaded here: CopyFonts(rename to .vbs)

 

The script can be summarized as follows:

  • Check default gateway on the NIC, and if matching branch offices change the install source
  • Check for the acad.exe file in the installation directory, and proceed if it doesn’t exist yet
  • Run the UninstallProducts script to remove previous versions of software
  • Run the Autodesk deployment through the .lnk file created from Autodesk setup.exe
  • Begin a loop which checks for setup.exe in the running processes.
    • Wait 2 minutes before proceeding with the loop
  • Once setup.exe is no longer running, continue by deleting unnecessary shortcuts
  • Add extra shortcuts that point to a specific ARG file for customizations
  • Install additional programs (AcroPlot PDF software in this case)
  • Run the CopyFonts script, passing in the Fonts path for this particular product
    • This copies required fonts to C:\Windows\Fonts and the installation directory
  • Check again for acad.exe, and if it now exists then log success, otherwise log failure.

 

 

 

Office 2013 Deployment

office_logoMy company is now utilizing Office 365 for it’s email and Office products, and for a variety of reasons there was a need to mass upgrade to Office 2013.

Our parent company from a recent acquisition handles it’s deployment in a way that doesn’t meet our requirements, since it is user-based rather than computer based which we require.

 

There were a few things we had to define for this to be a successful project:

  • Installation must run under admin privileges (which our users do not have)
  • Ideally, installation should not interrupt or delay a user, but if necessary it is acceptable
  • Install source should be dynamic to allow for different branch locations
  • Success or failure should be logged to a central file

 

Based on the above, I came up with a combination of scripts which are reproduced below.

Overall the project was a success, with the only major issue being users not reading instructions (even openly admitting this fact) which caused a huge increase in IT Support requests.

 

1. Group Policy Objects

I set up two GPO’s to perform two separate functions:

  • One to create a Scheduled Task that runs once at 3:00am, executing the install script
  • One to execute the install script as a Startup Script under the Computer Configuration settings for all workstations in our area of AD

Using this method, any computer powered on at deployment date would receive Office 2013 at 3:00am without user interruption, and any other computer after that would receive it at startup. The majority of our staff working in an office were not interrupted, and our field staff would all receive the software eventually.

 

2. Installation Script

My commented installation script can be downloaded here: Office2013InstallStatus (rename to .bat)

In essence, here is what it does:

  • Begin by defining location variables that will apply to all PCs by default
  • Check matching NIC gateway addresses for offices without an Apps repository and overwrite the location variables if necessary
    • This will ensure that all installation files come from a local source
    • Note that the LogFile variable is not changed; central to all installations
  • Next a check occurs for Office 2013 installation
    • If this returns true, the script will exit without further action
  • If Office 2013 isn’t already installed, installation will begin
    • First write a registry entry on the PC which can be referenced by the Install Status Script (see below) if the user happens to log on during installation
    • Uninstall Office 2010 (a straight upgrade has been known to cause problems)
    • Uninstall Office 2013 (this will apply to PCs which had ONLY Lync installed)
    • Install Office 2013
    • Write result to a Log File
    • Reset the registry entry of installation status to signify end of installation
    • Exit script

 

3. Install Status Script

Because many of our installations would take place at computer Startup (the second GPO) and it would be possible for users to log onto the computer before the installation is completed (because Windows 7 doesn’t run startup scripts synchronously), I needed a way to tell the user not to open Office products while the installation was running.

My status script can be downloaded here: Office2013StartupScript (rename to .vbs)

This script is placed within all users Startup folder in the start menu, and performs the following:

  • Read the InstallingStatus value from the registry which would be set by the Office2013StartupScript.bat script
  • If the Status = 0, exit the script. If it = 1, begin a Do loop
  • While in the loop, check for the status of the registry key again
    • If Status = 1, display the HTA application. This has a timeout of 5 minutes, after which the loop will resume
    • If Status = 0, the loop ends and a final message is displayed to the user

One problem we did encounter (which isn’t really resolved yet) is that occasionally the Office 2013 installer would auto-reboot. When this occurred, it interrupted this status script, causing the “installingStatus” flag to remain active. On the next reboot, the Status window would re-appear even though no installation was taking place.

 

4. Install Status Window (HTA)

The HTA file I’m using to display to the user, called from the Status Script, can be downloaded here: Office2013_message(rename to .hta)

 

 

 

Web development is a lot like building LEGO

IMG_9831I am by no means a “web developer“, however I have spent a significant amount of my time this year building web applications for my company.

I am by no means a “lego designer“, however I have spent a significant amount of my time this year building whatever my son asked me to build.

Through these two experiences I have learned that they are both very similar.

 

It starts with an idea; something that catches my attention, something useful or productive, or just fun.

From there I begin building, but rarely is the building linear. A piece here, a piece there, a section at a time, the building begins.

Building takes time, and during that time I always come up with enhancements and ways to make it better. The scope changes and grows but it is usually for the better.

Of course, even when the project is incomplete, I start thinking about how it looks. I smooth out the rough edges, inspect the symmetry, and makes sure it moves the way I want it to.

Eventually I begin looking at security; making sure the project won’t break, or be broken into. I test it again and again, and I get other people to look at it.

 

I take a lot of joy knowing that I’m creating something. That’s a little different than a typical System Administrator responsibility, and it is something I’m thankful I have the opportunity for. Whether it’s a line-of-business application that will be used by my entire company, or a 2 foot robot my 5 year old will play with for 30 minutes before destroying; it is a lot of fun.

Lightswitch – Query where no match exists in reference table

I’m building an internal IT inventory application in LightSwitch, and have been trying to add a screen that only shows software in the inventory that has not been assigned to hardware.

Lightswitch doesn’t allow the graphical query editor to select the “many” side of a relationship on a filter (as documented here), so this is something that must be done in code.

I struggled for a bit trying to make a Left Outer Join in Linq between my two entities, but eventually stumbled upon a post by the always helpful Yann Duran:

http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/664454f7-0b2e-409e-b57c-625180132c53/

What I needed was the C# syntax for his suggestion, which is reproduced here with my relevant entity name:

query = query.Where((a) => a.itinv_SoftwareAssignedHardwares.Any() == false);

This is created within a query on the itinv_Software entity.