WP Query to set post thumbnail for existing old posts

The first step is to loop through all the posts:

$wpse87964query = new WP_Query();

Now, that will get all the posts; but we’re only interested in posts that don’t have a featured image set. WordPress stores the featured image via a post custom meta field: _thumbnail_id; so, we can use that in a meta query, to get only the posts that don’t have a set featured image:

$wpse87964query_args = array(
    'nopaging' => true,
    meta_query( array(
        array(
            'key' => '_thumbnail_id',
            'compare' => 'NOT EXISTS'
        )
    ) )
)
$wpse87964query = new WP_Query( wpse87964query_args );

Now, set up the loop:

if ( $wpse87964query->have_posts() ) : while ( $wpse87964query->have_posts() ) : $wpse87964query->the_post();

// CODE WILL GO HERE

endwhile; endif;
wp_reset_postdata();

Now, query for attachments:

$attachments = get_children( 'post_parent=" . get_the_ID() . "&post_type=attachment&post_mime_type=image&order=desc' );
if( $attachments ) {
    $keys = array_reverse( $attachments );
    set_post_thumbnail( get_the_ID(), $keys[0]->ID );
};

Now wrap the whole thing inside a function, so you can call it somewhere, or hook it into something:

function wpse87964_set_post_thumbnails() {

    // Query args
    $wpse87964query_args = array(
        'nopaging' => true,
        meta_query( array(
            array(
                'key' => '_thumbnail_id',
                'compare' => 'NOT EXISTS'
            )
        ) )
    )
    // Run query
    $wpse87964query = new WP_Query( wpse87964query_args );

    // Open query loop
    if ( $wpse87964query->have_posts() ) : while ( $wpse87964query->have_posts() ) : $wpse87964query->the_post();

        // Query post attachments
        $attachments = get_children( 'post_parent=" . get_the_ID() . "&post_type=attachment&post_mime_type=image&order=desc' );
        if( $attachments ) {
            $keys = array_reverse( $attachments );
            set_post_thumbnail( get_the_ID(), $keys[0]->ID );
        };

    // Close query loop
    endwhile; endif;
    wp_reset_postdata();

}

You can improve this function, by stepping through the posts in batches, or by defining your own post custom meta to query against, so that you only process each post once, etc.