Q:

Script only partially runs on theme activation, but runs fully on deactivation?

The code below is near the top of my functions.php and is set to run only when my theme is activated:
if ( is_admin() && isset($_GET['activated'] ) && $pagenow == 'themes.php' ) {

However, even though its creating the category "my-utilities", it is apparently not able to set the parent of the category1 and category2 items to the newly created category.
Perhaps its too soon to call get_cat_id on the newly created category?
I believe it has something to do with that, since the category's reparent on the 2nd time the theme is activated. This, I presume, is since the category that will be used as parent has been created previously, the routine has no problem finding its ID and using it as the parent for category1 and category2.
What am I missing?
// with activate make sure theme's utility categories are present and parented correctly
if ( is_admin() && isset($_GET['activated'] ) && $pagenow == 'themes.php' ) {

    if (file_exists(ABSPATH.'/wp-admin/includes/taxonomy.php'))
    {
        require_once(ABSPATH.'/wp-admin/includes/taxonomy.php');    

        if(!get_cat_ID('my-utilities')){wp_create_category('my-utilities');}

        //find out the ID of the newly created category, "my-utilities"
        $my_default_cat = my_cat();

        if(!get_cat_ID('category1')){wp_create_category('category1',$my_default_cat);}
        if(!get_cat_ID('category2')){wp_create_category('category2',$my_default_cat);}

        //if the categories already existed, reparent them
        $myCategory1['cat_ID'] = get_cat_id('category1');
        $myCategory1['category_parent'] = $my_default_cat;
        wp_update_category($myCategory1);

        $myCategory2['cat_ID'] = get_cat_id('category2');
        $myCategory2['category_parent'] = $my_default_cat;
        wp_update_category($myCategory2);

    }
}

//utility category
function my_cat()
{
    if(get_cat_ID('my-utilities')) 
    {
        return get_cat_ID('my-utilities');
    }
    else
    {
        if(term_exists(1)) return "1";
        else return get_option('default_category');
    }
}

A:

You're looking for this:
register_activation_hook( __FILE__, 'your_plugin_activate_function_name' );

Edit: for a theme, you can use something like this instead:
$theme_version = get_option('my_theme_version');

switch ((string) $theme_version) {
  // an early alpha... run upgrade code
  case '0.1':

  // another version... run upgrade code
  case '0.5':

  // add other cases as needed... without any break statement.

    // if we're here and in the admin area (to avoid race conditions),
    // actually save whichever changes we did
    if (is_admin()) {
      update_option('my_theme_version', '1.0');
      // do other stuff
    }

  // we're at the latest version: bail here.
  case '1.0':
    break;

  default:
    // install code goes here
}

