Microsoft's NEWID() documentation does not explain, but I agree that the likely reason is related @Payload's comment on another answer:
NEWID() is a non Deterministic function, which after 2005 is allowed
in UDF but, as NEWID changes some of the internal counters and values
inside the database structure it is considered to have a 'side effect'
and as UDF's are not allowed to have side effects it is not allowed in
the UDF, the same goes for RAND() as each call to RAND changes the
seed value in the inner workings of MSSQL and this again is considered
a side effect. GETDATE()/GETUTCDATE() and the allowed lists of
functions have no side effects, so are allowed.
For those willing to risk it, see @dio-phung's workaround suggested in another comment on that same answer:
@DavidSpillett: FYI you can get around the ban of newid() by reading
from a view : CREATE VIEW vw_NewGuid AS SELECT NEWID() AS new_guid .
Then in your UDF, you can do : SELECT new_guid FROM vw_NewGuid
Note @david-spillett's caution:
@Dio: I would be very wary of workarounds that involve conning the
engine that something is deterministic when it in fact isn't. You are
either using a bug that may be fixed later (perhaps it should detect
that the column in the view is not deterministic and they'll fix that
in SQL Sever {Nextversion}) or relying upon "undefined behaviour" that
similarly isn't guaranteed to work the same in later versions (or even
in your current version if other circumstances change in the query).
That workaround/trick is offered in several other answers.
newid()by reading from a view :CREATE VIEW vw_NewGuid AS SELECT NEWID() AS new_guid. Then in your UDF, you can do :SELECT new_guid FROM vw_NewGuid. – Dio Phung Jun 15 '16 at 18:09