When creating Logins or Users based on a Windows account, that Windows Login or Windows Group needs to be accessible as it's the source of the SID.
Now, it is possible to create a Login by supplying an SID, but that only works for SIDs that are for SQL Server accounts.
Also, Users created using WITHOUT LOGIN
aren't simply orphaned Users that can be connected to a Login later. True "Users without a Login" are permanently "without a Login". When creating a User based on a Windows account and also using WITHOUT LOGIN
, the WITHOUT LOGIN
part is pretty much ignored as it isn't relevant given that SQL Server isn't handling the authentication (Windows / Active Directory is).
If you do create a real User without a Login, you won't be able to connect it to a Login later:
Msg 33016, Level 16, State 1, Line XXXXX
The user cannot be remapped to a login. Remapping can only be done for users that were mapped to Windows or SQL logins.
Creating a SQL Server Login with the intention of mapping it to your client's Windows account later, that also won't work:
Msg 33017, Level 16, State 1, Line XXXXX
Cannot remap a user of one type to a login of a different type. For example, a SQL user must be mapped to a SQL login; it cannot be remapped to a Windows login.
One thing you can do, though, is remap a User's name and SID at the same time with ALTER USER
. I just tried this with a Windows account associated with only a User (no Login). I had deleted the Windows account and then remapped the User, and the principal_id
(in sys.database_principals
), and even the create_date
of that principal, stayed the same.
This leaves two possibilities as far as I can see:
Remap Users created locally:
- Create dummy Windows accounts in your Domain (but with the client's account names to help keep everything straight), or even local Windows accounts on the computer itself.
CREATE USER [YourDomain\ClientLoginName];
- When finished, Detach / Backup the database and then Attach / Restore it onto the client system.
- If the client's instance doesn't already have the Logins created, you will then need to create the Logins.
- After creating the Logins, remap the Users using:
ALTER USER [YourDomain\ClientLoginName]
WITH LOGIN = [ClientDomain\ClientLoginName];
Get the correct client Logins / SIDs ahead of time:
- Install SQL Server Express 2016 or even SQL Server Express LocalDB 2016 at the client (assuming they don't have it, else use their existing SQL Server 2016 if they do have it)
- Create a new database in SQL Server 2016
- Add the desired Users from the client's Domain
- Detach / Backup the database and then Attach / Restore it onto your system.
- When finished, Detach / Backup the database and then Attach / Restore it onto the client system.
- If the client's instance doesn't already have the Logins created, you will then need to create the Logins (but not the Users as they already exist in the database).
This option doesn't require any remapping. As long as you don't need to test the database on your system because these Users won't be able to log in. But, you should still be able to grant them permissions and add them to database roles (it worked in my limited test).
IN BOTH CASES: The database will be owned by the Login that did the Attach / Restore, so you will most likely need to:
ALTER AUTHORIZATION ON DATABASE::[{RestoredDatabase}]
TO [{LoginWhoShouldOwnTheDatabase}];
Generate Scripts
feature in the UI when selecting a database. However, thedomain\user
SQL Server Logins which were generated in the script were not created on the new server, due to the fact that I had set the script to continue on error and because the user couldn't be created because of the issues already mentioned by others in the answers. So you are stuck with the solutions mentioned in the answers here. Good luck.