Membuat dan mengelola pekerjaan elastis dengan menggunakan PowerShell

Berlaku untuk:Azure SQL Database

Artikel ini menyediakan tutorial dan contoh untuk mulai bekerja dengan pekerjaan elastis menggunakan PowerShell. Pekerjaan elastis memungkinkan berjalannya satu atau beberapa skrip Transact-SQL (T-SQL) secara paralel di banyak database.

Dalam tutorial end-to-end ini, Anda mempelajari langkah-langkah yang diperlukan untuk menjalankan kueri di beberapa database:

  • Membuat agen pekerjaan elastis
  • Membuat kredensial pekerjaan sehingga pekerjaan dapat menjalankan skrip pada targetnya
  • Tentukan target (server, kumpulan elastis, database) yang ingin Anda jalankan pekerjaannya
  • Membuat kredensial cakupan database dalam database target sehingga agen menyambungkan dan menjalankan pekerjaan
  • Membuat pekerjaan
  • Menambahkan langkah-langkah pekerjaan ke dalam pekerjaan
  • Mulai menjalankan pekerjaan
  • Memantau pekerjaan

Prasyarat

Pekerjaan database elastis memiliki satu set cmdlet PowerShell.

Cmdlet ini diperbarui pada November 2023.

Menginstal cmdlet pekerjaan elastis terbaru

Jika Anda tidak memiliki langganan Azure, buat akun gratis sebelum Anda memulai.

Jika belum ada, instal versi Az.Sql terbaru modul dan SqlServer . Jalankan perintah berikut ini di PowerShell dengan akses administratif.

# installs the latest PackageManagement and PowerShellGet packages
Find-Package PackageManagement | Install-Package -Force
Find-Package PowerShellGet | Install-Package -Force

# Restart your powershell session with administrative access

# Install and import the Az.Sql module, then confirm
Install-Module -Name Az.Sql
Import-Module Az.Sql
Install-Module -Name SqlServer
Import-Module SqlServer

Untuk detailnya, lihat Memasang modul SQL Server PowerShell.

Membuat sumber daya yang diperlukan

Membuat agen pekerjaan elastis memerlukan database (S1 atau lebih tinggi) untuk digunakan sebagai database pekerjaan elastis.

Skrip berikut membuat grup sumber daya, server, dan database baru untuk digunakan sebagai database pekerjaan elastis. Skrip kedua membuat server kedua dengan dua database kosong untuk menjalankan pekerjaan.

Pekerjaan elastis tidak memiliki persyaratan penamaan khusus sehingga Anda dapat menggunakan konvensi penamaan apa pun yang Anda inginkan, selama sesuai dengan persyaratan Azure apa pun. Jika Anda sudah membuat database kosong ke server sebagai database pekerjaan elastis, lewati untuk Membuat agen pekerjaan elastis.

Mengonfigurasi aturan firewall dengan New-AzSqlServerFirewallRule tidak perlu saat menggunakan titik akhir privat pekerjaan elastis.

# Sign in to your Azure account
Connect-AzAccount

# The SubscriptionId in which to create these objects
$SubscriptionId = '<your subscription id>'
# Set subscription context, important if you have access to more than one subscription.
Set-AzContext -SubscriptionId $subscriptionId 

# Create a resource group
Write-Output "Creating a resource group..."
$resourceGroupName = Read-Host "Please enter a resource group name"
$location = Read-Host "Please enter an Azure Region, for example westus2"
$rg = New-AzResourceGroup -Name $resourceGroupName -Location $location
$rg

# Create an Azure SQL logical server
Write-Output "Creating a server..."
$agentServerName = Read-Host "Please enter an agent server name"
$agentServerName = $agentServerName + "-" + [guid]::NewGuid()
$adminLogin = Read-Host "Please enter the server admin name"
$adminPassword = Read-Host "Please enter the server admin password"
$adminPasswordSecure = ConvertTo-SecureString -String $AdminPassword -AsPlainText -Force
$adminCred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $adminLogin, $adminPasswordSecure
$parameters = @{
    ResourceGroupName = $resourceGroupName 
    Location = $location
    ServerName = $agentServerName 
    SqlAdministratorCredentials = ($adminCred)    
}
$agentServer = New-AzSqlServer @parameters

