Vytváření a správa elastických úloh pomocí PowerShellu

Platí pro:Azure SQL Database

Tento článek obsahuje kurz a příklady, které vám pomůžou začít pracovat s elastickými úlohami pomocí PowerShellu. Elastické úlohy umožňují paralelní spouštění jednoho nebo více skriptů Transact-SQL (T-SQL) napříč mnoha databázemi.

V tomto kompletním kurzu se naučíte kroky potřebné ke spuštění dotazu napříč několika databázemi:

  • Vytvoření agenta elastických úloh
  • Vytvoření přihlašovacích údajů k úloze, aby úlohy mohly na svých cílech spouštět skripty
  • Definujte cíle (servery, elastické fondy, databáze), pro které chcete úlohu spustit.
  • Vytvoření přihlašovacích údajů v cílových databázích s vymezeným oborem databáze, aby se agent připojil a spustil úlohy
  • Vytvoření úlohy
  • Přidání kroků do úlohy
  • Spuštění provádění úlohy
  • Monitorování úlohy

Požadavky

Úlohy elastické databáze mají sadu rutin PowerShellu.

Tyto rutiny byly aktualizovány v listopadu 2023.

Instalace nejnovějších rutin elastických úloh

Pokud ještě nemáte předplatné Azure, vytvořte si napřed bezplatný účet.

Pokud ještě není k dispozici, nainstalujte nejnovější verze modulů Az.Sql a SqlServer modulů. Spusťte následující příkazy v PowerShellu s přístupem pro správu.

# 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

Podrobnosti najdete v tématu Instalace modulu SQL Server PowerShell.

Vytvoření požadovaných prostředků

Vytvoření agenta elastických úloh vyžaduje databázi (S1 nebo vyšší) pro použití jako databázi elastických úloh.

Následující skript vytvoří novou skupinu prostředků, server a databázi pro použití jako databázi elastických úloh. Druhý skript vytvoří druhý server se dvěma prázdnými databázemi pro spouštění úloh.

Elastické úlohy nemají žádné specifické požadavky na pojmenování, abyste mohli použít libovolné zásady vytváření názvů, pokud vyhovují jakýmkoli požadavkům Azure. Pokud jste už vytvořili prázdnou databázi pro server jako databázi elastických úloh, přeskočte k vytvoření agenta elastických úloh.

Konfigurace pravidla brány firewall s New-AzSqlServerFirewallRule využitím privátního koncového bodu elastických úloh není nutná.

# 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

Vytvoření agenta elastických úloh

Agent elastických úloh je prostředek Azure pro vytváření, spouštění a správu úloh. Agent spouští úlohy na základě plánu nebo jako jednorázové úlohy. Všechna data a časy v elastických úlohách jsou v časovém pásmu UTC.

Rutina New-AzSqlElasticJobAgent vyžaduje, aby již existuje databáze ve službě Azure SQL Database, takže serverNameresourceGroupNameparametr a databaseName parametry musí odkazovat na existující prostředky. Podobně lze set-AzSqlElasticJobAgent použít k úpravě agenta elastických úloh.

Pokud chcete vytvořit nového agenta elastických úloh pomocí ověřování Microsoft Entra se spravovanou identitou přiřazenou uživatelem, použijte IdentityType argumenty New-AzSqlElasticJobAgent:IdentityID

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

Pokud chcete vytvořit nového agenta elastických úloh pomocí přihlašovacích údajů s oborem databáze a IdentityTypeIdentityID nejsou k dispozici.

Vytvoření ověřování úloh

Agent elastických úloh musí být schopný ověřit každý cílový server nebo databázi.

Jak je popsáno v ověřování agenta vytvoření úlohy:

  • Použijte uživatele databáze mapované na spravovanou identitu přiřazenou uživatelem (UMI) k ověření na cílových serverech/databázích.
    • Použití UMI s ověřováním Microsoft Entra (dříve Azure Active Directory) je doporučená metoda. Rutiny PowerShellu teď mají nové argumenty pro podporu ověřování Microsoft Entra pomocí rozhraní UMI.
    • Toto je doporučená metoda ověřování.
  • Použijte uživatele databáze mapované na přihlašovací údaje v oboru databáze v každé databázi.
    • Dříve byly přihlašovací údaje v oboru databáze jedinou možností, jak agent elastických úloh ověřit cíle.

Použití ověřování Microsoft Entra s UMI k ověřování cílům

Pokud chcete použít doporučenou metodu ověřování Microsoft Entra (dříve Azure Active Directory) na spravovanou identitu přiřazenou uživatelem, postupujte takto. Agent elastických úloh se připojí k požadovaným cílovým logickým serverům/databázím prostřednictvím ověřování Entra.

Kromě přihlašovacích údajů a uživatelů databáze si všimněte přidání GRANT příkazů v následujícím skriptu. Tato oprávnění se vyžadují pro skript, který jsme zvolili pro tuto ukázkovou úlohu. Vaše úlohy můžou vyžadovat různá oprávnění. Vzhledem k tomu, že příklad vytvoří novou tabulku v cílových databázích, uživatel databáze v každé cílové databázi potřebuje správná oprávnění k úspěšnému spuštění.

