Easy way to remove an old Domain Controller

by JasonRShaver 19. March 2009 16:57

 I found this link that shows how to use NTDSUTIL.exe tool to stop dead DCs from annyoing you.  It is not the kind of thing you need often, but it is better then doing it by hand.

http://www.petri.co.il/delete_failed_dcs_from_ad.htm

Tags:

Blog

An Easy .NET CF Settings Class

by JasonRShaver 11. March 2009 16:56

Every time I start a new Windows Mobile project, I find myself needing a new 'Settings' class.  This is the one that I have been using for many of my projects, here are some of its features:

  • Simple Key/Value pair usage
  • You can select wether to save using an XML file or registry by Key
  • Supports Int, Bool, and String
  • Can hold settings on the file system using the filename "MyApplication.exe.config"
  • Can hold settings in the registry using the path "HKLM/Software/MyApplication.exe/"
  • Fast read caching for file settings

As a note, you can't use GetEntryAssembly in the .NET Compact Framework to find the name of the launching executable, so instead I am using the GetModuleFileName from CoreDll.

Here is the code, if you find anything I can do better, send me an email or leave a comment:

using System;

using System.Data;

using System.IO;

using System.Runtime.InteropServices;

using Microsoft.Win32;

 

namespace ThisNamespace

{

    static public class Settings

    {

        static private DataSet _SettingsDataSet = null;

        static private String _ApplicationName = String.Empty;

        static private String _XmlFile = String.Empty;

        static private String _RegistryPath = String.Empty;

 

        static private DataSet SettingsDataSet

        {

            get

            {

                if (_SettingsDataSet == null)

                {

                    _SettingsDataSet = new DataSet();

                    _SettingsDataSet.Tables.Add(new DataTable("Settings"));

                    _SettingsDataSet.Tables["Settings"].Columns.Add("Key", Type.GetType("System.String"));

                    _SettingsDataSet.Tables["Settings"].Columns.Add("Value", Type.GetType("System.String"));

 

                    if (File.Exists(XmlFile))

                        _SettingsDataSet.ReadXml(XmlFile, XmlReadMode.Auto);

                }

                return _SettingsDataSet;

            }

        }

        static private DataTable SettingsTable

        {

            get

            {

                return SettingsDataSet.Tables["Settings"];

            }

        }

        static private String ApplicationName

        {

            get

            {

                if (String.IsNullOrEmpty(_ApplicationName))

                {

                    byte[] buffer = new byte[520];

                    int ReturnedDataLength = GetModuleFileName(IntPtr.Zero, buffer, buffer.Length);

                    String ApplicationFullName = System.Text.Encoding.Unicode.GetString(buffer, 0, ReturnedDataLength * 2);

                    _ApplicationName = Path.GetFileName(ApplicationFullName);

                }

                return _ApplicationName;

            }

        }

        static private String XmlFile

        {

            get

            {

                if (String.IsNullOrEmpty(_XmlFile))

                    _XmlFile = String.Format(@"{0}.config", ApplicationName);

                return _XmlFile;

            }

        }

        static private String RegistryPath

        {

            get

            {

                if (String.IsNullOrEmpty(_RegistryPath))

                    _RegistryPath = String.Format(@"Software\{0}\Settings", ApplicationName);

                return _RegistryPath;

            }

        }

 

        static public void SaveSetting(string key, bool value)

        {

            SaveSetting(key, value.ToString(), StoreLocation.File);

        }

        static public void SaveSetting(string key, bool value, StoreLocation storeLocation)

        {

            SaveSetting(key, value.ToString(), storeLocation);

        }

        static public void SaveSetting(string key, int value)

        {

            SaveSetting(key, value.ToString(), StoreLocation.File);

        }

        static public void SaveSetting(string key, int value, StoreLocation storeLocation)

        {

            SaveSetting(key, value.ToString(), storeLocation);

        }

        static public void SaveSetting(string key, string value)

        {

            SaveSetting(key, value, StoreLocation.File);

        }

        static public void SaveSetting(string key, string value, StoreLocation storeLocation)