# Set server firewall rules to allow all Azure IPs
# Unnecessary if using an elastic jobs private endpoint
Write-Output "Creating a server firewall rule..."
$agentServer | New-AzSqlServerFirewallRule -AllowAllAzureIPs -FirewallRuleName "Allowed IPs"
$agentServer

# Create the job database
Write-Output "Creating a blank database to be used as the Job Database..."
$jobDatabaseName = "JobDatabase"
$parameters = @{
    ResourceGroupName = $resourceGroupName 
    ServerName = $agentServerName 
    DatabaseName = $jobDatabaseName 
    RequestedServiceObjectiveName = "S1"
}
$jobDatabase = New-AzSqlDatabase @parameters
$jobDatabase
# Create a target server and sample databases - uses the same credentials
Write-Output "Creating target server..."
$targetServerName = Read-Host "Please enter a target server name"
$targetServerName = $targetServerName + "-" + [guid]::NewGuid()
$parameters = @{
    ResourceGroupName= $resourceGroupName
    Location= $location 
    ServerName= $targetServerName
    ServerVersion= "12.0"
    SqlAdministratorCredentials= ($adminCred)
}
$targetServer = New-AzSqlServer @parameters

# Set target server firewall rules to allow all Azure IPs
# Unnecessary if using an elastic jobs private endpoint
$targetServer | New-AzSqlServerFirewallRule -AllowAllAzureIPs 

# Set the target firewall to include your desired IP range. 
# Change the following -StartIpAddress and -EndIpAddress values.
$parameters = @{
    StartIpAddress = "0.0.0.0" 
    EndIpAddress = "0.0.0.0"
    FirewallRuleName = "AllowAll"
}
$targetServer | New-AzSqlServerFirewallRule @parameters
$targetServer

# Create two sample databases to execute jobs against
$parameters = @{
    ResourceGroupName = $resourceGroupName 
    ServerName = $targetServerName 
    DatabaseName = "database1"
}
$db1 = New-AzSqlDatabase @parameters
$db1
$parameters = @{
    ResourceGroupName = $resourceGroupName 
    ServerName = $targetServerName 
    DatabaseName = "database2"
}
$db2 = New-AzSqlDatabase @parameters
$db2

Membuat agen pekerjaan elastis

Agen pekerjaan elastis adalah sumber daya Azure untuk membuat, menjalankan, dan mengelola pekerjaan. Agen mengeksekusi pekerjaan berdasarkan jadwal atau sebagai tugas satu waktu. Semua tanggal dan waktu dalam pekerjaan elastis berada di zona waktu UTC.

Cmdlet New-AzSqlElasticJobAgent memerlukan database di Azure SQL Database sudah ada, sehingga resourceGroupNameparameter , serverName, dan databaseName semuanya harus menunjuk ke sumber daya yang ada. Demikian pula, Set-AzSqlElasticJobAgent dapat digunakan untuk memodifikasi agen pekerjaan elastis.

Untuk membuat agen pekerjaan elastis baru menggunakan autentikasi Microsoft Entra dengan identitas terkelola yang ditetapkan pengguna, gunakan IdentityType argumen dan IdentityID dari New-AzSqlElasticJobAgent:

Write-Output "Creating job agent..."
$agentName = Read-Host "Please enter a name for your new elastic job agent"
$parameters = @{
    Name = $agentName 
    IdentityType = "UserAssigned" 
    IdentityID = "/subscriptions/abcd1234-caaf-4ba9-875d-f1234/resourceGroups/contoso-jobDemoRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/contoso-UMI"
}
$jobAgent = $jobDatabase | New-AzSqlElasticJobAgent @parameters
$jobAgent

Untuk membuat agen pekerjaan elastis baru menggunakan kredensial cakupan database, IdentityType dan IdentityID tidak disediakan.

Membuat autentikasi pekerjaan

Agen pekerjaan elastis harus dapat mengautentikasi ke setiap server atau database target.

