Monday, August 30, 2010

First Steps with Windows 7 Unattended Installation

We use nLite to customize our Windows XP Professional installations, including slipstreaming of service packs and adding drivers, but most importantly for Windows Unattended Installation. With several dozens of computers to deploy in a very short period of time at the beginning of each season, we needed a solution to reduce human intervention and error.

While we are still waiting on hardware drivers to make a full migration, we are beginning to deploy Windows 7. Because of my familiarity with nLite, I have started with vLite to create a similar unattended solution for Windows 7. I achieved some level of success my first afternoon; however, I am already debating its continued use since vLite was designed for Vista, is no longer being developed, and has hit limitations for some Windows 7 configurations. I will be evaluating alternatives shortly.

What our unattended configuration does:
  • Wipes the primary hard drive, partitioning the entire disk as one primary partition, formated as NTFS
  • Configure US/English locale settings and Pacific Standard Time timezone
  • Set the local Administrator account password
  • Set a temporary computer name
  • Join the Active Directory domain
  • Run unattended software installation scripts (Still to-do)
I copied the contents of our Windows 7 Enterprise DVD to my hard drive, ran vLite, and rebuilt the image. My first struggle was getting vLite to start, and then I also ended up with several "CD frisbees" from a couple of gotchas. So some noteworthy items:
I found Technet's Unattended Windows Setup Reference useful in customizing our Autounattend.xml. Make sure you maintain this file outside of the vLite image because vLite will replace it if you rebuild. Just copy your version in after building the image, but before burning a CD or creating an ISO.

My Autounattend.xml is available for reference, in the public domain, here. I have stripped out all sensitive information, so you will need to replace data in brackets with your own. I want to stress using this configuration WILL WIPE YOUR DATA AND PARTITIONS, so use at your own risk and create backups before installing. Enjoy!

Thursday, August 26, 2010

Emailing Promo Codes

In my last post, I explained our automatic promo code solution used for our pass referral program. The SQL stored procedure creates discount codes in your RTP|One database. It is run every minute by SQL Agent. The table PassReferralDiscount was created in a custom, resort-specific database to store our settings outside of the RTP|One.

The next step is to email the guest their referral code using the script emailPassReferral.vbs. It was written in VBScript because it is available with Windows Server by default, so no additional prerequisites. While VB Script is not ideal for large projects, it seemed like a good fit for the small task at hand. Also, a forewarning to the VB Script militants out there: I'm not a fan of Hungarian notation so I hope reading my code doesn't scar your retinas. The script looks up the name and email address of those who have not been emailed, sends the email, and updates the email indicator flag If someone wants it resent, just reset the flag back to 0. You will want to modify the database and mail settings before running.

It sends email using the file emailPassReferralTemplate.html stored in the same directory as the script, with rudimentary variable replacement. Example:

Hi [$First Name$],

Thanks for your purchase. Your pass referral code is: [$Promo Code$]

I left out HTML tags and formating for brevity's sake. The script is run every 5 minutes from Windows Task Scheduler. Download the source code for emailPassReferral.vbs.

Calculate Customer Age by Fixed Date bug in RTP|Online eStore

There is a bug in RTP|Online eStore 2010.1.x if you are using RFID reload and the Product Header rule "Calculate Customer Age by Fixed Date". Instead of calculating a customer's age using the fixed date in the Business Unit Configuration Settings, it is using today's date. If you have age restricted products with this rule, it could result in unfair/inconsistent service to your guest and/or loss revenue if your pricing scales as age increases.

This problem is scheduled to be fixed in 2010.2. In the meantime, I have written a SQL query to report customer codes that meet the bug criteria so their sale can be corrected. You will need to change the @FixedDate and @TranStartDate (Transaction Start Date) variables in the script file to match your settings. This assumes you only have one Business Unit. You will need to make additional JOINs for the Sale Location and Business Unit if you have more than one. Download the source code for getReloadEligbilityAgeCalculationErrors.sql.