V každém cílovém serveru nebo databázích vytvořte uživatele, který je namapovaný na rozhraní UMI.

  • Pokud má elastická úloha cíle logického serveru nebo fondu, musíte v databázi cílového logického serveru vytvořit uživatele, který je namapovaný na UMI master .
  • Pokud například chcete v databázi vytvořit přihlášení master k databázi s omezením a uživatele v uživatelské databázi na základě spravované identity přiřazené uživatelem ( job-agent-UMIUMI):
$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
}

Použití přihlašovacích údajů v oboru databáze k ověřování pro cíle

Agenti úloh používají přihlašovací údaje určené cílovou skupinou při spuštění a spouštění skriptů. Tyto přihlašovací údaje v oboru databáze se také používají k připojení k master databázi, aby se zjistily všechny databáze na serveru nebo v elastickém fondu, pokud se některý z nich používá jako typ člena cílové skupiny.

Přihlašovací údaje v oboru databáze musí být vytvořeny v databázi úloh. Všechny cílové databáze musí mít přihlašovací účet s dostatečnými oprávněními pro úspěšné dokončení úlohy.

Kroměpřihlašovacích GRANT Tato oprávnění se vyžadují pro skript, který jsme zvolili pro tuto ukázkovou úlohu. Vaše úlohy můžou vyžadovat různá oprávnění. Vzhledem k tomu, že příklad vytvoří novou tabulku v cílových databázích, uživatel databáze v každé cílové databázi potřebuje správná oprávnění k úspěšnému spuštění.

Přihlašovací jméno/uživatel na každém cílovém serveru nebo databázi musí mít stejný název jako identita přihlašovacích údajů v oboru databáze pro uživatele úlohy a stejné heslo jako přihlašovací údaje v oboru databáze pro uživatele úlohy. Pokud skript PowerShellu používá <strong jobuser password here>, použijte stejné heslo v celém prostředí.

Následující příklad používá přihlašovací údaje v oboru databáze. Pokud chcete vytvořit požadované přihlašovací údaje úlohy (v databázi úloh), spusťte následující skript, který používá ověřování SQL pro připojení k cílovým serverům nebo databázím:

# 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

Definování cílových serverů a databází

Cílová skupina definuje sadu jedné nebo více databází, pro které se provede určitý krok úlohy.

Následující fragment kódu vytvoří dvě cílové skupiny: serverGroupa serverGroupExcludingDb2. serverGroup cílí na všechny databáze, které existují na serveru v době provádění, a serverGroupExcludingDb2 cílí na všechny databáze na serveru s výjimkou 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

Vytvoření úlohy a kroků

Tento příklad definuje úlohu a dva kroky úlohy, které má úloha spustit. První krok úlohy (step1) vytvoří novou tabulku (Step1Table) v každé databázi v cílové skupině ServerGroup. Druhý krok úlohy (step2) vytvoří novou tabulku (Step2Table) v každé databázi s výjimkou TargetDb2, protože cílová skupina definovaná dříve byla určena pro vyloučení.

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

Spuštění úlohy

Pokud chcete úlohu okamžitě spustit, spusťte následující příkaz:

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

Po úspěšném dokončení by se měly zobrazit dvě nové tabulky TargetDb1a pouze jedna nová tabulka v TargetDb2.

Můžete také naplánovat, aby se úloha spustila později.

Důležité

Všechny časy spuštění v elastických úlohách jsou v časovém pásmu UTC.

Pokud chcete naplánovat spuštění úlohy na určitý čas, spusťte následující příkaz:

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

Monitorování stavu provádění úloh

Následující fragment kódu získá podrobnosti o provádění úlohy:

# 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

Následující tabulka uvádí možné stavy provádění úloh:

Stát Popis
Vytvořeny Právě se vytvořilo spuštění úlohy a zatím neprobíhá.
InProgress Právě probíhá provádění úlohy.
WaitingForRetry Spuštění úlohy nemohlo dokončit svou akci a čeká na opakování.
Podařilo Spuštění úlohy bylo úspěšně dokončeno.
SucceededWithSkipped Provádění úlohy bylo úspěšně dokončeno, ale některé z jejích podřízených položek byly vynechány.
Neúspěch Spuštění úlohy selhalo a vyčerpalo jeho opakování.
Timedout Vypršel časový limit provádění úlohy.
Zrušeno Spuštění úlohy bylo zrušeno.
Vynecháno Spuštění úlohy se přeskočilo, protože na stejném cíli už bylo spuštěné jiné spuštění stejného kroku úlohy.
WaitingForChildJobExecutions Spuštění úlohy čeká na dokončení podřízených spuštění.

Vyčištění prostředků

Odstraněním skupiny prostředků odstraňte prostředky Azure vytvořené v tomto kurzu.

Tip

Pokud chcete s těmito úlohami dál pracovat, nevyčistíte prostředky vytvořené v tomto článku.

Remove-AzResourceGroup -ResourceGroupName $resourceGroupName

Další krok