Seperti yang tercakup dalam Membuat autentikasi agen pekerjaan:

  • Gunakan pengguna database yang dipetakan ke identitas terkelola yang ditetapkan pengguna (UMI) untuk mengautentikasi ke server target/database.
    • Menggunakan UMI dengan autentikasi Microsoft Entra (sebelumnya Azure Active Directory) adalah metode yang direkomendasikan. Cmdlet PowerShell sekarang memiliki argumen baru untuk mendukung autentikasi Microsoft Entra dengan UMI.
    • Ini adalah metode autentikasi yang direkomendasikan.
  • Gunakan pengguna database yang dipetakan ke kredensial cakupan database di setiap database.
    • Sebelumnya, kredensial cakupan database adalah satu-satunya opsi bagi agen pekerjaan elastis untuk mengautentikasi ke target.

Menggunakan autentikasi Microsoft Entra dengan UMI untuk autentikasi ke target

Untuk menggunakan metode autentikasi Microsoft Entra (sebelumnya Azure Active Directory) yang direkomendasikan ke identitas terkelola (UMI) yang ditetapkan pengguna, ikuti langkah-langkah ini. Agen pekerjaan elastis terhubung ke server logis target/database yang diinginkan melalui autentikasi Entra.

Selain pengguna login dan database, perhatikan penambahan GRANT perintah dalam skrip berikut. Izin ini diperlukan untuk skrip yang kami pilih untuk pekerjaan contoh berikut. Pekerjaan Anda mungkin memerlukan izin yang berbeda. Karena contoh membuat tabel baru dalam database yang ditargetkan, pengguna database di setiap database target memerlukan izin yang tepat agar berhasil dijalankan.

Di setiap server target/database, buat pengguna mandiri yang dipetakan ke UMI.

  • Jika pekerjaan elastis memiliki server logis atau target kumpulan, Anda harus membuat pengguna yang terkandung yang dipetakan ke UMI dalam master database server logis target.
  • Misalnya, untuk membuat login database mandiri dalam master database, dan pengguna dalam database pengguna, berdasarkan identitas terkelola yang ditetapkan pengguna (UMI) bernama job-agent-UMI:
$targetServer = '<target server name>'
$adminLogin = '<username>'
$adminPassword = '<password>'

# For the target logical server, in the master database
# Create the login named [job-agent-UMI] based on the UMI [job-agent-UMI], and a user
$params = @{
  'database' = 'master'
  'serverInstance' =  $targetServer.ServerName + '.database.windows.net'
  'username' = $adminLogin
  'password' = $adminPassword
  'outputSqlErrors' = $true
  'query' = 'CREATE LOGIN [job-agent-UMI] FROM EXTERNAL PROVIDER;'
}
Invoke-SqlCmd @params
$params.query = "CREATE USER [job-agent-UMI] FROM LOGIN [job-agent-UMI]"
Invoke-SqlCmd @params

# For each target database in the target logical server
# Create a database user from the job-agent-UMI login 
$targetDatabases = @( $db1.DatabaseName, $Db2.DatabaseName )
$createJobUserScript =  "CREATE USER [job-agent-UMI] FROM LOGIN [job-agent-UMI]"

# Grant permissions as necessary. For example ALTER and CREATE TABLE:
$grantAlterSchemaScript = "GRANT ALTER ON SCHEMA::dbo TO [job-agent-UMI]" 
$grantCreateScript = "GRANT CREATE TABLE TO [job-agent-UMI]"

$targetDatabases | % {
  $params.database = $_
  $params.query = $createJobUserScript
  Invoke-SqlCmd @params
  $params.query = $grantAlterSchemaScript
  Invoke-SqlCmd @params
  $params.query = $grantCreateScript
  Invoke-SqlCmd @params
}

Menggunakan kredensial cakupan database untuk autentikasi ke target

Agen pekerjaan menggunakan kredensial yang ditentukan oleh grup target setelah eksekusi dan menjalankan skrip. Kredensial cakupan database ini juga digunakan untuk menyambungkan ke master database untuk menemukan semua database di server atau kumpulan elastis, ketika salah satu dari ini digunakan sebagai jenis anggota grup target.

Kredensial cakupan database harus dibuat dalam database pekerjaan. Semua database target harus memiliki login dengan izin yang memadai agar pekerjaan diselesaikan dengan baik.

Selain kredensial dalam gambar, perhatikan penambahan GRANT perintah dalam skrip berikut. Izin ini diperlukan untuk skrip yang kami pilih untuk pekerjaan contoh berikut. Pekerjaan Anda mungkin memerlukan izin yang berbeda. Karena contoh membuat tabel baru dalam database yang ditargetkan, pengguna database di setiap database target memerlukan izin yang tepat agar berhasil dijalankan.

