My Blog

Blog

View All Posts In My Blog »


Jupiter Chevrolet: How not to sell a car

1.03.2012 | 0 Comments

This is the chat log I had today with Francisco Oguntosin at Jupiter Chevrolet in Garland, Texas. Take notes kids, this is the way to lose a customer and wind up on the internet.

Jupiter Chevrolet Inc : Thank you for choosing Jupiter Chevrolet Inc !
System: We have alerted the online representatives that you are waiting. Someone should be with you momentarily.
System: A representative has joined the conversation. Compose your message below and then click Send.
Francis Oguntosin : Hello, How may I help you?
You: Hi there. I’ve sent a couple emails today about your Chevy Cruze inventory
You: I’m about ready to make a decision and purchase today and there are a lot of competitive offers.
Francis Oguntosin : great
You: Can you get me out the door for $14,500 on the silver 2011 LT?
Francis Oguntosin : best deal is $14.600 plus TTL
You: OK. I’ve already got that deal with only 8k miles on it from another dealer
Francis Oguntosin : are you still there
You: yes. on the phone with another dealer
Francis Oguntosin : this is an LT
You: yes
Francis Oguntosin : that is a great price for $14,900
You: It is. I assume you are talking about Autohause listing, but I’m talking with a different dealer who is competitive with your offer, has lower miles and is dealer certified
Francis Oguntosin : we do have a life time warranty (powertrain warranty)
You: Yeah, I’m going to have to go take a look at those other two cars unless you can do something for me to get the price down or find some upgrades or something.
Francis Oguntosin : i can asure we are not going to miss your business.
You: I don’t imagine that you will. That’s a pretty poor attitude to have with a potential customer, especially when you’re doing it in writing.
You: If you haven’t heard of Ocean Marketing, you might want to Google it. It’s a cautionary tale of another customer service rep who shot his mouth off on the internet


Haystack: an IndexTank client for CodeIgniter 2.0+

9.29.2011 | 0 Comments

IndexTank is a hosted search solution used by some of the largest sites on the web such as Reddit, Twitvid and ZenCoder. It offers some cool features such as Geolocation, fuzzy search, autocomplete, “Did you mean” spelling correction, stemming and most importantly, real-time indexing.

It’s a pretty cool service, and did I mention that it’s free to index up to 100,000 documents?

The only problem is that there wasn’t a PHP client available for the CodeIgniter framework, until now.

Haystack is a PHP client offering basic interaction with the IndexTank API, implemented as a CodeIgniter library. It is very much a work in progress, and as I wrote it primarily for use in my current project, it is not as general as it could be. I will be maintaining the library on Github and will continue to add new functionality and improvements as time allows.

You can download the library from my Github repository.

Basic Usage

Selec All Code:
class Search extends CI_Controller
{
     $this->load->library('Haystack');
 
     // Create a new index
     $this->haystack->create_index('cars');
 
     // Set the index to work with for the next one or more IndexTank API calls
     $this->haystack->set_index('cars');
 
 
     // Add a single document to the currently selected index
     $docid = 1;
     $fields = array(
          'text' => 'The Chevrolet Impala is a full-size automobile built by the Chevrolet division of General Motors introduced for the 1958 model year.',
     );
 
     $this->haystack->add_document($docid, $fields);
 
 
     // Add multiple documents to the currently selected index
     $docs = array(
          array(
               'docid' => 1,
               'fields' => array(
                    'text' => 'The Chevrolet Impala is a full-size automobile built by the Chevrolet division of General Motors introduced for the 1958 model year.'
               )
          ),
          array(
               'docid' => 2,
               'fields' => array(
                    'text' => 'The Ford GT is a mid-engine two-seater sports car. Ford Motor Company produced the Ford GT for the 2005 to 2006 model years. The designers drew inspiration from Ford\'s GT40 race cars of the 1960s.'
               )
          )
     );
 
     $this->haystack->add_documents($docs);
 
 
     // Delete a single document from the currently selected index
     $this->haystack->delete_document(1);
 
 
     // Delete multiple documents from the currently selected index
     $docids = array(1, 2, 3, 10);
     $this->haystack->delete_documents($docids);
 
 
     // Select a different search index to work with and add a new document
     $this->haystack->set_index('trucks');
     $docid = 12;
     $fields = array(
          'text' => 'Bigfoot, introduced in 1979, is regarded as the original monster truck. Other trucks with the name "Bigfoot" have been introduced in the years since, and it remains the most well-known monster truck moniker in the United States.'
     );
 
