There are multiple options with customization, but here's what I found based on my research which will eliminate the hassle for you:
https://sites.secure.force.com/appexchange/listingDetail?listingId=a0N30000005utCcEAI
above is appExchange app which works smooth for the same requirement, also following is suggestions for customization:
https://developer.salesforce.com/forums?id=906F00000008xrpIAA
Also Salesforce has considered making this as standard function which is under their future roadmap on which you can vote and help to get delivered soon:
https://success.salesforce.com/ideaview?id=08730000000Br5dAAC
And last but not least, I have code structure for this solution:
trigger autoCampaignMemberStatusTrigger on Campaign (after insert) {
List<Campaign> newCamps = [select Id from Campaign where Id IN :trigger.new AND ParentID = Null AND Campaign_Template__c=false];
List<CampaignMemberStatus> cms = new List<CampaignMemberStatus>();
Set<Id> camps = new Set<Id>();
List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>();
for(Campaign camp : newCamps){
camps.add(camp.Id);
}
for(CampaignMemberStatus cm : [select Id, Label, CampaignId from CampaignMemberStatus where CampaignId IN :camps]) {
CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=false,
Label = 'Email Sent', SortOrder = 3, isDefault = true);
cms2Insert.add(cms1);
CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=false,
Label = 'Called', SortOrder = 4);
cms2Insert.add(cms2);
CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId = cm.CampaignId, HasResponded=true,
Label = 'Appointment Set', SortOrder = 5);
cms2Insert.add(cms3);
}
insert cms2Insert;
}