        {

            switch (storeLocation)

            {

                case StoreLocation.File:

                    foreach (DataRow ThisRow in SettingsTable.Rows)

                    {

                        if (ThisRow["Key"].Equals(key))

                        {

                            ThisRow["Key"] = value;

                            _SettingsDataSet.WriteXml(XmlFile);

                            return;

                        }

                    }

                    DataRow NewRow = SettingsTable.NewRow();

                    NewRow["Key"] = key;

                    NewRow["Value"] = value;

                    _SettingsDataSet.WriteXml(XmlFile, XmlWriteMode.IgnoreSchema);

                    return;

                case StoreLocation.Registry:

                    RegistryKey ThisKey = Registry.LocalMachine.OpenSubKey(RegistryPath, true);

                    if (ThisKey == null)

                    {

                        RegistryKey LocalMachineKey = Microsoft.Win32.Registry.LocalMachine;

                        LocalMachineKey.CreateSubKey(RegistryPath);

                        LocalMachineKey.Close();

                        ThisKey = Registry.LocalMachine.OpenSubKey(RegistryPath, true);

                    }

                    ThisKey.SetValue(key, value, RegistryValueKind.String);

                    ThisKey.Close();

                    return;

                default:

                    throw new ArgumentException("Unknown StoreLocation type");

            }

        }

        static public int GetSetting(string key, int defaultValue)

        {

            return GetSetting(key, defaultValue, StoreLocation.File);

        }

        static public int GetSetting(string key, int defaultValue, StoreLocation storeLocation)

        {

            String Result = GetSetting(key, defaultValue.ToString(), storeLocation);

            return int.Parse(Result);

        }

        static public bool GetSetting(string key, bool defaultValue)

        {

            return GetSetting(key, defaultValue, StoreLocation.File);

        }

        static public bool GetSetting(string key, bool defaultValue, StoreLocation storeLocation)

        {

            String Result = GetSetting(key, defaultValue.ToString(), storeLocation);

            return bool.Parse(Result);

        }

        static public string GetSetting(string key, String defaultValue)

        {

            return GetSetting(key, defaultValue, StoreLocation.File);

        }

        static public string GetSetting(string key, String defaultValue, StoreLocation storeLocation)

        {

            switch (storeLocation)

            {

                case StoreLocation.File:

                    foreach (DataRow ThisRow in SettingsTable.Rows)

                    {

                        if (ThisRow["Key"].Equals(key))

                        {

                            return ThisRow["Key"].ToString();

                        }

                    }

                    return defaultValue;

                case StoreLocation.Registry:

                    try

                    {

                        RegistryKey ThisKey = Registry.LocalMachine.OpenSubKey(RegistryPath, false);

                        object Result = ThisKey.GetValue(key, defaultValue);

                        ThisKey.Close();

                        return Result.ToString();

                    }

                    catch

                    {

                        return defaultValue;

                    }

                default:

                    throw new ArgumentException("Unknown StoreLocation type");

            }

        }

 

        [DllImport("coredll.dll", SetLastError = true)]

        static private extern int GetModuleFileName(IntPtr hModule, byte[] lpFilename, int nSize);

 

        public enum StoreLocation

        {

            File = 0,

            Registry = 1,

        }

 

    }

}

Tags:

Blog

Improving Your Internet Sales Performance

by JasonRShaver 7. March 2009 16:56

There is an old sales trick (I used to sell for Acura): get them used to saying yes.  So when they are test driving a car:

  • Do you like this kind of weather? "Yes"
  • Are you married? (when you see the wedding ring) "Yes"
  • Do you like sedans? "Yes"
  • Do you like the safety features? "Yes"
  • Do you like the way this drives? "Yes"
  • (Notice their current car color) Do you like this color? "Yes"

And you just keep going, get them used to saying yes all the time, then when the test drive is over, it is easy to get them they to the table:

  • So did you enjoy your test drive? "Yes"
  • Do you like this car better than your old one? "Yes"
  • Is there a price where I can sell you a car today, like what about $1? "Sure"
  • Ok, I can't do that of course, but lets see how we can help you out.