     $this->haystack->add_document($docid, $fields);
 
 
     // Delete an entire search index and all of its documents
     $this->haystack->delete_index('vans');
 
 
     // Search in the currently selected index
     $terms = "monster truck";
     $results = $this->haystack->search($terms);
 
     if($results->matches == 0)
     {
          // No results found
     }
     else
     {
          // Results found. Loop through them and print the id.
          foreach($results->results as $doc)
          {
               echo "Found document {$doc->docid}<br />";
          }
     }
}

View the SQL code of a Stored Procedure in SQL Server Management Studio

10.11.2010 | 0 Comments

I’m working on overhauling a large project management application for a client that I inherited from a previous developer.  Part of the application will produce various reports based on data pulled from a SQL Server database.  The query that pulls this data is a Stored Procedure in the database. Rather than try to reverse engineer the SQL query, I can simply run a SQL query of my own to dump the SQL code from the Stored Procedure so I can incorporate it into my application.

Just log into SQL Server Management Studio, open the database where the Stored Procedure resides, and execute the following query:

sp_helptext ‘dbo.stored_procedure_name_here’


Exchange 2007 Dynamic Distribution Groups with Custom Filters

10.08.2010 | 0 Comments

Recently I was experimenting with Exchange 2007 Dynamic Distribution Groups for a client.  I have the Active Directory profiles of each mailbox-enabled user filled out so that I can dynamically create and set their Outlook profiles automatically.  I wanted to use some of this information that I already store about each user to create distribution groups on the fly so that I don’t have to actively maintain group membership.

Specifically, I wanted to use the Office and Description field of their Active Directory profile to include them in a distribution group.  For instance, I have the following basic information stored in Active Directory for each user:

User A
Description: Dallas User
Office: Corporate Office

User B
Description: Dallas User
Office:
North Dallas Field Office

User C
Description: Houston User
Office: Houston Office

If I want to maintain distribution groups in Exchange for each geographical area as well as each individual office, that is pretty easy in Exchange 2007.  You just create a new Dynamic Distribution Group.  However, the difficulty comes when you want to use an Active Directory profile field that is not built in the Exchange Management Console GUI.

Executing the following command in the Exchange Management Shell will create a new Dynamic Distribution Group that selects every mailbox-enabled user with a Description field set to “Dallas User”:

New-DynamicDistributionGroup -Name “GroupNameHere” -OrganizationalUnit “domain.local/OUNameHere” -RecipientFilter { ((RecipientType -eq ‘UserMailbox’) -or (RecipientType -eq ‘MailContact’) -or (RecipientType -eq ‘Contact)) -and (Description -eq ‘Dallas User’) }


Backup Windows SharePoint Services 3 using command line utilities

9.11.2010 | 1 Comment

I recently had a SharePoint server in a RAID 1 configuration lose one of its hard drives.  Since the server was approaching it’s hard drive storage limitations anyway, I decided to install 2 new larger drives rather than rebuild the current array.  An added benefit of this approach is that I can archive the drive we’re using now and have a fairly failsafe recovery point.

The following steps outline how to use the Stsadm.exe utility to backup a Windows SharePoint Services 3 installation.  This tutorial assumes you will be logged onto the SharePoint server when you run this command, and that your SharePoint site is set as the default website in IIS.

Step 1:  Open a comman prompt and find Stsadm.exe
There is a chance that this location is already part of your PATH variable, but if not you will find Stsadm.exe at:

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\BIN

Step 2: Run the Stsadm.exe utility with parameters

stsadm -o backup -url http://localhost -filename mybackup.bak


Allow non administrative users of Windows XP to adjust power settings

8.17.2010 | 0 Comments

I’m not sure why Microsoft thinks that normal users shouldn’t be able to adjust their own power settings – especially laptop users – but they do.  Here is how to grant the appropriate permission to the power settings while keeping everything else locked down.

This walk through assumes that you are logged onto the machine as the non administrative user.

Step 1:  Launch the registry as the administrator
Navigate to Start > Run and issue the following command:

