Сценарий Powershell для создания групп безопасности в Azure Active Directory для управления доступом к Azure SQL - PullRequest
0 голосов
/ 03 мая 2019

Ниже приведен сценарий, который создает группы в Azure AD и затем назначает роли SQL группам. Сценарий зависит от ODBC 17 и утилиты sqlcmd версии 15, что затрудняет его использование в конвейере разработки для Azure. Мне было интересно, если кто-нибудь знает какие-либо альтернативные командлеты powershell, которые я могу использовать, чтобы выполнить запросы в сценарии против SQL. Я пробовал invoke-sqlcmd, но столкнулся с проблемой при попытке аутентификации с использованием учетной записи onmicrosoft. при использовании пользователя администратора sql, который вы создаете с базой данных SQL, я могу запустить команды для установки разрешений для целевой базы данных, но не могу выполнить запрос sql, который создает группы (FROM EXTERNAL PROVIDER) в базе данных master. Так что я немного застрял. Идея заключается в том, чтобы добавить скрипт в конвейер развертывания и позволить ему автоматизировать создание групп AAD, что позволит операционным командам управлять доступом пользователей к базе данных. Пожалуйста помоги :-) <# .SYNOPSIS Создает группы AAD, которые используются для управления доступом к ресурсам SQL Server и базы данных </p>

            .DESCRIPTION
                Based on the SQL Server and Database supplied as a input the script will create the required AAD groups required for every Azure SQL Server


            .INPUTS
                sqlServerName: Name of the sql server (IAAS) or the sql server instance (PAAS)
                sqlDatabaseName: Name of the database
                custom_vars_envResourceGroupName : Resource group the sql server resides in
                sqlAdminUser: 
                sqlAdminPassword
                ProjectId
                EnvironmentId
            .OUTPUTS
                Names of the AAD groups that was created

            .NOTES
                Script assumes that it is running in a session that is already connected to Azure RM TODO: Test least privilage
                Script assumes that it is running in a session that is already connected to Azure RM with contributor RBAC rights on the resource group TODO: Test least privilage
                If you are running this manually you need to add the sqlAdmin user into the Server admim group**** TODO: Still need to get the this automated to used the Azure DevOps Service Principle.
                Dont try this with a microsoft account it needs a AAD account to work on the db authenication
                If the qlAdminPassword is passed using clear text dont user "$" or "&" or "/" as special characters in the password.
            .EXAMPLE
            $sqlAdminPasswordnotsecure = "lhfuhwe48234#E"
            $sqlAdminSecurePassword = ConvertTo-SecureString $sqlAdminPasswordnotsecure -AsPlainText -Force
            #.\sqlAADGroupsCreator.ps1 `
                -custom_vars_envResourceGroupName "<Resource Group>" 
                -sqlServerName "<Servername>" 
                -sqlAdminUser "<eg sqlAdminUser@companydirectory.onmicrosoft.com>" 
                -sqlAdminSecurePassword "<complex password>" 
                -sqlDatabaseName "<database name>"
                -ProjectId "<Name of project>" 
                -EnvironmentId "<environment>"
            #>

            #region parameters
            Param(
                [Parameter(Mandatory = $True)][string]$custom_vars_envResourceGroupName,
                [Parameter(Mandatory = $True)][string]$sqlServerName,
                [Parameter(Mandatory = $True)][string]$sqlAdminUser,
                [Parameter(Mandatory = $True)][securestring]$sqlAdminSecurePassword,
                [Parameter(Mandatory = $True)][string]$sqlDatabaseName,
                [Parameter(Mandatory = $True)][string]$ProjectId,
                [Parameter(Mandatory = $True)][string]$EnvironmentId
            )
            $ErrorActionPreference = "Stop"
            #endregion parameters
            #region secureStringConversion
            #Convert secure string back to plain text to be used in SQL connection 
            function Get-PlainText() {
                [CmdletBinding()]
                param
                (
                    [parameter(Mandatory = $true)]
                    [System.Security.SecureString]$SecureString
                )
                BEGIN { }
                PROCESS {
                    $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString);

                    try {
                        return [Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr);
                    }
                    finally {
                        [Runtime.InteropServices.Marshal]::FreeBSTR($bstr);
                    }
                }
                END { }
            }

            #Call The function
            $sqlAdminPassword = get-plaintext -SecureString $sqlAdminSecurePassword 
            #endregion secureStringConversion
            #region manualParameter
            <#Variables that can be used during testing or running manual
            $custom_vars_envResourceGroupName   = "MATA-APP-0-0-COMMON"
            $sqlServerName = "<server name>"
            $sqlAdminUser = "<SqlAdmin@educationtestgovtnz.onmicrosoft.com>"
            $sqlAdminPassword = "<complex password>"
            $sqlDatabaseName = "<database name>"
            $EnvironmentId = "<environment variable"
            $ProjectId ="<application name or abreviation>"
            #>
            #endregion manualParameter
            #region aadGroupsCreation. 
            #Build up database server Url 
            $sqlServerURL = $sqlServerName + ".database.windows.net"
            ###Create AAD Groups based on resource group name
            $sqlAdminGroupName = $sqlReadGroupName = $sqlDbContributorGroupName = $sqlDbReadGroupName = ""
            $sqlAdminGroupName = "AL SQL " + ($ProjectId.ToUpper()) + " " + ($EnvironmentId.ToUpper()) + " Admin"
            $sqlReadGroupName = "AL SQL " + ($ProjectId.ToUpper()) + " " + ($EnvironmentId.ToUpper()) + " Read" 
            $sqlDbContributorGroupName = "AL DB " + ($sqlServerName.ToUpper()) + " " + ($sqlDatabaseName.ToUpper()) + " Contributor" 
            $sqlDbReadGroupName = "AL DB " + ($sqlServerName.ToUpper()) + " " + ($sqlDatabaseName.ToUpper()) + " Read" 


            ###Create the Groups in Azure AD if they dont exist then assign access roles to Resource Group
            #SQL LEVEL ADMIN And DB OWNER#
            #Create new group for Owner
            if ($sqlAdminGroupName -ne ((Get-AzureRmADGroup -SearchString $sqlAdminGroupName).displayname)) {
                #$slqAdminGroupDiscription = "Server Admin and database owner access to "+ $sqlServerName
                New-AzureRmADGroup `
                    -DisplayName $sqlAdminGroupName `
                    -MailNickName "NotSet"
            }

            #Update group membership of sqlAdmin group
            $groupUser = Get-AzureRmADGroupMember -GroupDisplayName $sqlAdminGroupName
            if ($sqlAdminUser -ne ($groupUser.UserPrincipalName)) {
                Add-AzureRmADGroupMember -MemberUserPrincipalName $sqlAdminUser -TargetGroupDisplayName $sqlAdminGroupName
            }
            #DB LEVEL CONTRIBUTOR###
            #Create new group for Contributor
            if ($sqlDbContributorGroupName -ne ((Get-AzureRmADGroup -SearchString $sqlDbContributorGroupName).displayname)) {
                #$sqlContributorGroupDiscription = "Contributor access to "+ $sqlDatabase
                New-AzureRmADGroup `
                    -DisplayName $sqlDbContributorGroupName `
                    -MailNickName "NotSet"
            }

            #SQL LEVEL READER###
            #Create new group for ReadOnly
            if ($sqlReadGroupName -ne ((Get-AzureRmADGroup -SearchString $sqlReadGroupName).displayname)) {
                #$RGReadOnlygroupDiscription = "Read Only access to "+ $sqlDatabase
                New-AzureRmADGroup `
                    -DisplayName $sqlReadGroupName `
                    -MailNickName "NotSet"
            }

            #DB LEVEL READER###
            #Create new group for ReadOnly
            if ($sqlDbReadGroupName -ne ((Get-AzureRmADGroup -SearchString $sqlDbReadGroupName).displayname)) {
                #$RGReadOnlygroupDiscription = "Read Only access to "+ $sqlDatabase
                New-AzureRmADGroup `
                    -DisplayName $sqlDbReadGroupName `
                    -MailNickName "NotSet"
            }
            #endregion aadGroupsCreation.
            #region setDbPermissions
            #Enable Azure AD Administrator on the SQL server (SQL / AAD Integration)
            $sqlAdminGroupNameId = (Get-AzureRmADGroup -DisplayName $sqlAdminGroupName).Id
            Set-AzureRmSqlServerActiveDirectoryAdministrator -ResourceGroupName  $custom_vars_envResourceGroupName  -ServerName $sqlServerName -DisplayName $sqlAdminGroupName -ObjectId $sqlAdminGroupNameID

            #SQL Query to create the AAD groups in SQL master and map the appropriate roles to the AAD Groups
            $createSQLUsersQuery = ""
            $createSQLUsersQuery = @" 
            CREATE USER [$sqlDbContributorGroupName] FROM EXTERNAL PROVIDER;
            CREATE USER [$sqlReadGroupName] FROM EXTERNAL PROVIDER;
            CREATE USER [$sqlDbReadGroupName] FROM EXTERNAL PROVIDER;
            "@
            #Connect to SQL sever and configure the SQL Sever level logins
            Sqlcmd -S $sqlServerURL -d master -U $sqlAdminUser -P $sqlAdminPassword -G -Q $createSQLUsersQuery

            #SQL Query to create the AAD groups in targeted sqldatabase
            $createSQLDBUsersQuery = ""
            $createSQLDBUsersQuery = @"
            CREATE USER [$sqlAdminGroupName] FROM EXTERNAL PROVIDER;
            CREATE USER [$sqlDbContributorGroupName] FROM EXTERNAL PROVIDER;
            CREATE USER [$sqlReadGroupName] FROM EXTERNAL PROVIDER;
            CREATE USER [$sqlDbReadGroupName] FROM EXTERNAL PROVIDER;
            "@
            #Connect to SQL sever and configure the SQL database level logins
            Sqlcmd -S $sqlServerURL -d $sqlDatabaseName -U $sqlAdminUser -P $sqlAdminPassword -G -Q $createSQLDBUsersQuery

            #SQL Query to set the database level permissions in targeted sqldatabase
            $setSQLDBPermissionsQuery = ""
            $setSQLDBPermissionsQuery = @"
            ALTER ROLE db_owner ADD MEMBER [$sqlAdminGroupName]
            ALTER ROLE db_datareader ADD MEMBER [$sqlReadGroupName]
            ALTER ROLE db_datawriter ADD MEMBER [$sqlDbContributorGroupName]
            ALTER ROLE db_datareader ADD MEMBER [$sqlDbContributorGroupName]
            ALTER ROLE db_datareader ADD MEMBER [$sqlDbReadGroupName]
            "@
            #Connect to SQL sever and configure the SQL database level permissions
            Sqlcmd -S $sqlServerURL -d $sqlDatabaseName -U $sqlAdminUser -P $sqlAdminPassword -G -Q $setSQLDBPermissionsQuery
            #endregion setDbPermissions