And boom, you are at the table talking about price.

The funnel is this same kind of thing.  There is a point in every sales transaction when you ask the client to do something harder then what they are doing now.  For your web site, that could be getting them to call.  You need to give them a reason to call you.  You need to build a case for them to call you.  You need to make them WANT to call you, more than the other 5 web sites they just visited (and did not call), and that is where the funnel comes in.

If I tried to sell a car by saying:

  • Test drive this car. "umm, ok"
  • (after test drive is done)
  • Ok, how much do you want to pay? "I have to think about it".

The customer would not want to talk about price because he does not yet know if he likes, wants, or needs the product yet.  The salesperson did not do their job.

When getting traffic for your product via Pay-Per-Click (PPC) advertising such as Google AdWords, your 'funnel' is your salesperson.  The trick to a funnel is to get them on that process of committing to the product.  Lets go over all of the steps for a fiction company that sells a "start your own business" product.

The Add

First we need a good AdWords ad:

Be Your Own Boss
Make $100,000 a year
with a $10k investment
www.WigetSeller.com

So goal of the ad is to connect with people who want that service.  In your ad, you want to make sure you do what you can to filter out 'non-customers'.  In this case, I am saying that there is a $10,000 investment so that only people who are ok with that idea will click.  Remember that each click costs money.  And for some keywords such as "Start a business" cost you $5.00 a click, and eat up to $1000 a day from your advertising budget.

The Landing Page

So, the landing page is where your AdWords ad will send the potential customer.  Anyone with a history of running a web site will know that a huge amount of visitors will look at your site and then hit the 'back' button.  This is called a 'bounce'.  Your landing page is to let users that have clicked on your ad know that this is what they are looking for.

You need this page to validate every fact the AdWords ad gave, such as make "$100,000 a year", or "$10k investment". If you don't Google might reject your ad, as the rules stat that "If your price is listed in your add then that price must be disclosed on the web site no deeper than 3 pages" for example.

Think of this page as a full page ad, here are some simple rules:

  1. You want to make sure that you have your general navigate out of the way on this page; you don't want uses walking around unescorted through your web site.  You are trying to deliver a marketing message here.
  2. Make sure the text (copy) starts in the upper left and goes down from there.
  3. Make sure that any pictures do not take up the width of a whole column of text.  This will 'lose' some people.  Even if you are selling photos, this is still a bad idea.

Then at the bottom of that page, have a big button or link leading them into the funnel.  Something with text like "Click here for more information", "See how the process works", or "What is involved". 

The Funnel Pages

So now the potential customer hits, 'the funnel'.  These pages have two simple goals:

  1. Get the customer commited to your product.
  2. Letting the website owner know where his marketing message is failing.

To do this, write down a list of the top 5 reasons why someone would not buy your product, such as "It is too hard to do", "I am not sure it works", and "I don't know if I can get the investment money".

For each one of your reasons, make a web page that address the question.  So for example, "It is too hard to do", make a page that show how easy it is to use your product, maybe have some customer testimonials, or a video.

Then at the bottom of each page, in a big button or link, lead them to the next funnel page with text such as "Does it really work?" leading to the "I am not sure it works" page, or "How do I get the startup money?" leading "I don't know if I can get the investment money" page.

The Conversion Page

So, after your potential customer has gone through the Funnel Page and received some information about your product, you direct then to the conversion page.  This is the page that tells them to make the 'hard step', this would be the page where you have them fill out a contact form, make a phone call, or buy a product.

As a general note, if your product requires human involvement, make sure you give both a contact form AND a phone number.  Some people are not comfortable calling a number on a web site, but willingly full out contact forms.

How to Improve Your Funnel

Ok, so you have your ad, landing page, funnel, and conversion page up for a week (at least 7 days) and you want to get better results.  Here is where the magic really happens.

Sign up for Google Analytics and add it to your site.  Then setup your "Conversion Goals and Funnel" via Actions -> Edit.

Now, when you view your report, under Goals -> Funnel Visualization, you can see what is happening with your funnel.

Users Are Bouncing Off My Landing Page

