sp_help_revlogin causing loss of characters on LOGINs with Unicode characters

I'll preface this by saying that it's much better to do this via some tool, rather than cobbling together something in T-SQL. You can use SSMS or similar.

Be that as it may:

The script you have posted has multiple issues.

  • The primary issue you were facing: use of varchar instead of nvarchar, means that other languages get clobbered.
  • Use of a cursor unnecessarily. This can be done in a single query using string aggregation.
  • The binary-to-hex procedure is complete overkill, as this can be done with a simple CONVERT. Even if it were necessary, it could have been done with an inline TVF.
  • Some missing QUOTENAME usages, to quote the names correctly.
  • It only adds fixed server roles, rather than any user-defined roles
  • It only adds CONNECT permissions, rather than any other permissions.
  • Usage of the deprecated sys.syslogins, which was replaced in 2005.

The following script is a full rewrite.

  • It returns all SQL logins and Windows logins based on AD users or AD groups (but not any other logins such as certificate based ones).
  • It adds all server-level permissions.
  • It adds all server roles, including user-defined.
CREATE OR ALTER PROCEDURE [dbo].[sp_help_revlogin]   
      @login_name sysname = NULL 
AS

SELECT
    '
/* sp_help_revlogin script
** Generated ' + CONVERT(nvarchar(30), GETDATE()) + ' on ' + QUOTENAME(@@SERVERNAME) + ' */
GO
' + STRING_AGG(CONCAT(
    '
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N',
    QUOTENAME(p.name, ''''),
    ')
BEGIN
    CREATE LOGIN ',
    QUOTENAME(p.name),
    CASE WHEN p.type IN ('G', 'U') THEN ' FROM WINDOWS' END,
    ' WITH',
    CASE WHEN p.type = 'S' THEN CONCAT(
        ' PASSWORD = ',
        CONVERT(nvarchar(max), ISNULL(l.password_hash, 0x0), 1),
        ' HASHED, SID = ',
        CONVERT(nvarchar(max), p.sid, 1),
        CASE WHEN l.is_policy_checked = 0 THEN ', CHECK_POLICY = OFF' END,
        CASE WHEN l.is_expiration_checked = 1 THEN ', CHECK_EXPIRATION = ON' END,
        ','
      ) END,
    ' DEFAULT_DATABASE = ',
    QUOTENAME(p.default_database_name),
    ', DEFAULT_LANGUAGE = ',
    QUOTENAME(p.default_language_name),
    ';
END;
GO
',
    CASE WHEN p.is_disabled = 1 THEN
      'ALTER LOGIN ' + QUOTENAME(p.name) + ' DISABLE;
GO
'
      END,
    r.roles + '
GO
',
    sp.perms + '
GO
'
    ), N'
') WITHIN GROUP (ORDER BY p.name)

FROM sys.server_principals p
LEFT JOIN sys.sql_logins l ON l.principal_id = p.principal_id

CROSS APPLY (
    SELECT STRING_AGG(

        'EXEC sp_addsrvrolemember @loginame = ' + p2.name + ', @rolename = ' + QUOTENAME(r.name, '''') + ';'
      , '
GO
'
    )
    FROM sys.server_role_members rm
    JOIN sys.server_principals r ON r.principal_id = rm.role_principal_id
    CROSS APPLY (VALUES( QUOTENAME(p.name, '''') )) p2(name)  -- error 8124 
    WHERE rm.member_principal_id = p.principal_id
) r(roles)

CROSS APPLY (
    SELECT STRING_AGG(CONCAT(

        CASE WHEN sp.state = 'W' THEN N'GRANT' ELSE sp.state_desc END,
        ' ',
        sp.permission_name  COLLATE DATABASE_DEFAULT,
        ' TO ',
        p2.name,
        CASE WHEN sp.state = 'W' THEN N' WITH GRANT OPTION' END,
        ';'
      ), N'
GO
'
    )
    FROM sys.server_permissions sp
    CROSS APPLY (VALUES( QUOTENAME(p.name, '''') )) p2(name)  -- error 8124 
    WHERE sp.grantee_principal_id = p.principal_id
      AND sp.class = 100
) sp(perms)

WHERE p.type IN ('S', 'G', 'U')
  AND p.name <> 'sa'
  AND (p.name = @login_name OR @login_name IS NULL);

GO

db<>fiddle