PowerShell kullanarak elastik işler oluşturma ve yönetme

Şunlar için geçerlidir: Azure SQL Veritabanı

Bu makalede, PowerShell kullanarak elastik işlerle çalışmaya başlamaya yönelik bir öğretici ve örnekler sağlanır. Elastik işler, bir veya daha fazla Transact-SQL (T-SQL) betiğinin birden fazla veritabanında paralel olarak çalıştırılmasını sağlar.

Bu uçtan uca öğreticide, birden çok veritabanında sorgu çalıştırmak için gereken adımları öğreneceksiniz:

  • Elastik iş aracısı oluşturma
  • İşlerin hedeflerinde betik yürütebilmesi için iş kimlik bilgileri oluşturma
  • İşi çalıştırmak istediğiniz hedefleri (sunucular, elastik havuzlar, veritabanları) tanımlayın
  • Aracının işleri bağlaması ve yürütmesi için hedef veritabanlarında veritabanı kapsamlı kimlik bilgileri oluşturma
  • İş oluşturma
  • Bir işe iş adımları ekleme
  • Bir işin yürütülmesini başlatma
  • Bir işi izleme

Önkoşullar

Elastik veritabanı işlerinin bir dizi PowerShell cmdlet'i vardır.

Bu cmdlet'ler Kasım 2023'te güncelleştirildi.

En son elastik işler cmdlet'lerini yükleme

Azure aboneliğiniz yoksa başlamadan önce ücretsiz bir hesap oluşturun.

Henüz yoksa ve SqlServer modüllerinin en son sürümlerini Az.Sql yükleyin. PowerShell'de yönetici erişimiyle aşağıdaki komutları çalıştırın.

# 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

Ayrıntılar için bkz . SQL Server PowerShell modülünü yükleme.

Gerekli kaynakları oluşturma

Elastik iş aracısı oluşturmak için elastik iş veritabanı olarak kullanılacak bir veritabanı (S1 veya üzeri) gerekir.

Aşağıdaki betik elastik iş veritabanı olarak kullanılmak üzere yeni bir kaynak grubu, sunucu ve veritabanı oluşturur. İkinci betik, işleri yürütmek için iki boş veritabanı olan ikinci bir sunucu oluşturur.

Elastik işlerin belirli adlandırma gereksinimleri yoktur, bu nedenle herhangi bir Azure gereksinimlerine uygun oldukları sürece istediğiniz adlandırma kurallarını kullanabilirsiniz. Elastik iş veritabanı olarak sunucuya zaten boş bir veritabanı oluşturduysanız Elastik iş aracısı oluşturma bölümüne atlayın.

Elastik işler özel uç noktası kullanılırken ile New-AzSqlServerFirewallRule bir güvenlik duvarı kuralı yapılandırmak gereksizdir.

# 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

Elastik iş aracısı oluşturma

Elastik iş aracısı, işleri oluşturmaya, çalıştırmaya ve yönetmeye yönelik bir Azure kaynağıdır. Aracı işleri belirli bir plana göre veya tek seferlik iş olarak yürütür. Elastik işlerdeki tüm tarihler ve saatler UTC saat dilimindedir.

New-AzSqlElasticJobAgent cmdlet'i, Azure SQL Veritabanı'da bir veritabanının zaten var olmasını gerektirir, bu nedenle , serverNameve databaseName parametrelerinin tümünün resourceGroupNamevar olan kaynakları işaret etmesi gerekir. Benzer şekilde, Set-AzSqlElasticJobAgent elastik iş aracısını değiştirmek için kullanılabilir.

Kullanıcı tarafından atanan yönetilen kimlikle Microsoft Entra kimlik doğrulamasını kullanarak yeni bir elastik iş aracısı oluşturmak için ve IdentityID bağımsız değişkenlerini New-AzSqlElasticJobAgentkullanınIdentityType:

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

Veritabanı kapsamlı kimlik bilgilerini IdentityType kullanarak yeni bir elastik iş aracısı oluşturmak için ve IdentityID sağlanmaz.

İş kimlik doğrulamasını oluşturma

Elastik iş aracısı her hedef sunucuda veya veritabanında kimlik doğrulaması yapabilmelidir.

İş aracısı kimlik doğrulaması oluşturma bölümünde açıklandığı gibi:

Hedeflere yönelik kimlik doğrulaması için UMI ile Microsoft Entra kimlik doğrulamasını kullanma

Kullanıcı tarafından atanan yönetilen kimlikte (UMI) önerilen Microsoft Entra (eski adıYla Azure Active Directory) kimlik doğrulaması yöntemini kullanmak için aşağıdaki adımları izleyin. Elastik iş aracısı, Entra kimlik doğrulaması aracılığıyla istenen hedef mantıksal sunuculara/veritabanlarına bağlanır.

Oturum açma bilgilerine ve veritabanı kullanıcılarına ek olarak, aşağıdaki betikteki komutların eklenmesine GRANT de dikkat edin. Bu izinler, bu örnek işte seçtiğimiz betik için geçerlidir. İşleriniz farklı izinler gerektirebilir. Örnek hedeflenen veritabanlarında yeni bir tablo oluşturduğundan, her hedef veritabanındaki veritabanı kullanıcısının başarıyla çalışması için uygun izinlere sahip olması gerekir.