In this case, your issue is related to your AdWords ad is misleading, or your landing page needs to be improved.  A good landing page should only be getting a 20-30% bounce rate from PPC visitors.  I have seen customers with landing pages in the low teens before too.

Make sure your landing page repeats the information in the ad, but not much more.  Make people enter the funnel to get information, this way you can see where you are losing them.  If you have all your information on the landing page, then you don't know if you are losing their interest because or price, quality, or concept.

Users Are Leaving The Funnel

The goal with the funnel is to find out where customers are losing interest.  Each funnel page should give out information about some part of your product.  So if you have the following pages with the following loss rates:

  1. What is it (15%)
  2. How it works (8%)
  3. How much (65%)
  4. Does it work (2%)

Than your issue is with the ordering.  You want your pages to be ordered (generally) from lowest loss to highest loss.  Obviously in the above example, you are losing ALOT of people at the "How much" step.  This means you did a bad job justafying your product cost, and your "Does it work" page is not really doing anything, as people who got that far are already committed.  Just by changing the order you will likely end up with:

  1. What is it (15%)
  2. How it works (8%)
  3. Does it Work (20%)
  4. How Much (25%)

Bringing you from a 35% retention rate to 47% retention rate, a 34% improvement.

If you you can't improve your numbers by reordering, changing text, or improving your marketing message, such as this:

  1. What is it (15%)
  2. How it works (8%)
  3. Does it work (20%)
  4. How Much (65%)

Then here is the sad pill to swallow...  your product costs too much for the people you are reaching.  Hopefully, you are happy with your present sales rate, because without trying to reach a better demographic or changing your product, there is not much you can do.  This applies to more then just price.  If the "How it works" loss rate is 45%, then you need to make your product easier to use or start targeting more technical or knowledgeable customers.

Users Are Leaving on the Conversion Page

This one is an easy one. 

  1. Your funnel is too short (you are not getting enough commitment)
  2. You are asking too much (in the effort sense)
  3. Your conversion page is too complex (users can't figure out what to do)

Each of the above should have an obvious fix.

Conclusion

So what is the point?  If you have the entire process setup:

  1. AdWord
  2. Landing Page
  3. Funnel Page #1
  4. Funnel Page #2
  5. Funnel Page #3
  6. Funnel Page #4
  7. Conversion Page

Then there is no excuse to not know why your product is not selling.  This process works and is used on almost every successful web site.  You don't need to pay money for a SEO specialist, AdWords manager, or marketing company.  Don't get lazy, don't cheat it, and don't cut corners.  Setup the funnel and make your web site the salesperson that you yourself would be

Tags:

Blog

New Running Goals

by JasonRShaver 6. March 2009 16:56

I am now picking my running goals for the full and half marathon this year:

For the Half-Marathon, I will try to run 9:02 minute miles with a goal of 1:59:05, but I will try to hit 8:27 minute miles and see how I feel in my pre-training, as that would get me into the 'D' corral for the marathon (and a 'D' xxxx bib number).

For the Marathon, my current goal is 9:05 pace with a goal of 3:58:09, but if I can't keep that pack up for my 20 miler runs beforehand, I will knock it back to a 10:00 pace and and take the 4:22:11 time.  

I did a 'test' 5K run yesterday and kept a strong 9:00 pace, and this is only a few weeks into serious running this year and on the first week of my training program.

No matter what, I will be beating my 5:40:53 time that made me so sad last year.  As another note, my toes finally healed from the marathon. =)

Tags:

Blog

Areas and Iterations Not Updating in TFS 2008

by JasonRShaver 4. March 2009 16:55

So I was setting up a new TFS 2008 install for a hosted scenario and then just when I thought I was done, and the client setup the first TFS Project, we realized a major problem, the Areas and Iterations would not update. 

Now when you see this issue, there is one of two things that will generally cause it:

  1. The update subscripitions are not running (consistantly or at all)
  2. The update subscriptions are going to the wrong place
  3. The update subscriptions are not working (failing)

