Azure SQL 数据库:使用 PowerShell、参数化 SQL 脚本和 Azure Key Vault 创建用户

Azure SQL DB: create users with PowerShell, parametrized SQL scripts and Azure Key Vault

目标:

代码:

DECLARE @username VARCHAR(50) = '$(username)';
DECLARE @password VARCHAR(50) = '$(password)';
DECLARE @schema VARCHAR(50) = 'xxx';

DECLARE @query NVARCHAR(MAX) = '
IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE NAME = ' + CHAR(39) + @username + CHAR(39) + ')
    BEGIN
        CREATE USER ' + @username + ' WITH PASSWORD = ' + CHAR(39) + @password + CHAR(39) + ';
        ALTER USER ' + @username + ' WITH DEFAULT_SCHEMA = ' + @schema + ';
    END

--ALTER ROLE db_datareader ADD MEMBER @username;
--ALTER ROLE db_datawriter ADD MEMBER @username;
GRANT SELECT ON SCHEMA::' + @schema + ' TO ' + @username + ';
GRANT INSERT ON SCHEMA::' + @schema + ' TO ' + @username + ';
GRANT UPDATE ON SCHEMA::' + @schema + ' TO ' + @username + ';
GRANT DELETE ON SCHEMA::' + @schema + ' TO ' + @username + ';
GRANT EXECUTE ON SCHEMA::' + @schema + ' TO ' + @username + ';
';

EXECUTE (@query);
  • 对于 PowerShell:
    • 必须在具有创建用户权限的连接字符串中使用用户及其凭据
    • 需要 'hack' 从安全密码到明文密码才能在 SQL 脚本
    • 中分别使用连接字符串中的密码
    • 它假定 SQL 脚本在同一级别或 PowerShell 脚本的某个子文件夹
    • 需要安装SQL模块
      • Install-module -Name SqlServer -Scope CurrentUser

代码:

$passwordAdminSecure = (Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name $adminSecretName).SecretValue
$passwordAdminPlain = (New-Object PSCredential "user",$passwordAdminSecure).GetNetworkCredential().Password

$dbConnectionString = "Server=tcp:$serverName.database.windows.net,1433;Initial Catalog=$dbName;Persist Security Info=False;User ID=$username;Password=$passwordAdminPlain;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"

$script = Get-ChildItem -Path $PSScriptRoot -Include scriptname.sql -Recurse

$userToCreate = 'xxx'
$passwordUserSecure = (Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name $userSecretName).SecretValue
$passwordUserPlain = (New-Object PSCredential "user",$passwordUserSecure).GetNetworkCredential().Password

Invoke-Sqlcmd -InputFile $script -ConnectionString $dbConnectionString -Variable username=$userToCreate, password=$passwordUserPlain -Verbose

Write-Host "Added user $userToCreate!"
  • 通过以下查询,您可以检查具有分配权限的现有用户

代码:

SELECT DISTINCT 
    pr.principal_id, 
    pr.name, 
    pr.type_desc, 
    pr.authentication_type_desc, 
    pe.state_desc, 
    pe.permission_name
FROM sys.database_principals AS pr
JOIN sys.database_permissions AS pe
    ON pe.grantee_principal_id = pr.principal_id;

I repeatedly ran into troubles with the correct notation for the parameters.

您正在混合使用 SQLCMD 变量和 TSQL 变量。这很棘手。

从 PowerShell 编写 SQL 时,我发现让 Powershell 构建最终查询要好得多。像这样:

$username = "joe"
$password = "23948230948"
$schema = "dbo"


$sql = @"
IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE NAME = '$username')
    BEGIN
        CREATE USER $username WITH PASSWORD = '$password';
        ALTER USER $username WITH DEFAULT_SCHEMA = $schema;
    END


GRANT SELECT ON SCHEMA::$schema TO $username;
GRANT INSERT ON SCHEMA::$schema TO $username;
GRANT UPDATE ON SCHEMA::$schema TO $username;
GRANT DELETE ON SCHEMA::$schema TO $username;
GRANT EXECUTE ON SCHEMA::$schema TO $username;
"@

invoke-sqlcmd $sql