Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a:SQL Server
Database SQL di Azure
Istanza gestita di SQL di Azure
In questo articolo sono descritti i passaggi per effettuare il provisioning delle chiavi per Always Encrypted usando il modulo PowerShell SqlServer. È possibile usare PowerShell per effettuare il provisioning di chiavi Always Encrypted con e senza separazione dei ruolioffrendo il controllo su coloro che hanno accesso alle chiavi di crittografia effettive nell'archivio chiavi e coloro che hanno accesso al database.
Note
Microsoft consiglia di usare PowerShell 7 o versione successiva quando si eseguono script di PowerShell Always Encrypted. PowerShell 7 offre un supporto multipiattaforma migliorato, prestazioni migliori e la compatibilità più recente con il modulo SqlServer (v22+), necessario per molti scenari Always Encrypted.
Per una panoramica della gestione delle chiavi Always Encrypted, incluse alcune procedure consigliate, vedere Panoramica della gestione delle chiavi per Always Encrypted. Per informazioni su come usare il modulo PowerShell SqlServer per Always Encrypted, vedere Configurare Always Encrypted tramite PowerShell.
Provisioning delle chiavi senza separazione dei ruoli
Il metodo di provisioning delle chiavi descritto in questa sezione non supporta la separazione dei ruoli tra gli amministratori della sicurezza e gli amministratori del database. Alcuni dei passaggi descritti in questa sezione combinano operazioni su chiavi fisiche con operazioni sui metadati delle chiavi. Pertanto, usare questo metodo di provisioning delle chiavi se l'organizzazione usa il modello DevOps o se il database è ospitato nel cloud e l'obiettivo principale è quello di limitare gli amministratori cloud (ma non gli amministratori del database locali) ad accedere ai dati sensibili. Non usare questo metodo se tra i potenziali avversari rientrano i DBA o se i DBA non devono avere accesso ai dati sensibili.
Prima di eseguire tutti i passaggi che comportano l'accesso a chiavi di testo non crittografato o all'archivio chiavi (identificate nella colonna Accesses plaintext keys/key store nella tabella seguente), assicurarsi che l'ambiente PowerShell venga eseguito in un computer sicuro diverso da un computer che ospita il database. Per altre informazioni, vedere Considerazioni sulla sicurezza per la gestione delle chiavi.
| Attività | Articolo | Accede alle chiavi in testo non crittografato o all'archivio delle chiavi | Accede al database |
|---|---|---|---|
| Passaggio 1: Creare una chiave principale della colonna in un archivio di chiavi. Nota: il modulo PowerShell SqlServer non supporta questo passaggio. Per eseguire questa attività da una riga di comando, usare gli strumenti specifici dell'archivio chiavi selezionato. |
Creare e archiviare chiavi master di colonna per Always Encrypted | Sì | NO |
| Passaggio 2. Avviare un ambiente PowerShell e importare il modulo PowerShell SqlServer. | Configurare Always Encrypted tramite PowerShell | NO | NO |
| Passaggio 3. Connettersi al server e al database. | Connettersi a un database | NO | Sì |
| Passaggio 4. Creare un oggetto SqlColumnMasterKeySettings che includa informazioni sul percorso della chiave master della colonna. In PowerShell SqlColumnMasterKeySettings è un oggetto presente in memoria. Utilizzare il cmdlet specifico per il proprio archivio chiavi. |
Impostazioni della chiave master di colonna del Key Vault di SQL Azure Nuovo-SqlCertificateStoreColumnMasterKeyImpostazioni New-SqlCngColumnMasterKeySettings (Imposta nuove configurazioni per la chiave principale della colonna in SQL) New-SqlCspColumnMasterKeySettings |
NO | NO |
| Passaggio 5. Creare i metadati relativi alla chiave master della colonna nel database. Nota: Non viene verificata la validità delle chiavi o dei certificati usati per generare la chiave master della colonna. |
[New-SqlColumnMasterKey](/powershell/sqlserver/sqlserver/vlatest/new-sqlcolumnmasterkey) Nota: sotto le quinte, il cmdlet rilascia l'istruzione CREATE COLUMN MASTER KEY per creare i metadati della chiave. |
NO | Sì |
| Passaggio 6. Autenticati su Azure, se la chiave master della colonna è conservata in Azure Key Vault. | Connect-AzAccount | Sì | NO |
| Passaggio 7. Ottieni un token di accesso per le Azure Key Vaults, se la chiave master della colonna è archiviata in una Azure Key Vault. | Get-AzAccessToken | NO | NO |
| Passaggio 8. Generare una nuova chiave di crittografia di colonna, crittografarla con la chiave master della colonna e creare i metadati della chiave di crittografia della colonna nel database. |
New-SqlColumnEncryptionKey Nota: usare una variante del cmdlet che genera internamente e crittografa una chiave di crittografia della colonna. Nota: Internamente, il cmdlet esegue l'istruzione CREATE COLUMN ENCRYPTION KEY per creare i metadati della chiave. |
Sì | Sì |
Archivio certificati Windows senza separazione dei ruoli (esempio)
Questo script è un esempio end-to-end di generazione di una chiave master della colonna che è un certificato nell'archivio certificati di Windows, di generazione e crittografia di una chiave di crittografia della colonna e di creazione dei metadati della chiave in un database di SQL Server.
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$DatabaseName = '<database name>',
[Parameter(Mandatory = $false)]
[string]$ServerName = "<server name>",
[Parameter(Mandatory = $false)]
[string]$CertificateSubject = "AlwaysEncryptedCert",
[Parameter(Mandatory = $false)]
[string]$CmkName = "CMK",
[Parameter(Mandatory = $false)]
[string]$CekName = "CEK"
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
Import-Module SqlServer -MinimumVersion 22.0.50 -ErrorAction Stop
Write-Host "[AE] Locating certificate '$CertificateSubject' in CurrentUser\\My"
$cert = Get-ChildItem -Path Cert:CurrentUser\My |
Where-Object { $_.Subject -eq "CN=$CertificateSubject" } |
Sort-Object NotAfter -Descending |
Select-Object -First 1
if (-not $cert) {
Write-Host "[AE] Certificate not found. Creating self-signed certificate."
$cert = New-SelfSignedCertificate `
-Subject $CertificateSubject `
-CertStoreLocation Cert:CurrentUser\My `
-KeyExportPolicy Exportable `
-Type DocumentEncryptionCert `
-KeyUsage DataEncipherment `
-KeySpec KeyExchange
}
Write-Host "[AE] Connecting to SQL Server '$ServerName' / Database '$DatabaseName'"
$connStr = "Server=$ServerName;Database=$DatabaseName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30"
try {
$database = Get-SqlDatabase -ConnectionString $connStr -ErrorAction Stop
}
catch {
Write-Error "Failed to connect to '$ServerName' database '$DatabaseName'. Verify instance name SQL2025, database existence, and local permissions."
throw
}
Write-Host "[AE] Creating CMK settings from certificate thumbprint"
$cmkSettings = New-SqlCertificateStoreColumnMasterKeySettings -CertificateStoreLocation "CurrentUser" -Thumbprint $cert.Thumbprint
Write-Host "[AE] Ensuring CMK '$CmkName' exists"
$existingCmk = Get-SqlColumnMasterKey -InputObject $database | Where-Object { $_.Name -eq $CmkName }
if (-not $existingCmk) {
New-SqlColumnMasterKey -Name $CmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings | Out-Null
}
Write-Host "[AE] Ensuring CEK '$CekName' exists"
$existingCek = Get-SqlColumnEncryptionKey -InputObject $database | Where-Object { $_.Name -eq $CekName }
if (-not $existingCek) {
New-SqlColumnEncryptionKey -Name $CekName -InputObject $database -ColumnMasterKey $CmkName | Out-Null
}
Write-Host "Completed successfully"
Azure Key Vault senza separazione dei ruoli (esempio)
Questo script è un esempio end-to-end di provisioning e configurazione di un Azure Key Vault, generazione di una column master key nel vault, generazione e crittografia di una column encryption key e creazione dei metadati della chiave in un database SQL di Azure.
param(
[Parameter(Mandatory = $true)] [string]$SubscriptionId,
[Parameter(Mandatory = $true)] [string]$ResourceGroupName,
[Parameter(Mandatory = $true)] [string]$AzureLocation,
[Parameter(Mandatory = $true)] [string]$KeyVaultName,
[Parameter(Mandatory = $true)] [string]$KeyName,
[Parameter(Mandatory = $true)] [string]$ServerName,
[Parameter(Mandatory = $true)] [string]$DatabaseName,
[string]$CmkName = "CMK",
[string]$CekName = "CEK",
[bool]$AssignRbacToCurrentPrincipal = $true
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
Import-Module Az.Accounts -ErrorAction Stop
Import-Module Az.Resources -ErrorAction Stop
Import-Module Az.KeyVault -ErrorAction Stop
Import-Module SqlServer -ErrorAction Stop
function Get-CurrentPrincipalObjectId {
param([string]$AccountId)
$userSignedIn = Get-AzADUser -SignedIn -ErrorAction SilentlyContinue
if ($userSignedIn) { return $userSignedIn.Id }
$user = Get-AzADUser -UserPrincipalName $AccountId -ErrorAction SilentlyContinue
if ($user) { return $user.Id }
$sp = Get-AzADServicePrincipal -DisplayName $AccountId -ErrorAction SilentlyContinue | Select-Object -First 1
if ($sp) { return $sp.Id }
throw "Could not resolve Microsoft Entra object id for account '$AccountId'."
}
try {
Write-Host "[AE] Signing in and selecting subscription"
Connect-AzAccount | Out-Null
$ctx = Set-AzContext -SubscriptionId $SubscriptionId
Write-Host "[AE] Ensuring resource group exists"
$resourceGroup = Get-AzResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue
if (-not $resourceGroup) {
$resourceGroup = New-AzResourceGroup -Name $ResourceGroupName -Location $AzureLocation
}
Write-Host "[AE] Ensuring key vault exists (RBAC mode)"
$vault = Get-AzKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue
if (-not $vault) {
$vault = New-AzKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -Location $AzureLocation -EnableRbacAuthorization
}
if (-not $vault.EnableRbacAuthorization) {
throw "Key Vault '$KeyVaultName' is not using RBAC authorization. Enable RBAC authorization on the vault before running this script."
}
if ($AssignRbacToCurrentPrincipal) {
Write-Host "[AE] Ensuring RBAC role assignment"
$principalSignInName = $ctx.Account.Id
$roleName = "Key Vault Crypto Officer"
$existingRole = Get-AzRoleAssignment -SignInName $principalSignInName -Scope $vault.ResourceId -RoleDefinitionName $roleName -ErrorAction SilentlyContinue
if (-not $existingRole) {
New-AzRoleAssignment -SignInName $principalSignInName -Scope $vault.ResourceId -RoleDefinitionName $roleName | Out-Null
}
}
Write-Host "[AE] Ensuring column master key material exists in Key Vault"
$akvKey = Get-AzKeyVaultKey -VaultName $KeyVaultName -Name $KeyName -ErrorAction SilentlyContinue
if (-not $akvKey) {
$akvKey = Add-AzKeyVaultKey -VaultName $KeyVaultName -Name $KeyName -Destination "Software"
}
Write-Host "[AE] Connecting to Azure SQL and creating metadata"
$keyVaultAccessToken = (Get-AzAccessToken -ResourceUrl "https://vault.azure.net").Token
$connStr = "Server=tcp:$ServerName.database.windows.net,1433;Database=$DatabaseName;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Authentication=Active Directory Interactive"
$database = Get-SqlDatabase -ConnectionString $connStr -Encrypt Mandatory
$cmkSettings = New-SqlAzureKeyVaultColumnMasterKeySettings -KeyUrl $akvKey.Key.Kid
$existingCmk = Get-SqlColumnMasterKey -InputObject $database | Where-Object { $_.Name -eq $CmkName }
if (-not $existingCmk) {
New-SqlColumnMasterKey -Name $CmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings | Out-Null
}
$existingCek = Get-SqlColumnEncryptionKey -InputObject $database | Where-Object { $_.Name -eq $CekName }
if (-not $existingCek) {
New-SqlColumnEncryptionKey -Name $CekName -InputObject $database -ColumnMasterKey $CmkName -KeyVaultAccessToken $keyVaultAccessToken | Out-Null
}
Write-Host "Completed successfully"
}
catch {
Write-Error "Script failed: $($_.Exception.Message)"
throw
}
CNG/KSP senza separazione dei ruoli (esempio)
Lo script che segue è un esempio end-to-end di generazione di una chiave master della colonna in un archivio chiavi che implementa l'API Cryptography Next Generation (CNG) generando e crittografando una chiave di crittografia della colonna e creando i metadati della chiave in un database di SQL Server.
Nell'esempio viene usato l'archivio chiavi che usa il provider di archiviazione chiavi software Microsoft. È possibile scegliere di modificare l'esempio per usare un altro archivio, ad esempio il modulo di sicurezza hardware. A tale scopo, è necessario assicurarsi che il provider di archiviazione chiavi (KSP) che implementa CNG per il dispositivo sia installato correttamente nel computer. Sostituire quindi Microsoft Software Key Storage Provider con il nome KSP del dispositivo.
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$ServerName = "<server name>",
[Parameter(Mandatory = $true)]
[string]$DatabaseName = "<database name>",
[Parameter(Mandatory = $false)]
[string]$CngKeyName = "AlwaysEncryptedKey",
[Parameter(Mandatory = $false)]
[string]$CmkName = "CMK",
[Parameter(Mandatory = $false)]
[string]$CekName = "CEK"
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
# Local key store provider and key settings.
$cngProviderName = "Microsoft Software Key Storage Provider"
$cngAlgorithmName = "RSA"
$cngKeySize = 2048
Import-Module SqlServer -ErrorAction Stop
Write-Host "[AE] Creating local CNG key '$CngKeyName'"
$cngProvider = New-Object System.Security.Cryptography.CngProvider($cngProviderName)
$cngKeyParams = New-Object System.Security.Cryptography.CngKeyCreationParameters
$cngKeyParams.Provider = $cngProvider
$cngKeyParams.KeyCreationOptions = [System.Security.Cryptography.CngKeyCreationOptions]::OverwriteExistingKey
$keySizeProperty = New-Object System.Security.Cryptography.CngProperty(
"Length",
[System.BitConverter]::GetBytes($cngKeySize),
[System.Security.Cryptography.CngPropertyOptions]::None
)
$cngKeyParams.Parameters.Add($keySizeProperty)
$cngAlgorithm = New-Object System.Security.Cryptography.CngAlgorithm($cngAlgorithmName)
[System.Security.Cryptography.CngKey]::Create($cngAlgorithm, $CngKeyName, $cngKeyParams) | Out-Null
Write-Host "[AE] Connecting to $ServerName / $DatabaseName"
$connStr = "Server=$ServerName;Database=$DatabaseName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True"
$database = Get-SqlDatabase -ConnectionString $connStr
Write-Host "[AE] Preparing column master key settings"
$cmkSettings = New-SqlCngColumnMasterKeySettings -CngProviderName $cngProviderName -KeyName $CngKeyName
Write-Host "[AE] Ensuring CMK exists"
$existingCmk = Get-SqlColumnMasterKey -InputObject $database | Where-Object { $_.Name -eq $CmkName }
if (-not $existingCmk) {
New-SqlColumnMasterKey -Name $CmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings | Out-Null
}
Write-Host "[AE] Ensuring CEK exists"
$existingCek = Get-SqlColumnEncryptionKey -InputObject $database | Where-Object { $_.Name -eq $CekName }
if (-not $existingCek) {
New-SqlColumnEncryptionKey -Name $CekName -InputObject $database -ColumnMasterKey $CmkName | Out-Null
}
Write-Host "Completed successfully"
Gestione delle chiavi con separazione dei ruoli
In questa sezione sono elencati i passaggi per la configurazione della crittografia per i casi in cui gli amministratori della sicurezza non hanno accesso al database e gli amministratori di database non hanno accesso all'archivio chiavi o alle chiavi di testo non crittografato.
Amministratore della sicurezza
Prima di eseguire tutti i passaggi che comportano l'accesso alle chiavi di testo non crittografato o all'archivio chiavi (identificato nella colonna Accesses plaintext keys/key store nella tabella seguente), assicurarsi che:
- L'ambiente di PowerShell viene eseguito su una macchina protetta diversa da un computer che ospita il database.
- gli amministratori di database dell'organizzazione non abbiano accesso al computer (cosa che vanificherebbe lo scopo della separazione dei ruoli).
Per altre informazioni, vedere Considerazioni sulla sicurezza per la gestione delle chiavi.
| Attività | Articolo | Accede alle chiavi in testo non crittografato o all'archivio delle chiavi | Accede al database |
|---|---|---|---|
| Passaggio 1: Creare una chiave principale della colonna in un archivio di chiavi. Nota: il modulo SqlServer non supporta questo passaggio. Per eseguire questa attività da una riga di comando, è necessario usare gli strumenti specifici del tipo di archivio chiavi. |
Creare e archiviare chiavi master di colonna per Always Encrypted | Sì | NO |
| Passaggio 2. Avviare una sessione di PowerShell e importare il modulo SqlServer. | Importazione del modulo SqlServer | NO | NO |
| Passaggio 3. Creare un oggetto SqlColumnMasterKeySettings che includa informazioni sul percorso della chiave master della colonna. SqlColumnMasterKeySettings è un oggetto presente in memoria (PowerShell). Utilizzare il cmdlet specifico per il proprio archivio chiavi. |
Impostazioni della chiave master di colonna del Key Vault di SQL Azure Nuovo-SqlCertificateStoreColumnMasterKeyImpostazioni New-SqlCngColumnMasterKeySettings (Imposta nuove configurazioni per la chiave principale della colonna in SQL) New-SqlCspColumnMasterKeySettings |
NO | NO |
| Passaggio 4. Autenticati su Azure, se la chiave master della colonna è conservata in Azure Key Vault. | Connect-AzAccount | Sì | NO |
| Passaggio 5. Ottieni un token di accesso per le Azure Key Vaults, se la chiave master della colonna è archiviata in una Azure Key Vault. | Get-AzAccessToken | NO | NO |
| Passaggio 6. Generare una chiave di crittografia della colonna, crittografarla con la chiave master della colonna per generare un valore crittografato della chiave di crittografia della colonna. | New-SqlColumnEncryptionKeyEncryptedValue | Sì | NO |
| Passaggio 7. Fornire il percorso della chiave master della colonna (nome del provider e percorso della chiave master della colonna) e un valore crittografato della chiave di crittografia della colonna all'amministratore di database. | Vedere gli esempi alla fine dell'articolo. | NO | NO |
DBA
Gli amministratori di database usano le informazioni ricevute dall'amministratore della sicurezza (passaggio 7 precedente) per creare e gestire i metadati della chiave Always Encrypted nel database.
| Attività | Articolo | Accede alle chiavi di testo non crittografato | Accede al database |
|---|---|---|---|
| Passaggio 1: Ottieni il percorso della chiave master della colonna e il valore crittografato della chiave di crittografia della colonna dal tuo amministratore della sicurezza. | Vedere gli esempi alla fine dell'articolo. | NO | NO |
| Passaggio 2. Avviare un ambiente PowerShell e importare il modulo SqlServer. | Configurare Always Encrypted tramite PowerShell | NO | NO |
| Passaggio 3. Connettiti al server e a un database. | Connettersi a un database | NO | Sì |
| Passaggio 4. Creare un oggetto SqlColumnMasterKeySettings che includa informazioni sul percorso della chiave master della colonna. SqlColumnMasterKeySettings è un oggetto presente in memoria. | New-SqlColumnMasterKeySettings | NO | NO |
| Passaggio 5. Creare i metadati relativi alla chiave master della colonna nel database. Nota: Non viene verificata la validità delle chiavi o dei certificati usati per generare la chiave master della colonna. |
New-SqlColumnMasterKey Nota: sotto le quinte, il cmdlet rilascia l'istruzione CREATE COLUMN MASTER KEY (Transact-SQL) per creare i metadati della chiave master della colonna. |
NO | Sì |
| Passaggio 6. Creare i metadati della chiave di crittografia della colonna nel database. | New-SqlColumnEncryptionKey Nota: gli amministratori di database usano una variazione del cmdlet che crea soltanto i metadati della chiave di crittografia della colonna. Sotto le quinte, il cmdlet rilascia l'istruzione CREATE COLUMN ENCRYPTION KEY (Transact-SQL) per creare i metadati della chiave di crittografia della colonna. |
NO | Sì |
Archivio certificati Windows con separazione dei ruoli (esempio)
Amministratore della sicurezza
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$ServerName = '<server name>',
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$DatabaseName = '<database name>',
[Parameter(Mandatory = $false)]
[string]$CertificateSubject = 'AlwaysEncryptedCert',
[Parameter(Mandatory = $false)]
[string]$CmkName = 'CMK1',
[Parameter(Mandatory = $false)]
[string]$CekName = 'CEK1',
[Parameter(Mandatory = $false)]
[string]$ExportKeyDataPath = 'C:\temp\keydata.txt'
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
Import-Module SqlServer -MinimumVersion 22.0.50 -ErrorAction Stop
Write-Host "[AE] Finding certificate '$CertificateSubject' in CurrentUser\\My"
$cert = Get-ChildItem -Path 'Cert:CurrentUser\My' |
Where-Object { $_.Subject -eq "CN=$CertificateSubject" } |
Sort-Object NotAfter -Descending |
Select-Object -First 1
if (-not $cert) {
Write-Host '[AE] Certificate not found. Creating a new self-signed certificate.'
$cert = New-SelfSignedCertificate `
-Subject $CertificateSubject `
-CertStoreLocation 'Cert:CurrentUser\My' `
-KeyExportPolicy Exportable `
-Type DocumentEncryptionCert `
-KeyUsage DataEncipherment `
-KeySpec KeyExchange
}
Write-Host "[AE] Connecting to SQL Server '$ServerName' / Database '$DatabaseName'"
$connStr = "Server=$ServerName;Database=$DatabaseName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30"
try {
$database = Get-SqlDatabase -ConnectionString $connStr -ErrorAction Stop
}
catch {
Write-Error "Failed to connect to '$ServerName' / '$DatabaseName'. Verify instance name, database, and local permissions."
throw
}
Write-Host '[AE] Building CMK settings from certificate'
$cmkSettings = New-SqlCertificateStoreColumnMasterKeySettings -CertificateStoreLocation 'CurrentUser' -Thumbprint $cert.Thumbprint
Write-Host "[AE] Ensuring CMK '$CmkName' exists"
$existingCmk = Get-SqlColumnMasterKey -InputObject $database | Where-Object { $_.Name -eq $CmkName }
if (-not $existingCmk) {
New-SqlColumnMasterKey -Name $CmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings | Out-Null
}
Write-Host "[AE] Ensuring CEK '$CekName' exists"
$existingCek = Get-SqlColumnEncryptionKey -InputObject $database | Where-Object { $_.Name -eq $CekName }
if (-not $existingCek) {
New-SqlColumnEncryptionKey -Name $CekName -InputObject $database -ColumnMasterKey $CmkName | Out-Null
}
if ($ExportKeyDataPath) {
Write-Host "[AE] Exporting key metadata to '$ExportKeyDataPath'"
$encryptedValue = New-SqlColumnEncryptionKeyEncryptedValue -TargetColumnMasterKeySettings $cmkSettings
"KeyStoreProviderName,KeyPath,EncryptedValue" | Set-Content -Path $ExportKeyDataPath -Encoding UTF8
"$($cmkSettings.KeyStoreProviderName),$($cmkSettings.KeyPath),$encryptedValue" | Add-Content -Path $ExportKeyDataPath -Encoding UTF8
}
Write-Host 'Completed successfully'
DBA
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$ServerName = 'localhost\SQL2025',
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$DatabaseName = 'AdventureWorks2025',
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$KeyDataFile = 'C:\temp\keydata.txt',
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$CmkName = 'CMK1',
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string]$CekName = 'CEK1'
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
Import-Module SqlServer -MinimumVersion 22.0.50 -ErrorAction Stop
if (-not (Test-Path -Path $KeyDataFile -PathType Leaf)) {
throw "Key data file not found: $KeyDataFile"
}
Write-Host "[AE] Loading key metadata from '$KeyDataFile'"
$keyData = Import-Csv -Path $KeyDataFile
if (-not $keyData) {
throw "Key data file '$KeyDataFile' is empty."
}
$keyDataRow = $keyData | Select-Object -First 1
if (-not $keyDataRow.KeyStoreProviderName -or -not $keyDataRow.KeyPath -or -not $keyDataRow.EncryptedValue) {
throw "Key data file must include non-empty columns: KeyStoreProviderName, KeyPath, EncryptedValue."
}
Write-Host "[AE] Connecting to SQL Server '$ServerName' / Database '$DatabaseName'"
$connStr = "Server=$ServerName;Database=$DatabaseName;Integrated Security=True;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30"
try {
$database = Get-SqlDatabase -ConnectionString $connStr -ErrorAction Stop
}
catch {
Write-Error "Failed to connect to '$ServerName' / '$DatabaseName'. Verify instance name, database, and local permissions."
throw
}
Write-Host "[AE] Building CMK settings for provider '$($keyDataRow.KeyStoreProviderName)'"
$cmkSettings = New-SqlColumnMasterKeySettings -KeyStoreProviderName $keyDataRow.KeyStoreProviderName -KeyPath $keyDataRow.KeyPath
Write-Host "[AE] Ensuring CMK '$CmkName' exists"
$existingCmk = Get-SqlColumnMasterKey -InputObject $database | Where-Object { $_.Name -eq $CmkName }
if (-not $existingCmk) {
New-SqlColumnMasterKey -Name $CmkName -InputObject $database -ColumnMasterKeySettings $cmkSettings | Out-Null
}
Write-Host "[AE] Ensuring CEK '$CekName' exists"
$existingCek = Get-SqlColumnEncryptionKey -InputObject $database | Where-Object { $_.Name -eq $CekName }
if (-not $existingCek) {
New-SqlColumnEncryptionKey -Name $CekName -InputObject $database -ColumnMasterKey $CmkName -EncryptedValue $keyDataRow.EncryptedValue | Out-Null
}
Write-Host 'Completed successfully'
Contenuti correlati
- Configurare la crittografia delle colonne usando Always Encrypted con PowerShell
- Aggiornare le chiavi Always Encrypted utilizzando PowerShell
- Sviluppare applicazioni usando Always Encrypted
- Always Encrypted
- Panoramica della gestione delle chiavi per Always Encrypted
- Creare e archiviare chiavi master di colonna per Always Encrypted
- Configurare Always Encrypted tramite PowerShell
- Effettuare il provisioning di chiavi Always Encrypted con SQL Server Management Studio
- CREATE COLUMN MASTER KEY (Transact-SQL)
- DROP COLUMN MASTER KEY (Transact-SQL)
- CREATE COLUMN ENCRYPTION KEY (Transact-SQL)
- ALTER COLUMN ENCRYPTION KEY (Transact-SQL)
- DROP COLUMN ENCRYPTION KEY (Transact-SQL)
- sys.column_master_keys (Transact-SQL)
- sys.column_encryption_keys (Transact-SQL)