runas /user:localhost\administrator regedit

A command window will appear and prompt you for the administrator password.  You will not see the password on the screen as you type.

Step 2: Modify permissions on the PowerCfg registry key

  1. Browse  to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Controls Folder\PowerCfg
  2. Right-click on the “GlobalPowerPolicy” key and choose “Permissions”
  3. Click on the “Advanced” button
  4. Click “Add”
  5. Type INTERACTIVE and click “Check names”, then OK
  6. Check the “Set value” and “Create Subkey” checkboxes in the “Allow” column, and click OK to apply your changes all the way out
  7. Repeat the above steps for the “PowerPolicies” registry key

Allow non administrative users of Windows XP to change the system time and time zone settings

8.17.2010 | 0 Comments

I won’t go into whether or not it is a good idea to grant rights to non-administrative users of a PC to change the system time and time zone settings, but if you need to do it without logging on locally as a computer administrator, here is how you do it.

Step 1:   Grant the SeSystemtimePrivilige to the user
You can perform this step on the command line with the NTRights application or via the GUI.  We will perform the steps using the Windows GUI.

  1. Navigate to the Control Panel > Administrative Tools
  2. Hold the shift key while right clicking the Local Security Policy applet and choose the Run As option
  3. Specify that you want to run the applet as the local administrator and provide the appropriate password.
  4. From the menu on the left hand side, navigate to Security Settings > Local Policies > User Rights Assignment
  5. Double click the “Change the system time” policy located in the right side of the screen.
  6. Click the Add User or Group button and locate the user you wish to grant permission to.  Click OK to apply your changes all the way back out.

Step 2: Launch the registry editor as the local administrator
To begin, click Start > Run and type the following:

runas /user:localhost\administrator regedit

A command prompt window will open and prompt you for the local administrator credentials.  Enter the password and hit Enter.  You will not see any characters appear in the command window while typing the password.

Step 3:  Grant permission to the user on the TimeZoneInformation registry key
It should go without saying, but messing around in the registry can cause system problems, so be careful.  Use this link to create a backup of the registry before continuing.

  1. Locate the HKLM\System\CurrentControlSet\Control\TimeZoneInformation registry key.
  2. Right click on the key and choose the Permissions option
  3. Click the Advanced button
  4. Locate the appropriate user or group you wish to delegate permissions to.  Click on the user or group and hit the Edit button
  5. Modify the permissions so that the Query Value, Set Value, Create Subkey, Enumerate Subkeys, Notify and Read Control permissions are applied.
  6. Click OK to apply your changes all the way out

Step 4:  Reboot
Once you reboot the machine the non-administrative user will be able to adjust the time and time zone settings on their machine.


3 Reasons you shouldn’t build a website in Adobe Flash

8.02.2010 | 0 Comments

I’ve never really liked Flash.  I’ve been over the typical splash page intro for a long time.  Don’t misunderstand me here – I’m guilty of creating the kind of block-text-flying-past-your-face-with-laser-noises site intros.  Sometimes the client insists on that kind of Dane Cookery.  Some things never change – but at least now there is a better alternative: HTML 5.  I’ll cover some interesting aspects of HTML 5 in my next article.

But let’s not get ahead of ourselves.  Here are a few reasons why building a Flash website is a really bad idea:

1.  Search engines can’t index it (mostly)
OK, so this might be changing.  Google has announced that it can index some parts of your Flash movie – but not all parts.  Basically the Google bot uses a brute force method to click around in your Flash movie and record what happens.  Sounds a little sketchy to me.  Certainly sketchy enough that I wouldn’t pin one of my site’s SEO hopes and dreams on it.  And what about Bing, Yahoo! and Ask.com?

2.  Flash requires a special browser plugin
This should be pretty obvious.  Would you go to a restaurant that required you to bring your own silverware or would you go to a restaurant that makes it easy for you to just show up, enjoy yourself and leave when you’re ready?  Why would you put an unnecessary roadblock in front of your site visitors?  What if your visitors aren’t even able to install the Flash plugin on their computers because their company IT department has locked them down?  What if your Flash movie relies on special Flash 9 functionality but Sally in the marketing department of Really Big Company You Want To Do Business With only has Flash 7 installed?  It sounds like we have a lot of easily avoidable barriers to entry here.