Login/pengguna di setiap server/database target harus memiliki nama yang sama dengan identitas kredensial cakupan database untuk pengguna pekerjaan, dan kata sandi yang sama dengan kredensial cakupan database untuk pengguna pekerjaan. Di mana skrip PowerShell menggunakan <strong jobuser password here>, gunakan kata sandi yang sama di seluruh.

Contoh berikut menggunakan kredensial cakupan database. Untuk membuat kredensial pekerjaan yang diperlukan (dalam database pekerjaan), jalankan skrip berikut, yang menggunakan Autentikasi SQL untuk menyambungkan ke server target/database:

# For the target logical server, in the master database
# Create the master user login, master user, and job user login
$targetServer = '<target server name>'
$adminLogin = '<username>'
$adminPassword = '<password>'

$params = @{
  'database' = 'master'
  'serverInstance' =  $targetServer.ServerName + '.database.windows.net'
  'username' = $adminLogin
  'password' = $adminPassword
  'outputSqlErrors' = $true
  'query' = 'CREATE LOGIN adminuser WITH PASSWORD=''<strong adminuser password here>'''
}
Invoke-SqlCmd @params
$params.query = "CREATE USER adminuser FROM LOGIN adminuser"
Invoke-SqlCmd @params
$params.query = 'CREATE LOGIN jobuser WITH PASSWORD=''<strong jobuser password here>'''
Invoke-SqlCmd @params

# For each target database in the target logical server
# Create the jobuser from jobuser login and check permission for script execution
$targetDatabases = @( $db1.DatabaseName, $Db2.DatabaseName )
$createJobUserScript =  "CREATE USER jobuser FROM LOGIN jobuser"

# Grant permissions as necessary. For example ALTER and CREATE TABLE:
$grantAlterSchemaScript = "GRANT ALTER ON SCHEMA::dbo TO jobuser"
$grantCreateScript = "GRANT CREATE TABLE TO jobuser"

$targetDatabases | % {
  $params.database = $_
  $params.query = $createJobUserScript
  Invoke-SqlCmd @params
  $params.query = $grantAlterSchemaScript
  Invoke-SqlCmd @params
  $params.query = $grantCreateScript
  Invoke-SqlCmd @params
}

# Create job credential in job database for admin user
Write-Output "Creating job credentials..."
$loginPasswordSecure = (ConvertTo-SecureString -String '<strong jobuser password here>' -AsPlainText -Force)
$loginadminuserPasswordSecure = (ConvertTo-SecureString -String '<strong adminuser password here>' -AsPlainText -Force)

$adminCred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList "adminuser", $loginadminuserPasswordSecure
$adminCred = $jobAgent | New-AzSqlElasticJobCredential -Name "adminuser" -Credential $adminCred

$jobCred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList "jobuser", $loginPasswordSecure
$jobCred = $jobAgent | New-AzSqlElasticJobCredential -Name "jobuser" -Credential $jobCred

Menentukan server dan database target

Grup target menentukan kumpulan satu database atau lebih yang akan dijalankan oleh langkah pekerjaan.

Cuplikan berikut membuat dua grup target: serverGroup, dan serverGroupExcludingDb2. serverGroup menargetkan semua database yang ada di server pada saat eksekusi, dan serverGroupExcludingDb2 menargetkan semua database di server, kecuali TargetDb2:

Write-Output "Creating test target groups..."
# create ServerGroup target group
$serverGroup = $jobAgent | New-AzSqlElasticJobTargetGroup -Name 'ServerGroup'
$serverGroup | Add-AzSqlElasticJobTarget -ServerName $targetServerName -RefreshCredentialName $adminCred.CredentialName

# create ServerGroup with an exclusion of db2
$serverGroupExcludingDb2 = $jobAgent | New-AzSqlElasticJobTargetGroup -Name 'ServerGroupExcludingDb2'
$serverGroupExcludingDb2 | Add-AzSqlElasticJobTarget -ServerName $targetServerName -RefreshCredentialName $adminCred.CredentialName
$serverGroupExcludingDb2 | Add-AzSqlElasticJobTarget -ServerName $targetServerName -Database $db2.DatabaseName -Exclude

Membuat pekerjaan dan langkah-langkah