Wednesday, August 25, 2010

Automatic Generation of Promo Codes in RTP|One

We have a cool program for renewing pass holders at Stevens Pass to refer new pass holders (who receive significant savings off the rack rate) and cash-in on prizes when their referral code is used. You can learn more about the referral program here.

Implementing this in RTP's resort management software RTP|One required custom development despite its vast capabilities. In this posting, I provide the stored procedure that automatically generates discount (a.k.a promotional, promo, or referral) codes.

If you do not use RTP|One, it may be a useful example of the following:
  • Transact-SQL language syntax
  • Microsoft SQL Server store sprocedures
  • INSERT INTO using SELECT with JOIN
  • Sub SELECT using the IN keyword
  • Use of IF EXISTS keyword
These techniques help avoid the use of cursors and iterators, improve performance and code manageability. I also avoid locking any RTP database tables to avoid interference with their software. If you are an RTP|One user, some limitations to consider:
  • Only transactions are checked, not orders, because we auto fulfill season pass renewals
  • The discount is setup as a Product Header discount, not LOB
  • No override accounting or prompts are configured
  • Compatible with RTP|One Release 2010.1 or above
  • Use at own risk!
The stored procedure is licensed under the GPL, so many limitations can be overcome with additional work and modification. What the procedure does:
  • Checks transaction line items for the sale of a renwal pass that need a corresponding discount code generated. You will need to update the Display Group Category Codes to match Product Headers that should be checked.
  • Uses a template discount as a clone to automatically generated new discount codes. You will need to create your template discount and update the template Discount Code.
The Discount Code is created in the format PRP-2010-11-[Customer IP Code] where PRP stands for "Pass Referral Program", 2010-11 is the year, and [Customer IP Code] is the unique, renewing customer code.

The promotional information is stored in a table "PassReferralDiscount" in a resort specific database called "Stevens". You will want to update this to your own and create the following table:
CREATE TABLE PassReferralDiscount (
IPCode INT NOT NULL,
DiscountCode NVARCHAR(255) NOT NULL PRIMARY KEY,
EmailedInd BIT NOT NULL,
UpdateDate DATETIME NOT NULL
)
This table allows us to track discount creation and emails to customers. The procedure is run once every minute and typically finishes within 0-1 seconds. In my next post, I'll discuss how to email automatically email customers their discount codes using a template.

Extend Windows Boot Partitions With diskpart

An old Windows 2003 Server installation was running low on disk space on the C: drive. Oddly the partition was only using 15 GB of an 80 GB disk. An attempt to extend the partition would result in the following error:

Diskpart failed to extend the volume. Please make sure the volume is valid for extending

Commercial software is capable of getting around this issue, but it turns the Bart PE disc I made for aligning boot partitions in a previous blog post was the quick and inexpensive solution to my problem. Note, that the free space must be on the same drive and the next contiguous space to your partition for this to work. Anyway, I booted from the BartPE disc, ran diskpart, and selected the boot volume to extend:

list volume
select volume 2
extend

I rebooted from the hard disk and all is well... 65% unused!


Sunday, November 22, 2009

Understanding technology != successful technology

Geeks. Nerds.

I do not need to paint much of mental picture for you to know exactly who I am talking about. While fashion sense, hygiene, and social skills are on the list of what we typically lack, it is the latter that really hurts our profession. As our industry matures, I believe having technical qualifications are not going to be good enough, and consider the inability to communicate and understand people and behavior is what makes IT fail for many businesses. In the title of this blog, I illustrate with the simple example "!="... easily recognizable by programmers as "does not equal", but likely creates an immediate disconnect for others. It is simple things like this that cause break down between IT and the rest of the company.

