\documentclass{article}
\begin{document}
\newcommand\hello{Hello, \LaTeX!}
\newwrite\foo
\immediate\openout\foo foo.tex
\immediate\write\foo{\unexpanded\expandafter{\hello}} % documentation of `\unexpanded` is in texdoc etex_man
%\immediate\write\foo{\detokenize\expandafter{\hello}} % this is an alternative, I believe it's slower than the above, although I didn't benchmark
\immediate\closeout\foo
\end{document}
although the actual issue here is: \LaTeX command is robust, but it's old-style robust. So an alternative fix (identical in this case but hopefully you can see what's the difference) is
\documentclass{article}
\begin{document}
\newcommand\hello{Hello, \LaTeX!}
\newwrite\foo
\immediate\openout\foo foo.tex
\makeatletter
\set@display@protect % see source2e...
\immediate\write\foo{\hello}
\restore@protect
\makeatother
\immediate\closeout\foo
\end{document}
there's \protected@write but no analogous \immediate@protected@write as far as I can see.
(or you can copy the \protected@iwrite from https://tex.stackexchange.com/a/110885/250119.
Similar question: Storing environment arguments by \immediate\write
\newcommand\hello{Hello, \string\LaTeX!}works for \write, but also prevents expansion when used in text. – John Kormylo Feb 04 '23 at 16:50