Contoh ini mendefinisikan pekerjaan dan dua langkah pekerjaan agar pekerjaan dapat dijalankan. Langkah pekerjaan pertama (step1) membuat tabel baru (Step1Table) di setiap database dalam grup ServerGrouptarget . Langkah pekerjaan kedua (step2) membuat tabel baru (Step2Table) di setiap database kecuali , TargetDb2karena grup target yang ditentukan sebelumnya ditentukan untuk mengecualikannya.

Write-Output "Creating a new job..."
$jobName = "Job1"
$job = $jobAgent | New-AzSqlElasticJob -Name $jobName -RunOnce
$job

Write-Output "Creating job steps..."
$sqlText1 = "IF NOT EXISTS (SELECT * FROM sys.tables WHERE object_id = object_id('Step1Table')) CREATE TABLE [dbo].[Step1Table]([TestId] [int] NOT NULL);"
$sqlText2 = "IF NOT EXISTS (SELECT * FROM sys.tables WHERE object_id = object_id('Step2Table')) CREATE TABLE [dbo].[Step2Table]([TestId] [int] NOT NULL);"

$job | Add-AzSqlElasticJobStep -Name "step1" -TargetGroupName $serverGroup.TargetGroupName -CredentialName $jobCred.CredentialName -CommandText $sqlText1
$job | Add-AzSqlElasticJobStep -Name "step2" -TargetGroupName $serverGroupExcludingDb2.TargetGroupName -CredentialName $jobCred.CredentialName -CommandText $sqlText2

Menjalankan pekerjaan

Untuk segera memulai pekerjaan, jalankan perintah berikut:

Write-Output "Start a new execution of the job..."
$jobExecution = $job | Start-AzSqlElasticJob
$jobExecution

Setelah berhasil menyelesaikan, Anda akan melihat dua tabel baru di TargetDb1, dan hanya satu tabel baru di TargetDb2.

Anda juga dapat menjadwalkan pekerjaan untuk dijalankan nanti.

Penting

Semua waktu mulai dalam pekerjaan elastis berada di zona waktu UTC.

Untuk menjadwalkan tugas yang akan dijalankan pada waktu tertentu, jalankan perintah berikut:

# run every hour starting from now
$job | Set-AzSqlElasticJob -IntervalType Hour -IntervalCount 1 -StartTime (Get-Date) -Enable

Memantau status eksekusi pekerjaan

Cuplikan berikut menunjukkan detail eksekusi pekerjaan:

# get the latest 10 executions run
$jobAgent | Get-AzSqlElasticJobExecution -Count 10

# get the job step execution details
$jobExecution | Get-AzSqlElasticJobStepExecution

# get the job target execution details
$jobExecution | Get-AzSqlElasticJobTargetExecution -Count 2

Tabel berikut ini mencantumkan kemungkinan status eksekusi pekerjaan:

Provinsi Deskripsi
Dibuat Eksekusi pekerjaan baru saja dibuat dan belum dalam progres.
InProgress Eksekusi pekerjaan sedang dalam progres.
WaitingForRetry Eksekusi pekerjaan tidak dapat selesai dan sedang menunggu untuk mencoba kembali.
Berhasil Eksekusi pekerjaan telah berhasil diselesaikan.
SucceededWithSkipped Eksekusi pekerjaan telah berhasil diselesaikan, tetapi beberapa elemen anaknya dilewati.
Gagal Eksekusi pekerjaan telah gagal dan kelelahan.
TimedOut Waktu eksekusi pekerjaan telah habis.
Canceled Eksekusi pekerjaan dibatalkan.
Skipped Eksekusi pekerjaan dilewati karena eksekusi lain dari langkah pekerjaan yang sama sudah berjalan pada target yang sama.
WaitingForChildJobExecutions Eksekusi pekerjaan sedang menunggu eksekusi pekerjaan anaknya selesai.

Membersihkan sumber daya

Hapus sumber daya Azure yang dibuat dalam tutorial ini dengan menghapus grup sumber daya.

Tip

Jika Anda berencana untuk terus bekerja dengan pekerjaan ini, sebaiknya Anda tidak menghapus sumber daya yang dibuat di artikel ini.

Remove-AzResourceGroup -ResourceGroupName $resourceGroupName

Langkah selanjutnya