3.  Apple iPhones don’t support Flash
Perhaps you’ve heard of the iPhone.  It is currently the world’s most popular cell phone, having ousted the venerable Motorola RAZR.  More specifically, it is the world’s most popular cell phone that does not support Flash.  I don’t want to start an Apple vs. Adobe holy war here, and there is probably some bad blood between Steve Jobs and Adobe below the surface, but the main reason the iPhone doesn’t support Flash is:

It can’t.  At least not very well.

Think about it: the main interaction between a user and Flash animation is through the mouse – a device which supports the concept of hovering.  Menus expand to reveal sub menus on a hover, tooltips appear on a hover, new content is brought into focus on a hover.  How do you hover on an iPhone?  You can’t.  There is only clicked or unclicked.

The problem isn’t an Apple problem, it’s an interface problem.  All touch screen devices suffer from this affliction.  I’m sure some day a clever developer will invent an even more clever way to implement hover on a touch screen, but that day isn’t today.  If you build a website that relies on Flash for navigation or key elements of your site, you are instantly losing a huge chunk of potential visitors.

So what should I do?
Well, first of all you should think about whether using Flash is bringing any value to your visitor’s experience, or if you’re just playing the design version of Keeping Up With The Joneses.  Every design and implementation choice you make on a website should serve a purpose.  It should make the content more readable, the navigation more intuitive, or the page load faster.

Have you ever visited a site, found the information you were looking for, and said to yourself, “You know, this website was great, but I sure wish it used more Flash.”  I haven’t.  Ever.

But let’s say that you or your client insist on having that menu fly across the screen and do a flip every time a page loads.  At least do it with HTML 5.  More on that next time.


How to renew a GoDaddy Subject Alternative Name SSL certificate on Exchange 2007

7.14.2010 | 0 Comments

I manage an Exchange 2007 server for one of my clients where we have deployed Outlook Anywhere, a.k.a. RPC-HTTPS, to deliver a robust Exchange experience to remote users.  We use a standard SSL certificate purchased from GoDaddy to secure communications.

That certificate expired today.  I used articles from telnetport25 and msexchangegeek as resources, but I thought it would be helpful to compile the entire procedure in one location.

Note:  Since the process to create and download an SSL certificate is different for every Certificate Authority, I will not cover it here.  You should have your new certificate ready before beginning this procedure.

Step 1:  Get the thumprint of the expired certificate
You have to know the unique thumbprint of a certificate before it can be uninstalled.  On the Exchange server, open the Exchange Management Shell and run the following command:

Get-ExchangeCertificate | fl | out-file –filePath c:\certs.txt

You will end up with a file on your C drive called certs.txt.  Open this file and locate the certificate that needs to be uninstalled.  Look for the NotAfter parameter to help you determine which certificate is expired or expiring soon if you have more than one certificate installed.  Once you locate the certificate that needs to be uninstalled, make a note of the value of the Thumbprint parameter.

Step 2:  Uninstall the expired certificate
Run the following command, substituting the value of the Thumbprint from Step 1 where it says <thumbprint>:

Remove-ExchangeCertificate –thumbprint <thumbprint>

You will be prompted to confirm that you really wish to uninstall this certificate from the system.  Press ‘a’ to confirm and continue when you’re ready.

Step 3:  Import your new certificate
You should have already generated your new certificate.  Since every certificate authority has a different process, we won’t cover that part of this operation here.  Download your new certificate to the C drive of the Exchange server and run the following command:

Import-ExchangeCertificate -path c:\mycert.cer –FriendlyName “mail.mydomain.com”

The FriendlyName parameter can be anything you want, so make it something descriptive that you will recognize later.  It is common practice to use the URL of the domain you are securing as the FriendlyName.

Make a note of the new Thumbprint that is generated for your new certificate.

Step 4:  Enable the new certificate for OWA
Substitute the Thumbprint value from the previous step where it says <thumbprint> and run the following command to enable the new certificate to secure OWA:

Enable-ExchangeCertificate -Thumbprint <thumbprint> -Services IIS

That’s all there is to it.  Test your certificate installation by opening your OWA domain in a web browser.  If the SSL encryption icon is set and you do not receive any warnings about certificate errors, you are done.