|
| 1 | +--- |
| 2 | +title: Migrate SQL Server on-premises Windows users and groups to Azure SQL Database managed instance using T-SQL DDL syntax | Microsoft Docs |
| 3 | +description: Learn about how to migrate SQL Server on-premises Windows users and groups to managed instance |
| 4 | +services: sql-database |
| 5 | +ms.service: sql-database |
| 6 | +ms.subservice: security |
| 7 | +ms.topic: tutorial |
| 8 | +author: GitHubMirek |
| 9 | +ms.author: mireks |
| 10 | +ms.reviewer: vanto |
| 11 | +ms.date: 10/22/2019 |
| 12 | +--- |
| 13 | + |
| 14 | +# Tutorial: Migrate SQL Server on-premises Windows users and groups to Azure SQL Database managed instance using T-SQL DDL syntax |
| 15 | + |
| 16 | +> [!NOTE] |
| 17 | +> The syntax used to migrate users and groups to managed instance in this article is in **public preview**. |
| 18 | +
|
| 19 | +This article takes you through the process of migrating your on-premises Windows users and groups in your SQL Server to an existing Azure SQL Database managed instance using T-SQL syntax. |
| 20 | + |
| 21 | +In this tutorial, you learn how to: |
| 22 | + |
| 23 | +> [!div class="checklist"] |
| 24 | +> - Create logins for SQL Server |
| 25 | +> - Create a test database for migration |
| 26 | +> - Create logins, users, and roles |
| 27 | +> - Backup and restore your database to managed instance (MI) |
| 28 | +> - Manually migrate users to MI using ALTER USER syntax |
| 29 | +> - Testing authentication with the new mapped users |
| 30 | +
|
| 31 | +## Prerequisites |
| 32 | + |
| 33 | +To complete this tutorial, the following prerequisites apply: |
| 34 | + |
| 35 | +- The Windows domain is federated with Azure Active Directory (Azure AD). |
| 36 | +- Access to Active Directory to create users/groups. |
| 37 | +- An existing SQL Server in your on-premises environment. |
| 38 | +- An existing managed instance. See [Quickstart: Create an Azure SQL Database managed instance](sql-database-managed-instance-get-started.md). |
| 39 | +- You can connect to your managed instance within your network. See the following articles for additional information: |
| 40 | + - [Connect your application to Azure SQL Database managed instance](sql-database-managed-instance-connect-app.md) |
| 41 | + - [Quickstart: Configure a point-to-site connection to an Azure SQL Database Managed Instance from on-premises](sql-database-managed-instance-configure-p2s.md) |
| 42 | + - [Configure public endpoint in Azure SQL Database managed instance](sql-database-managed-instance-public-endpoint-configure.md) |
| 43 | + |
| 44 | +## T-SQL DDL syntax |
| 45 | + |
| 46 | +Below are the T-SQL DDL syntax used to support SQL Server on-premises Windows users and groups migration to managed instance with Azure AD authentication. |
| 47 | + |
| 48 | +```sql |
| 49 | +-- For individual Windows users with logins |
| 50 | +ALTER USER [domainName\userName] WITH LOGIN = [loginName@domainName.com]; |
| 51 | + |
| 52 | +--For individual groups with logins |
| 53 | +ALTER USER [domainName\groupName] WITH LOGIN=[groupName] |
| 54 | +``` |
| 55 | + |
| 56 | +## Arguments |
| 57 | + |
| 58 | +_domainName_</br> |
| 59 | +Specifies the domain name of the user. |
| 60 | + |
| 61 | +_userName_</br> |
| 62 | +Specifies the name of the user identified inside the database. |
| 63 | + |
| 64 | +_= loginName\@domainName.com_</br> |
| 65 | +Remaps a user to the Azure AD login |
| 66 | + |
| 67 | +_groupName_</br> |
| 68 | +Specifies the name of the group identified inside the database. |
| 69 | + |
| 70 | +## Part 1: Create logins for SQL Server on-premises users and groups |
| 71 | + |
| 72 | +> [!IMPORTANT] |
| 73 | +> The following syntax creates a user and a group login in your SQL Server. You'll need to make sure that the user and group exist inside your Active Directory (AD) before executing the below syntax. </br> </br> |
| 74 | +> Users: testUser1, testGroupUser </br> |
| 75 | +> Group: migration - testGroupUser needs to belong to the migration group in AD |
| 76 | +
|
| 77 | +The example below creates a login in SQL Server for an account named _testUser1_ under the domain _aadsqlmi_. |
| 78 | + |
| 79 | +```sql |
| 80 | +-- Sign into SQL Server as a sysadmin or a user that can create logins and databases |
| 81 | + |
| 82 | +use master; |
| 83 | +go |
| 84 | + |
| 85 | +-- Create Windows login |
| 86 | +create login [aadsqlmi\testUser1] from windows; |
| 87 | +go; |
| 88 | + |
| 89 | +/** Create a Windows group login which contains one user [aadsqlmi\testGroupUser]. |
| 90 | +testGroupUser will need to be added to the migration group in Active Directory |
| 91 | +**/ |
| 92 | +create login [aadsqlmi\migration] from windows; |
| 93 | +go; |
| 94 | + |
| 95 | + |
| 96 | +-- Check logins were created |
| 97 | +select * from sys.server_principals; |
| 98 | +go; |
| 99 | +``` |
| 100 | + |
| 101 | +Create a database for this test. |
| 102 | + |
| 103 | +```sql |
| 104 | +-- Create a database called [migration] |
| 105 | +create database migration |
| 106 | +go |
| 107 | +``` |
| 108 | + |
| 109 | +## Part 2: Create Windows users and groups, then add roles and permissions |
| 110 | + |
| 111 | +Use the following syntax to create the test user. |
| 112 | + |
| 113 | +```sql |
| 114 | +use migration; |
| 115 | +go |
| 116 | + |
| 117 | +-- Create Windows user [aadsqlmi\testUser1] with login |
| 118 | +create user [aadsqlmi\testUser1] from login [aadsqlmi\testUser1]; |
| 119 | +go |
| 120 | +``` |
| 121 | + |
| 122 | +Check the user permissions: |
| 123 | + |
| 124 | +```sql |
| 125 | +-- Check the user in the Metadata |
| 126 | +select * from sys.database_principals; |
| 127 | +go |
| 128 | + |
| 129 | +-- Display the permissions – should only have CONNECT permissions |
| 130 | +select user_name(grantee_principal_id), * from sys.database_permissions; |
| 131 | +go |
| 132 | +``` |
| 133 | + |
| 134 | +Create a role and assign your test user to this role: |
| 135 | + |
| 136 | +```sql |
| 137 | +-- Create a role with some permissions and assign the user to the role |
| 138 | +create role UserMigrationRole; |
| 139 | +go |
| 140 | + |
| 141 | +grant CONNECT, SELECT, View DATABASE STATE, VIEW DEFINITION to UserMigrationRole; |
| 142 | +go |
| 143 | + |
| 144 | +alter role UserMigrationRole add member [aadsqlmi\testUser1]; |
| 145 | +go |
| 146 | +``` |
| 147 | + |
| 148 | +Use the following query to display user names assigned to a specific role: |
| 149 | + |
| 150 | +```sql |
| 151 | +-- Display user name assigned to a specific role |
| 152 | +SELECT DP1.name AS DatabaseRoleName, |
| 153 | + isnull (DP2.name, 'No members') AS DatabaseUserName |
| 154 | + FROM sys.database_role_members AS DRM |
| 155 | + RIGHT OUTER JOIN sys.database_principals AS DP1 |
| 156 | + ON DRM.role_principal_id = DP1.principal_id |
| 157 | + LEFT OUTER JOIN sys.database_principals AS DP2 |
| 158 | + ON DRM.member_principal_id = DP2.principal_id |
| 159 | +WHERE DP1.type = 'R' |
| 160 | +ORDER BY DP1.name; |
| 161 | +``` |
| 162 | + |
| 163 | +Use the following syntax to create a group. Then add the group to the role `db_owner`. |
| 164 | + |
| 165 | +```sql |
| 166 | +-- Create Windows group |
| 167 | +create user [aadsqlmi\migration] from login [aadsqlmi\migration]; |
| 168 | +go |
| 169 | + |
| 170 | +-- ADD 'db_owner' role to this group |
| 171 | +sp_addrolemember 'db_owner', 'aadsqlmi\migration'; |
| 172 | +go |
| 173 | + |
| 174 | +--Check the db_owner role for 'aadsqlmi\migration' group |
| 175 | +select is_rolemember('db_owner', 'aadsqlmi\migration') |
| 176 | +go |
| 177 | +-- Output ( 1 means YES) |
| 178 | +``` |
| 179 | + |
| 180 | +Create a test table and add some data using the following syntax: |
| 181 | + |
| 182 | +```sql |
| 183 | +-- Create a table and add data |
| 184 | +create table test ( a int, b int); |
| 185 | +go |
| 186 | + |
| 187 | +insert into test values (1,10) |
| 188 | +go |
| 189 | + |
| 190 | +-- Check the table values |
| 191 | +select * from test; |
| 192 | +go |
| 193 | +``` |
| 194 | + |
| 195 | +## Part 3: Backup and restore the individual user database to managed instance |
| 196 | + |
| 197 | +Create a backup of the migration database using the article [Copy Databases with Backup and Restore](/sql/relational-databases/databases/copy-databases-with-backup-and-restore), or use the following syntax: |
| 198 | + |
| 199 | +```sql |
| 200 | +use master; |
| 201 | +go |
| 202 | +backup database migration to disk = 'C:\Migration\migration.bak'; |
| 203 | +go |
| 204 | +``` |
| 205 | + |
| 206 | +Follow our [Quickstart: Restore a database to a managed instance](sql-database-managed-instance-get-started-restore.md). |
| 207 | + |
| 208 | +## Part 4: Migrate users to managed instance |
| 209 | + |
| 210 | +Execute the ALTER USER command to complete the migration process on managed instance. |
| 211 | + |
| 212 | +1. Sign into your managed instance using the SQL Admin account for managed instance. Then create your Azure AD login in the managed instance using the following syntax: |
| 213 | + |
| 214 | + ```sql |
| 215 | + use master |
| 216 | + go |
| 217 | + |
| 218 | + -- Create login for AAD user [[email protected]] |
| 219 | + create login [testUser1@aadsqlmi.net] from external provider |
| 220 | + go |
| 221 | + |
| 222 | + -- Create login for the Azure AD group [migration]. This group contains one user [[email protected]] |
| 223 | + create login [migration] from external provider |
| 224 | + go |
| 225 | + |
| 226 | + --Check the two new logins |
| 227 | + select * from sys.server_principals |
| 228 | + go |
| 229 | + ``` |
| 230 | + |
| 231 | +1. Check your migration for the correct database, table, and principals. |
| 232 | + |
| 233 | + ```sql |
| 234 | + -- Switch to the database migration that is already restored for MI |
| 235 | + use migration; |
| 236 | + go |
| 237 | + |
| 238 | + --Check if the restored table test exist and contain a row |
| 239 | + select * from test; |
| 240 | + go |
| 241 | + |
| 242 | + -- Check that the SQL on-premise Windows user/group exists |
| 243 | + select * from sys.database_principals; |
| 244 | + go |
| 245 | + -- the old user aadsqlmi\testUser1 should be there |
| 246 | + -- the old group aadsqlmi\migration should be there |
| 247 | + ``` |
| 248 | + |
| 249 | +1. Use the ALTER USER syntax to map the on-premises user to the Azure AD login. |
| 250 | + |
| 251 | + ```sql |
| 252 | + /** Execute the ALTER USER command to alter the Windows user [aadsqlmi\testUser1] |
| 253 | + to map to the Azure AD user [email protected] |
| 254 | + **/ |
| 255 | + alter user [aadsqlmi\testUser1] with login = [[email protected]]; |
| 256 | + go |
| 257 | +
|
| 258 | + -- Check the principal |
| 259 | + select * from sys.database_principals; |
| 260 | + go |
| 261 | + -- New user [email protected] should be there instead |
| 262 | + |
| 263 | + --Check new user permissions - should only have CONNECT permissions |
| 264 | + select user_name(grantee_principal_id), * from sys.database_permissions; |
| 265 | + go |
| 266 | +
|
| 267 | + -- Check a specific role |
| 268 | + -- Display Db user name assigned to a specific role |
| 269 | + SELECT DP1.name AS DatabaseRoleName, |
| 270 | + isnull (DP2.name, 'No members') AS DatabaseUserName |
| 271 | + FROM sys.database_role_members AS DRM |
| 272 | + RIGHT OUTER JOIN sys.database_principals AS DP1 |
| 273 | + ON DRM.role_principal_id = DP1.principal_id |
| 274 | + LEFT OUTER JOIN sys.database_principals AS DP2 |
| 275 | + ON DRM.member_principal_id = DP2.principal_id |
| 276 | + WHERE DP1.type = 'R' |
| 277 | + ORDER BY DP1.name; |
| 278 | + ``` |
| 279 | + |
| 280 | +1. Use the ALTER USER syntax to map the on-premises group to the Azure AD login. |
| 281 | + |
| 282 | + ```sql |
| 283 | + /** Execute ALTER USER command to alter the Windows group [aadsqlmi\migration] |
| 284 | + to the Azure AD group login [migration] |
| 285 | + **/ |
| 286 | + alter user [aadsqlmi\migration] with login = [migration]; |
| 287 | + -- old group migration is changed to Azure AD migration group |
| 288 | + go |
| 289 | +
|
| 290 | + -- Check the principal |
| 291 | + select * from sys.database_principals; |
| 292 | + go |
| 293 | + |
| 294 | + --Check the group permission - should only have CONNECT permissions |
| 295 | + select user_name(grantee_principal_id), * from sys.database_permissions; |
| 296 | + go |
| 297 | + |
| 298 | + --Check the db_owner role for 'aadsqlmi\migration' user |
| 299 | + select is_rolemember('db_owner', 'migration') |
| 300 | + go |
| 301 | + -- Output 1 means 'YES' |
| 302 | + ``` |
| 303 | + |
| 304 | +## Part 5: Testing Azure AD user or group authentication |
| 305 | + |
| 306 | +Test authenticating to managed instance using the user previously mapped to the Azure AD login using the ALTER USER syntax. |
| 307 | + |
| 308 | +1. Log into the federated VM using your MI subscription as `aadsqlmi\testUser1` |
| 309 | +1. Using SQL Server Management Studio (SSMS), sign into your managed instance using **Active Directory Integrated** authentication, connecting |
| 310 | +to the database `migration`. |
| 311 | + 1. You can also sign in using the testUser1@aadsqlmi.net credentials with the SSMS option **Active Directory – Universal with MFA support**. However, in this case, you can't use the Single Sign On mechanism and you must type a password. You won't need to use a federated VM to log in to your managed instance. |
| 312 | +1. As part of the role member **SELECT**, you can select from the `test` table |
| 313 | + |
| 314 | + ```sql |
| 315 | + Select * from test -- and see one row (1,10) |
| 316 | + ``` |
| 317 | + |
| 318 | + |
| 319 | +Test authenticating to a managed instance using a member of a Windows group `migration`. The user `aadsqlmi\testGroupUser` should have been added to the group `migration` before the migration. |
| 320 | + |
| 321 | +1. Log into the federated VM using your MI subscription as `aadsqlmi\testGroupUser` |
| 322 | +1. Using SSMS with **Active Directory Integrated** authentication, connect to the MI server and the database `migration` |
| 323 | + 1. You can also sign in using the testGroupUser@aadsqlmi.net credentials with the SSMS option **Active Directory – Universal with MFA support**. However, in this case, you can't use the Single Sign On mechanism and you must type a password. You won't need to use a federated VM to log into your managed instance. |
| 324 | +1. As part of the `db_owner` role, you can create a new table. |
| 325 | + |
| 326 | + ```sql |
| 327 | + -- Create table named 'new' with a default schema |
| 328 | + Create table dbo.new ( a int, b int) |
| 329 | + ``` |
| 330 | + |
| 331 | +> [!NOTE] |
| 332 | +> Due to a known design issue for Azure SQL DB, a create a table statement executed as a member of a group will fail with the following error: </br> </br> |
| 333 | +> `Msg 2760, Level 16, State 1, Line 4 |
| 334 | +The specified schema name "[email protected]" either does not exist or you do not have permission to use it.` </br > </br > |
| 335 | +> The current workaround is to create a table with an existing schema in the case above <dbo.new> |
| 336 | + |
| 337 | +## Next steps |
| 338 | + |
| 339 | +- [Tutorial: Migrate SQL Server to an Azure SQL Database managed instance offline using DMS](../dms/tutorial-sql-server-to-managed-instance.md?toc=/azure/sql-database/toc.json) |
0 commit comments