Another option is to create a SQL Server agent job that runs on a schedule, to execute your SQL for all databases.
You can also wrap your code in a stored procedure, which you can create in the model database or a "Utilities" database.
One possible implementation is below (this assumes the login name and user name will be the same, but can be modified to handle differing login/user names):
CREATE PROCEDURE [dbo].[usp_CreateLoginAndUserDbDataReader]
@LoginName NVARCHAR(50),
@Password NVARCHAR(50),
@DbName NVARCHAR(128)
AS
BEGIN
DECLARE @SQL nvarchar(1000)
IF NULLIF(@LoginName, '') IS NULL
OR NULLIF(@Password, '') IS NULL
OR NULLIF(@DbName, '') IS NULL
THROW 70000, 'You must specify a value for @LoginName, @Password, and @DbName', 1
IF NOT EXISTS (SELECT name
FROM master.sys.server_principals
WHERE name = @LoginName)
BEGIN
PRINT '@loginname = ' + COALESCE( @LoginName, 'NULL' )
SET @SQL = 'CREATE LOGIN [' + @LoginName + '] WITH PASSWORD = ''' + @Password + ''', DEFAULT_DATABASE=[' + @DBNAME + '], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF';
PRINT @SQL
EXECUTE (@SQL);
END
SET @SQL = N'USE [' + @DbName + '];
IF NOT EXISTS (SELECT name FROM sys.database_principals WHERE name = ''' + @LoginName + ''')
BEGIN
CREATE USER [' + @LoginName + '] FOR LOGIN [' + @LoginName + ']
END';
PRINT @SQL
EXECUTE (@SQL);
SET @SQL = 'USE [' + @DbName + ']; ALTER ROLE [db_datareader] ADD MEMBER [' + @LoginName + ']';
PRINT @SQL
EXECUTE (@SQL);
RETURN 0
END
From a SQL Server Agent job scheduled to run daily, or on a desired schedule, you can then call the above like this:
sp_msforeachdb '
USE *DatabaseWhereStoredProcedureResides*
EXEC [usp_CreateLoginAndUserDbDataReader] ''*LoginName*'', ''*UserName*'', ''?''
'