We just opened the resort for 2009-10 season. After a successful implementation of the RTP and SKIDATA RFID gate solution last year, and returning with the same success in our sophomore year, I was reflecting on our work with a system that impacts nearly every department of our operation, and noticed while understanding the technology was a key factor, understanding people and our business was just as significant. If your technology is falling short, some things you may want to consider:

1) Buy-in - Even the best of systems will not work if you cannot or have not effectively communicated to the true value of technology. If the people using it cannot visualize the potential, they will not use it. Trying to gain buy-in after it has already failed will be an uphill battle, likely viewed as strong arm tactics. Although, you will have to reiterate the value to keep people focused on the future... technology is an investment, and may not have the immediate or instant gratification our human nature desires.

2) Listen - Learn how to really listen to people. Ask questions, listen to them, then develop and communicate your ideas. Then listen to their feedback. Keep doing this until everyone is on the same page. While it may seem like a lot, if you do not have time to do it right, you will not have the time to do it over. Plan to spend as much time talking as you do implementing.

3) Talk - Instead of just requesting that people or departments get thing in queue, and relying on them to do this, also try going around and just talking to them. Do not get me wrong, request tracking/ticketing systems are great and I use one myself, but people are people... they do not want to burden IT departments with more work, do not trust technology or us because we are associated with it, and will forget to put their request in. In talking to them you help build trusting business friendships, learn of opportunities to make things easier/better, remind them to get routine requests in queue, and avoid them waiting until an issue festers to the point of complete frustration and/or absolute emergency.

Sunday, November 15, 2009

The Best Thing You Can Do to Keep Kids on Shred

I have had a busy week getting our resort ready to open, and as I sit and think about what IT wizardry or kung-fu I want to impress you with first, what is on the forefront of my mind is just life. Do not worry, I will have plenty of 0s and 1s to discuss another day, but prepare for me to get emo because I want to talk about the best thing you can do to keep kids on shred.

Part of the mountain culture is the connection we experience with family and friends... skiing and riding is a common family tradition with good reason. We all have family, and we are all connected, so I do not say this to just parents, or people shredding the mountain, but to everyone, no matter who you are or what your shred is.

I do not need to belabor you with how messed up our world is today, and how we have long forgotten what is truly important, and how easy it has become for it to slip away from us. I have worked and loved hard to have a home and a family, to come home to bright eyes, smiling faces, laughter, hugs, and love. Most days my reality is far from this... my apartment is empty, alone, and so quiet I can hear the clicking of the electric baseboard heaters. Am I angry, frustrated, and hurt? You bet! Family law, originally designed to prevent deadbeat parents and help children, is old and archaic, and more frequently is used to inflict hurt by hurting parents, joint custody is more like a cruel joke than a reality, and visitation is just that... visiting. We complicate our lives with work, problems, and stress that should not matter, and hurt and destroy families in the process. When you feel alone, helpless, and at your end, please do not stop loving and doing the right thing regardless of what others do. Your family needs it, and your kids need it.

If we slow down, get rid of the distractions and noise of life, I believe we all know deep within our hearts what the answers to life are. Do not let the fear of the unknown, the path you cannot map out, prevent you from doing this. Take one day at a time, trust, and know that the next step will present itself at the appropriate time. Doing what is right will always give you this, so be open to it. It may not make sense to even the closest of friends and family, but the rewards and respect you earn are not instant, self gratification, but an investment that pays later.

It is a struggle being a parent on your own sometimes, and while it may not come to me intuitively that painting my daughters nails will make her day, all she is looking for me to do is try... so I will talk in a high pitched voice with Polly Pockets and My Little Ponies. I will spend time with her reading, playing games, making good food, and yes, skiing. I cannot give her the life that I once dreamed, but I can try to give her a very good one. It is all worth it when you hear that soft, scratchy voice say "Put your arm down here so I can touch it. I will make you very very happy" or simply "I love you daddy."

So what is the best thing you can do? Love. Show support to your family regardless if you have kids. Be a good parent. And don't give up... never give up.