1 Ответ

1 голос
/ 30 мая 2019

Я думаю, что ваша проблема в том, что вы пытаетесь запустить следующий T-SQL в качестве администратора SQL, а не администратора AD, который был настроен для вашего экземпляра базы данных SQL Azure.

Чтобы создатьпользователь автономной базы данных на основе Azure AD (кроме администратора сервера, который владеет базой данных) подключается к базе данных с удостоверением Azure AD как пользователь с по крайней мере разрешением ALTER ANY USER.Затем используйте следующий синтаксис Transact-SQL:

CREATE USER <Azure_AD_principal_name> FROM EXTERNAL PROVIDER;

См. этот документ, поскольку он является основным документом для настройки Azure AD для базы данных SQL Azure (Single Instance / ElasticПулы), управляемый экземпляр и хранилище данных.

Что касается командлетов PowerShell, имейте в виду, что AzureRM.sql (поддерживается до 2020 года) устарел и Az.sql это новый модуль.Дополнительные сведения о интерфейсе командной строки Azure ( Link ).

Для сценариев автоматизации необходимо создать учетные данные из имени пользователя и защищенной строки:

$ passwd = ConvertTo-SecureString use a secure password here -AsPlainText -Force $ pscredential = New-Object System.Management.Automation.PSCredential ('имя / идентификатор участника службы, $ passwd) Connect-AzAccount -ServicePrincipal -Credential $ pscredential -TenantId $ tenantId * 10 * 101024 * $ params = @ {'Query' = 'СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ ИЗ ВНЕШНЕГО ПРОВАЙДЕРА' 'ConnectionString' = 'Источник данных = MYSERVER; Исходный каталог = MyDatabase; Интегрированная безопасность = True'}

Invoke-Sqlcmd @params

...