sp_addUser through sp_execute (SQL) in master db
Your dynamic text is not valid:

you should add spaces between IMMEDIATE and RESTORE, STATS = 5 and ALTER,
you should remove additional unclosed quotation mark here: SET MULTI_USER'' --> SET MULTI_USER'

Your 

@sql = 'use ' + @dbname
    exec sp_executeSQL @sql


is executed in it's own context so you changed db context not for your session but only within your dynamic code execution so your next piece of dynamic code that grants is still executed in the context of current database.

You should always print your dynamic code before try to execute it and you'll see where the errors are.

But the best solution for your situation is to write once a plain(not dynamic) code for all databases, save it and run every time you need it.