Skapa och hantera elastiska jobb med hjälp av PowerShell (förhandsversion)

Gäller för:Azure SQL Database

Den här artikeln innehåller en självstudie och exempel för att komma igång med elastiska jobb med hjälp av PowerShell. Elastiska jobb aktiverar körning av ett eller flera Transact-SQL-skript (T-SQL) parallellt över flera databaser.

I den här självstudien från slutpunkt till slutpunkt får du lära dig de steg som krävs för att köra en fråga i flera databaser:

  • Skapa en elastisk jobbagent
  • Skapa autentiseringsuppgifter för jobbet så att det kan köra skript på sina mål
  • Definiera de mål (servrar, elastiska pooler, databaser) som du vill köra jobbet mot
  • Skapa databasomfattande autentiseringsuppgifter i måldatabaserna så att agenten ansluter och kör jobb
  • Skapa ett jobb
  • Lägg till jobbsteg i ett jobb
  • Starta körningen av ett jobb
  • Övervaka ett jobb

Kommentar

Elastiska jobb finns i förhandsversion. Funktioner som för närvarande är i förhandsversion är tillgängliga under kompletterande användningsvillkor, granska för juridiska villkor som gäller för Azure-funktioner som är i förhandsversion. Azure SQL Database innehåller förhandsversioner som ger dig möjlighet att utvärdera och dela feedback med produktgruppen om funktioner innan de blir allmänt tillgängliga (GA).

Förutsättningar

Elastiska databasjobb har en uppsättning PowerShell-cmdletar.

Dessa cmdletar uppdaterades i november 2023.

Installera de senaste cmdletarna för elastiska jobb

Om du inte har någon Azure-prenumeration skapar du ett kostnadsfritt konto innan du börjar.

Installera de senaste versionerna av modulerna och SqlServer om de Az.Sql inte redan finns. Kör följande kommandon i PowerShell med administratörsbehörighet.

# 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

Mer information finns i avsnittet om att installera SQL Server PowerShell-modulen.

Skapa nödvändiga resurser

För att skapa en elastisk jobbagent krävs en databas (S1 eller senare) för användning som elastisk jobbdatabas.

Följande skript skapar en ny resursgrupp, server och databas för användning som elastisk jobbdatabas. Det andra skriptet skapar en andra server med två tomma databaser att köra jobb mot.

Elastiska jobb har inga specifika namngivningskrav så att du kan använda de namngivningskonventioner du vill, så länge de uppfyller alla Azure-krav. Om du redan har skapat en tom databas till servern som elastisk jobbdatabas går du vidare till Skapa den elastiska jobbagenten.

Det är inte nödvändigt att konfigurera en brandväggsregel med New-AzSqlServerFirewallRule när du använder en privat slutpunkt för elastiska jobb.

# 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

Skapa den elastiska jobbagenten

En elastisk jobbagent är en Azure-resurs för att skapa, köra och hantera jobb. Agenten kör jobb baserat på ett schema eller som ett engångsjobb. Alla datum och tider i elastiska jobb finns i UTC-tidszonen.

Cmdleten New-AzSqlElasticJobAgent kräver att en databas i Azure SQL Database redan finns, så parametrarna resourceGroupName, serverNameoch databaseName måste peka på befintliga resurser. På samma sätt kan Set-AzSqlElasticJobAgent användas för att ändra den elastiska jobbagenten.

Om du vill skapa en ny elastisk jobbagent med Hjälp av New-AzSqlElasticJobAgentMicrosoft Entra-autentisering med en användartilldelad hanterad identitet använder du argumenten IdentityType och IdentityID för :

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

Om du vill skapa en ny elastisk jobbagent med databasomfångsbegränsade autentiseringsuppgifter IdentityType och IdentityID inte tillhandahålls.

Skapa jobbautentiseringen

Den elastiska jobbagenten måste kunna autentisera till varje målserver eller databas.

Som beskrivs i Skapa jobbagentautentisering:

Använda Microsoft Entra-autentisering med en UMI för autentisering till mål

Följ dessa steg om du vill använda den rekommenderade metoden för Microsoft Entra-autentisering (tidigare Azure Active Directory) för en användartilldelad hanterad identitet (UMI). Den elastiska jobbagenten ansluter till önskad logisk målserver/databaser via Entra-autentisering.

Förutom inloggnings- och databasanvändarna noterar du tillägget av GRANT kommandona i följande skript. Dessa behörigheter krävs för skriptet vi valde för det här exempeljobbet. Dina jobb kan kräva olika behörigheter. Eftersom exemplet skapar en ny tabell i måldatabaserna behöver databasanvändaren i varje måldatabas rätt behörighet för att kunna köras.

