Set-ColumnEncryption
DBSystems: Configures column encryption for a SQL Server database
#Requires -Version 5.0
#Requires -Modules SQLServer
[CmdLetBinding()]
Param(
[Parameter(Mandatory = $true)]
[string]$ServerInstance,
[Parameter(Mandatory = $true)]
[string]$DatabaseName,
[Parameter(Mandatory = $true)]
[string]$SettingsCsvFile,
[pscredential]$ServerCredential,
[switch]$KeepCheckForeignKeyConstraints,
[string]$LogFileDirectory,
[int]$MaxDivergingIterations,
[int]$MaxDowntimeInSeconds,
[int]$MaxIterationDurationInDays,
[int]$MaxIterations,
[switch]$UseOnlineApproach,
[string]$CsvDelimiter = ';',
[ValidateSet('Unicode','UTF7','UTF8','ASCII','UTF32','BigEndianUnicode','Default','OEM')]
[string]$FileEncoding = 'UTF8',
[int]$ConnectionTimeout = 30
)
function Get-SqlServerInstanceInternal {
[CmdLetBinding()]
Param(
[Parameter(Mandatory = $true)]
[string]$ServerInstance,
[pscredential]$ServerCredential,
[int]$ConnectionTimeout = 30
)
try {
[hashtable]$cmdArgs = @{
'ErrorAction' = 'Stop'
'Confirm' = $false
'ServerInstance' = $ServerInstance
'ConnectionTimeout' = $ConnectionTimeout
}
if ($null -ne $ServerCredential) {
$cmdArgs.Add('Credential', $ServerCredential)
}
return Get-SqlInstance @cmdArgs
} catch {
throw
}
}
function Get-SqlDatabaseInternal {
[CmdLetBinding()]
Param(
[Parameter(Mandatory = $true)]
[object]$ServerInstance,
[Parameter(Mandatory = $true)]
[string]$DatabaseName
)
try {
[hashtable]$cmdArgs = @{
'ErrorAction' = 'Stop'
'InputObject' = $ServerInstance
'Name' = $DatabaseName
'Confirm' = $false
}
return Get-SqlDatabase @cmdArgs
} catch {
throw
}
}
Import-Module SQLServer
try {
$instance = Get-SqlServerInstanceInternal -ServerInstance $ServerInstance -ServerCredential $ServerCredential -ConnectionTimeout $ConnectionTimeout
$db = Get-SqlDatabaseInternal -DatabaseName $DatabaseName -ServerInstance $instance
if (-not (Test-Path -Path $SettingsCsvFile)) {
throw "CSV file not found: $SettingsCsvFile"
}
$settings = Import-Csv -Path $SettingsCsvFile -Delimiter $CsvDelimiter -Encoding $FileEncoding -Header @('ColumnName', 'EncryptionType', 'EncryptionKey') -ErrorAction Stop
$colEncry = @()
foreach ($item in $settings) {
if ($item.EncryptionType -eq 'EncryptionType' -or [string]::IsNullOrWhiteSpace($item.ColumnName)) {
continue
}
$setParams = @{
'ColumnName' = $item.ColumnName
'EncryptionType' = $item.EncryptionType
}
if ($item.EncryptionType -ne 'Plaintext' -and -not [string]::IsNullOrWhiteSpace($item.EncryptionKey)) {
$setParams.Add('EncryptionKey', $item.EncryptionKey)
}
$colEncry += New-SqlColumnEncryptionSettings @setParams
}
if ($colEncry.Count -eq 0) {
throw "No valid encryption settings found in CSV file."
}
[hashtable]$cmdArgs = @{
'ErrorAction' = 'Stop'
'ColumnEncryptionSettings' = $colEncry
'InputObject' = $db
}
if (-not [string]::IsNullOrWhiteSpace($LogFileDirectory)) {
$cmdArgs.Add('LogFileDirectory', $LogFileDirectory)
}
if ($UseOnlineApproach) {
$cmdArgs.Add('UseOnlineApproach', $true)
$cmdArgs.Add('KeepCheckForeignKeyConstraints', $KeepCheckForeignKeyConstraints.ToBool())
if ($MaxIterations -gt 0) { $cmdArgs.Add('MaxIterations', $MaxIterations) }
if ($MaxDowntimeInSeconds -gt 0) { $cmdArgs.Add('MaxDowntimeInSeconds', $MaxDowntimeInSeconds) }
if ($MaxIterationDurationInDays -gt 0) { $cmdArgs.Add('MaxIterationDurationInDays', $MaxIterationDurationInDays) }
if ($MaxDivergingIterations -gt 0) { $cmdArgs.Add('MaxDivergingIterations', $MaxDivergingIterations) }
}
$result = Set-SqlColumnEncryption @cmdArgs | Select-Object *
Write-Output $result
} catch {
throw
}Specifies the name of the target computer including the instance name, e.g. MyServer\Instance
Specifies the name of the SQL database to modify
Specifies the path to a CSV file containing the encryption settings. Required columns: ColumnName (e.g. Table.Col), EncryptionType (Deterministic, Randomized, or Plaintext), EncryptionKey (Name of CEK)
Specifies a PSCredential object for the connection to the SQL Server. ServerCredential is ONLY used for SQL Logins. When you are using Windows Authentication you don't specify -Credential. It is picked up from your current login.
If set, check semantics of foreign key constraints are preserved
If set, a log file will be created in the specified directory
Specifies the maximum number of consecutive catch-up iterations allowed before failing
Specifies the maximum downtime (in seconds) allowed for the source table
Specifies the maximum time (in days) for a single iteration
Specifies the maximum number of iterations in the catch-up phase
If set, the cmdlet will use the online approach to minimize downtime
Specifies the delimiter used in the CSV file (defaults to ';')
Specifies the character encoding of the CSV file (defaults to 'UTF8')
Specifies the time period to retry the command on the target server