Dela via


Skapa och hantera elastiska jobb med hjälp av PowerShell

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 möjliggör körning av ett eller flera Transact-SQL skript (T-SQL) parallellt på många databaser.

I denna omfattande handledning får du lära dig de steg som krävs för att köra en fråga över flera databaser.

  • Skapa en elastisk jobbagent
  • Skapa jobbautentiseringsuppgifter så att jobb 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ägga till jobbsteg i ett jobb
  • Starta exekveringen av ett jobb
  • Övervaka ett jobb

Förutsättningar

Elastiska databasjobb har en uppsättning PowerShell-cmdletar.

Dessa cmdlets uppdaterades i november 2023.

Installera den senaste versionen av cmdletarna för elastic jobs

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

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

# 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 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å du kan använda de namngivningskonventioner du vill, så länge de uppfyller alla Azure-krav. Om du redan har skapat en tom databas för att tjäna som den elastiska jobbdatabasen, 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 man 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 utfö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 Microsoft Entra-autentisering med en användartilldelad hanterad identitet använder du argumenten IdentityType och IdentityID i 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

Om du vill skapa en ny elastisk jobbagent med databasomfattande autentiseringsuppgifter tillhandahålls inte IdentityType och IdentityID.

Skapa jobbautentiseringen

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

Som beskrivs i Skapa jobbagentautentisering:

Använd Microsoft Entra-autentisering med en UMI för att autentisera mot 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, observera tillägget av kommandona GRANT i följande skript. Dessa behörigheter krävs för skriptet som 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 databasen master för den logiska målservern.
  • Om du till exempel vill skapa en innesluten databasinloggning i master-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änd databasavgränsade 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 databasomfattande autentiseringsuppgifter används också för att ansluta till den 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 jobbet ska kunna slutföras.

Förutom uppgifterna i bilden, noterar du tillägget av GRANT-kommandona i följande skript. Dessa behörigheter krävs för skriptet som 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. Om PowerShell-skriptet använder <strong jobuser password here>använder 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 + '.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 definierar uppsättningen med en eller flera databaser som ett jobbsteg ska köras på.

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

Det här exemplet definierar ett jobb och två jobbsteg som jobbet ska köra. 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 definierades tidigare specificerade att den skulle uteslutas.

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 uppgiften

Starta jobbet direkt genom att köra följande kommando:

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 TargetDb1och 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.

Om du vill schemalägga ett jobb som ska köras vid en viss tidpunkt kör du följande kommando:

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

Övervaka status för jobbexekveringar

Följande kodfragment hämtar detaljer 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
Skapat Jobbkörningen har just skapats och pågår inte ännu.
InProgress Arbetet pågår för närvarande.
VäntarPåOmförsök Jobbexekveringen kunde inte slutföra sin åtgärd och väntar på att försöka igen.
lyckades Jobbkörningen har slutförts framgångsrikt.
SucceededWithSkipped Jobbkörningen har slutförts framgångsrikt, men några av dess underliggande processer hoppades över.
misslyckades Jobbkörningen har misslyckats och uttömt dess återförsök.
TimedOut- Tidsgränsen för jobbkörningen har överskridits.
Avbrutna Jobbkörningen avbröts.
Överhoppad Jobbkörningen hoppades över eftersom en annan körning av samma jobbsteg redan kördes på samma mål.
VäntarPåBarnJobbkörningar Jobbkörningen väntar på att dess barnkörningar ska slutföras.

Rensa resurser

Ta bort de Azure-resurser som skapades i den här självstudien genom att ta bort resursgruppen.

Tips/Råd

Om du planerar att fortsätta arbeta med de här uppgifterna ska du inte rensa upp de resurser som skapats i denna artikel.

Remove-AzResourceGroup -ResourceGroupName $resourceGroupName

Nästa steg