Hedef sunucuların/veritabanlarının her birinde, UMI ile eşlenmiş bir kapsanan kullanıcı oluşturun.

  • Elastik işin mantıksal sunucusu veya havuz hedefleri varsa, hedef mantıksal sunucunun veritabanında UMI'ye master eşlenen kapsanan kullanıcıyı oluşturmanız gerekir.
  • Örneğin, adlı kullanıcı tarafından atanan yönetilen kimliği (UMI) job-agent-UMItemel alarak veritabanında kapsanan bir veritabanı oturum açma bilgileri master ve kullanıcı veritabanında bir kullanıcı oluşturmak için:
$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
}

Hedeflere kimlik doğrulaması için veritabanı kapsamlı kimlik bilgilerini kullanma

İş aracıları, yürütme ve yürütme betikleri sırasında hedef grup tarafından belirtilen kimlik bilgilerini kullanır. Bu veritabanı kapsamlı kimlik bilgileri, hedef grup üyesi türü olarak kullanıldığında, bir sunucudaki veya elastik havuzdaki tüm veritabanlarını bulmak için veritabanına bağlanmak master için de kullanılır.

Veritabanı kapsamlı kimlik bilgileri iş veritabanında oluşturulmalıdır. İşin başarıyla tamamlanması için hedef veritabanlarının tümünde yeterli izinlere sahip bir oturum açma adı olmalıdır.

Görüntüdeki kimlik bilgilerine ek olarak, aşağıdaki betikteki komutların eklenmesine GRANT dikkat edin. Bu izinler, bu örnek işte seçtiğimiz betik için geçerlidir. İşleriniz farklı izinler gerektirebilir. Örnek hedeflenen veritabanlarında yeni bir tablo oluşturduğundan, her hedef veritabanındaki veritabanı kullanıcısının başarıyla çalışması için uygun izinlere sahip olması gerekir.

Her hedef sunucu/veritabanındaki oturum açma/kullanıcı, iş kullanıcısı için veritabanı kapsamlı kimlik bilgilerinin kimliğiyle aynı ada ve iş kullanıcısının veritabanı kapsamlı kimlik bilgileriyle aynı parolaya sahip olmalıdır. PowerShell betiğinin kullandığı <strong jobuser password here>yerlerde, tüm boyunca aynı parolayı kullanın.

Aşağıdaki örnekte veritabanı kapsamlı kimlik bilgileri kullanılmaktadır. Gerekli iş kimlik bilgilerini oluşturmak için (iş veritabanında), hedef sunuculara/veritabanlarına bağlanmak için SQL Kimlik Doğrulaması'nı kullanan aşağıdaki betiği çalıştırın:

# 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 + '.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

Hedef sunucuları ve veritabanlarını tanımlama

Hedef grup, işin üzerinde çalışacağı veritabanı bir veya daha fazla veritabanından oluşan kümeyi tanımlar.

Aşağıdaki kod parçacığı iki hedef grup oluşturur: serverGroup, ve serverGroupExcludingDb2. serverGroup yürütme sırasında sunucuda bulunan tüm veritabanlarını hedefler ve serverGroupExcludingDb2 dışında TargetDb2sunucudaki tüm veritabanlarını hedefler:

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

İş ve adımlar oluşturma

Bu örnek, bir işi ve işin çalıştırılması için iki iş adımını tanımlar. İlk iş adımı (step1), hedef gruptaki ServerGroupher veritabanında yeni bir tablo (Step1Table) oluşturur. İkinci iş adımı (step2), hariç TargetDb2her veritabanında yeni bir tablo (Step2Table) oluşturur çünkü daha önce tanımlanan hedef grup bunu dışlamak için belirtilir.

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

İşi çalıştırma

İşi hemen başlatmak için aşağıdaki komutu çalıştırın:

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

Başarıyla tamamlandıktan sonra içinde iki yeni tablo ve içinde TargetDb1TargetDb2yalnızca bir yeni tablo görmeniz gerekir.

İşi daha sonra çalıştırılacak şekilde de zamanlayabilirsiniz.

Önemli

Elastik işlerdeki tüm başlangıç zamanları UTC saat dilimindedir.

Bir işi belirli bir zamanda çalışacak şekilde zamanlamak için aşağıdaki komutu çalıştırın:

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

İş yürütme durumunu izleme

Aşağıdaki kod parçacıkları, iş yürütme ayrıntılarını almaktadır:

# 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

Aşağıdaki tabloda olası iş yürütme durumları listelenmiştir:

Durum Açıklama
Oluşturulanlar İş yürütme yeni oluşturuldu ve henüz devam ediyor değil.
InProgress İş yürütme işlemi şu anda devam ediyor.
WaitingForRetry İş yürütme işlemi tamamlanamadı ve yeniden denemeyi bekliyor.
Başarılı İş yürütme başarıyla tamamlandı.
SucceededWithSkipped İş yürütmesi başarıyla tamamlandı, ancak bazı alt öğeleri atlandı.
Başarısız oldu İş yürütme başarısız oldu ve yeniden denemelerini tüketti.
Zaman Aşımı İş yürütme zaman aşımına uğradı.
İptal Edildi İş yürütme iptal edildi.
Atlandı Aynı iş adımının başka bir yürütmesi aynı hedefte zaten çalıştığından iş yürütmesi atlandı.
WaitingForChildJobExecutions İş yürütme, alt yürütmelerinin tamamlanmasını bekliyor.

Kaynakları temizleme

Kaynak grubunu silerek bu öğreticide oluşturulan Azure kaynaklarını silebilirsiniz.

İpucu

Bu işlerle çalışmaya devam etmek istiyorsanız, bu makalede oluşturulan kaynakları temizlemezsiniz.

Remove-AzResourceGroup -ResourceGroupName $resourceGroupName

Sonraki adım