You first need to make sure you actually need this functionality, you may have settled on a sub-par solution because you didn't think through the problem carefully. Clarifying what your use case is will let people offer better advice because what works in some situations will be useless in others.
Assuming you really do need this you can use the editmacro() api to re-write a macro when you're out of combat. You can call that within a macro to edit another one:
You need to make to macros. One called "HoP" -- it can be empty -- and a second containing the above code (I called it "setHoP").
/run HM='HoP';HS='Hand of Protection';HT=UnitName('target');
/run if InCombatLockdown() then print(HS..'!!'..HT..'!!');else EditMacro(HM,nil,nil,'#showtooltip\n/cast [target='..HT..'] '..HS,nil);print(HS..'->'..HT);end;
Set the HoP macro to whatever action bar button/keybind you like. Do the same with the setHoP macro (setting it to another key/bar slot obviously).
You you press the setHoP macro it'll replace the HoP macro code with the following:
Where the name "Hario" is replaced by the name of whatever you had targeted was.
/cast [target=Hario] Hand of Protection
If it works you'll see "Hand of Protection->Hario" in chat and if it failed you'll get "Hand of Protection!!Hario!!") instead.
You can create new macros for any particular spell you like (you'll need one called setMACROSXXX with a copy of the first snippet and it'll edit a macro called MACROSXXX). You'd just edit the first line of the first snippet editing HM to be the name of the macro, HS to the name of the spell, and HT for where you'll take the unit name from.
There are a number of restrictions on how macro conditions must be formatted, when you can run a command like this (ie: not in combat), and length-limits get in the way very quickly. I suspect there are relatively few places this kind of thing is useful but maybe you really do need it.