In the first case, this is easy to fix by looking into the Jobs in SQL Server in the case it is not working at all.  If they are not running all the time, try an "iisreset" on the AT and see if it goes away, otherwise, look at this post towards the end and you will find some ideas.

In the second case, there is an easy SQL Server query that can do it, "SELECT * FROM TfsIntegration.dbo.tbl_subscription WHERE delivery_type = 2".  If the result is now what you would expect, then do a "TfsAdminUtil ActivateAT" command on the AT (in the Tools folder) and your issue should be fixed.

In the final case, look at the event log and try google for the TFxxxxxx errors, there are ALOT of reasons this can happen.  In my case, I was having an issue with IWA working with the webservice.  My AT's "name" was an external FQDN (http://tfs.test.com:8080) but the routing on my internal network was messing it up.  I am sure not using SSL did not help much.

Tags:

Blog

Oscar Michelen is a great man

by JasonRShaver 3. March 2009 16:55

Oscar Michelen is a litigator in New York City who helps defend people against baseless copyright settlement letters.  Why is he a great man, because to help level the playing field against large companies and small wannabe companies, he offers to help you respond to the settlement offers for a dirt cheap fee (~$150) and it need be, will help litigate your case at a cheap rate (~$150 an hour, much less then his normal $400-500 an hour). 

So, thank you to Oscar Michelen for using your legal skill and experience to help the people in an age where the law is changing daily and can be very confusing.

I wish there were more people like him who would step up to the RIAA, MPAA, and other companies that instead of moving their induestry forward, decide to beat down innovation.  Justly, the people who chose to do crime have not been hampered (isohunt.com, warez rings, the 'scene') and the people like me, who really WANT to pay for a good services are unable to because no good service exists (Hulu.com is pretty close). 

(I have not talked to Oscar Michelen or used his services, if I have misunderstood his offer, please let me know)

Tags:

Blog

How to troubleshoot stored procedures

by JasonRShaver 2. March 2009 16:54

 This only works with SQL 2005 SP2 or greater, as the SP2 included the OBJECT_SCHEMA_NAME function.  This will tell you all of the performance metrics of every stored procedure run since the last SQL Server restart.

 

 

SELECT DB_NAME(st.dbid) DBName

      ,OBJECT_SCHEMA_NAME(objectid,st.dbid) SchemaName

      ,OBJECT_NAME(objectid,st.dbid) StoredProcedure

      ,max(cp.usecounts) execution_count

      ,sum(qs.total_elapsed_time) total_elapsed_time

      ,sum(qs.total_elapsed_time) / max(cp.usecounts) avg_elapsed_time

      ,sum(qs.total_worker_time) total_cpu_time

      ,sum(qs.total_worker_time) / (max(cp.usecounts) * 1.0)  avg_cpu_time

      ,sum(qs.total_physical_reads + qs.total_logical_reads + qs.total_logical_writes) total_IO

      ,sum(qs.total_physical_reads + qs.total_logical_reads + qs.total_logical_writes) / (max(cp.usecounts)) avg_total_IO

      ,sum(qs.total_physical_reads) total_physical_reads

      ,sum(qs.total_physical_reads) / (max(cp.usecounts) * 1.0) avg_physical_read   

      ,sum(qs.total_logical_reads) total_logical_reads

      ,sum(qs.total_logical_reads) / (max(cp.usecounts) * 1.0) avg_logical_read 

      ,sum(qs.total_logical_writes) total_logical_writes

      ,sum(qs.total_logical_writes) / (max(cp.usecounts) * 1.0) avg_logical_writes 

 FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) st

   join sys.dm_exec_cached_plans cp on qs.plan_handle = cp.plan_handle

  where DB_NAME(st.dbid) is not null and cp.objtype = 'proc'

 group by DB_NAME(st.dbid),OBJECT_SCHEMA_NAME(objectid,st.dbid), OBJECT_NAME(objectid,st.dbid)

 order by max(cp.usecounts) desc

 

 

 

 

Tags:

Blog

About the author

I am a software developer working for Microsoft in Redmond, WA.  In addition, my wife and I own TTXOnline, what is likely the 3rd largest table tennis store in the US.

Month List

Page List