I var och en av målservrarna/databaserna skapar du en innesluten användare som mappats till UMI.

  • Om det elastiska jobbet har logiska server- eller poolmål måste du skapa den inneslutna användaren som mappas till UMI i master databasen för den logiska målservern.
  • Om du till exempel vill skapa en innesluten master databasinloggning i databasen och en användare i användardatabasen, baserat på den användartilldelade hanterade identiteten (UMI) med namnet 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
}

Använda databasomfattande autentiseringsuppgifter för autentisering till mål

Jobbagenter använder autentiseringsuppgifter som anges av målgruppen vid körning och körning av skript. Dessa databasomfångsbegränsade autentiseringsuppgifter används också för att ansluta till master databasen för att identifiera alla databaser i en server eller en elastisk pool, när någon av dessa används som målgruppsmedlemstyp.

Autentiseringsuppgifterna med databasomfattning måste skapas i jobbdatabasen. Alla måldatabaser måste ha en inloggning med tillräcklig behörighet för att slutföra jobbet.

Förutom autentiseringsuppgifterna i avbildningen noterar du tillägget av GRANT kommandona i följande skript. Dessa behörigheter krävs för skriptet vi valde för det här exempeljobbet. Dina jobb kan kräva olika behörigheter. Eftersom exemplet skapar en ny tabell i måldatabaserna behöver databasanvändaren i varje måldatabas rätt behörighet för att kunna köras.

Inloggningen/användaren på varje målserver/databas måste ha samma namn som identiteten för den databasomfattande autentiseringsuppgiften för jobbanvändaren och samma lösenord som jobbanvändarens databasomfattande autentiseringsuppgifter. Där PowerShell-skriptet använder använder <strong jobuser password here>du samma lösenord hela vägen.

I följande exempel används databasomfattande autentiseringsuppgifter. Om du vill skapa nödvändiga jobbautentiseringsuppgifter (i jobbdatabasen) kör du följande skript, som använder SQL-autentisering för att ansluta till målservern/databaserna:

# 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

Definiera målservrar och databaser

En målgrupp utgörs av en eller flera databaser som ett jobbsteg ska köras mot.

Följande kodfragment skapar två målgrupper: serverGroup, och serverGroupExcludingDb2. serverGroup riktar sig till alla databaser som finns på servern vid tidpunkten för körningen och serverGroupExcludingDb2 riktar sig till alla databaser på servern, förutom 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

Skapa ett jobb och steg

Det här exemplet definierar ett jobb och två jobbsteg för jobbet som ska köras. Det första jobbsteget (step1) skapar en ny tabell (Step1Table) i varje databas i målgruppen ServerGroup. Det andra jobbsteget (step2) skapar en ny tabell (Step2Table) i varje databas förutom TargetDb2, eftersom målgruppen som definierats tidigare angavs för att exkludera den.

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

Kör jobbet

Kör följande kommando direkt för att starta jobbet:

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

När du har slutfört det bör du se två nya tabeller i TargetDb1, och endast en ny tabell i TargetDb2.

Du kan också schemalägga jobbet så att det körs senare.

Viktigt!

Alla starttider i elastiska jobb finns i UTC-tidszonen.

Kör följande kommando för att schemalägga ett jobb så att det körs vid en viss tid:

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

Övervaka status för jobbkörningar

Följande kodavsnitt hämtar information om jobbkörning:

# 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

I följande tabell visas de möjliga jobbkörningstillstånden:

Stat/län beskrivning
Skapad Jobbkörningen har just skapats och pågår inte ännu.
InProgress Jobbkörningen pågår för närvarande.
WaitingForRetry Jobbkörningen kunde inte slutföra åtgärden och väntar på att försöka igen.
Lyckades Jobbkörningen har slutförts.
SucceededWithSkipped Jobbkörningen har slutförts, men några av dess underordnade objekt hoppades över.
Misslyckades Jobbkörningen har misslyckats och uttömt dess återförsök.
TimedOut Tidsgränsen för jobbkörningen har överskrids.
Avbruten Jobbkörningen avbröts.
Överhoppad Jobbkörningen hoppades över eftersom en annan körning av samma jobbsteg redan kördes på samma mål.
WaitingForChildJobExecutions Jobbkörningen väntar på att dess underordnade körningar ska slutföras.

Rensa resurser

Ta bort alla resurser som du har skapat i den här självstudien genom att ta bort resursgruppen.

Dricks

Om du planerar att fortsätta arbeta med de här jobben rensar du inte resurserna som skapas i den här artikeln.

Remove-AzResourceGroup -ResourceGroupName $resourceGroupName

Gå vidare