%3CLINGO-SUB%20id%3D%22lingo-sub-1199565%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199565%22%20slang%3D%22en-US%22%3Etest%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1199595%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199595%22%20slang%3D%22en-US%22%3ETees%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1199597%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199597%22%20slang%3D%22en-US%22%3EReplying%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1199599%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199599%22%20slang%3D%22en-US%22%3EOne%20more%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1199600%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199600%22%20slang%3D%22en-US%22%3EReplying%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1199602%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199602%22%20slang%3D%22en-US%22%3EAndroid%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1199603%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199603%22%20slang%3D%22en-US%22%3ETalk%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1199606%22%20slang%3D%22en-US%22%3ERE%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1199606%22%20slang%3D%22en-US%22%3EAa%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1179929%22%20slang%3D%22en-US%22%3ECreating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1179929%22%20slang%3D%22en-US%22%3E%3CTABLE%20style%3D%22background-color%3A%20transparent%3B%20border-collapse%3A%20collapse%3B%20border-spacing%3A%200px%3B%20box-sizing%3A%20border-box%3B%20color%3A%20%23333333%3B%20font-family%3A%20%26amp%3Bquot%3B%20segoeui%26amp%3Bquot%3B%2C%26amp%3Bquot%3Blato%26amp%3Bquot%3B%2C%26amp%3Bquot%3Bhelvetica%20neue%26amp%3Bquot%3B%2Chelvetica%2Carial%2Csans-serif%3B%20font-size%3A%2016px%3B%20font-style%3A%20normal%3B%20font-variant%3A%20normal%3B%20font-weight%3A%20300%3B%20letter-spacing%3A%20normal%3B%20orphans%3A%202%3B%20text-align%3A%20left%3B%20text-decoration%3A%20none%3B%20text-indent%3A%200px%3B%20text-transform%3A%20none%3B%20-webkit-text-stroke-width%3A%200px%3B%20white-space%3A%20normal%3B%20width%3A%20100%25%3B%20word-spacing%3A%200px%3B%20border-style%3A%20double%3B%22%20border%3D%221%22%20width%3D%22100%25%22%3E%0A%3CTBODY%20style%3D%22box-sizing%3A%20border-box%3B%22%3E%0A%3CTR%20style%3D%22box-sizing%3A%20border-box%3B%22%3E%0A%3CTD%20width%3D%22100%25%22%20style%3D%22border-image-outset%3A%200%3B%20border-image-repeat%3A%20stretch%3B%20border-image-slice%3A%20100%25%3B%20border-image-source%3A%20none%3B%20border-image-width%3A%201%3B%20box-sizing%3A%20border-box%3B%20font-family%3A%20inherit%3B%20font-size%3A%2016px%3B%20font-weight%3A%20300%3B%20line-height%3A%201.7142%3B%20min-width%3A%2040px%3B%20word-break%3A%20normal%3B%20padding%3A%201px%205px%201px%205px%3B%20border%3A%201px%20solid%20%23c4c4c4%3B%22%3E%3CFONT%20style%3D%22box-sizing%3A%20border-box%3B%20color%3A%20%23ff0000%3B%20font-family%3A%20%26amp%3Bquot%3B%20segoeui%26amp%3Bquot%3B%2C%26amp%3Bquot%3Blato%26amp%3Bquot%3B%2C%26amp%3Bquot%3Bhelvetica%20neue%26amp%3Bquot%3B%2Chelvetica%2Carial%2Csans-serif%3B%20font-size%3A%2016px%3B%20font-style%3A%20normal%3B%20font-variant%3A%20normal%3B%20font-weight%3A%20300%3B%20letter-spacing%3A%20normal%3B%20orphans%3A%202%3B%20text-align%3A%20left%3B%20text-decoration%3A%20none%3B%20text-indent%3A%200px%3B%20text-transform%3A%20none%3B%20-webkit-text-stroke-width%3A%200px%3B%20white-space%3A%20normal%3B%20word-spacing%3A%200px%3B%22%20color%3D%22%23ff0000%22%3EElastic%20Jobs%20are%20currently%20in%20public%20preview.%26nbsp%3B%20The%20feature%20is%20ready%20and%20we%20are%20preparing%20to%20make%20it%20officially%20generally%20available.%26nbsp%3B%20No%20extra%20steps%20are%20required%20to%20get%20started.%3C%2FFONT%3E%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3C%2FTBODY%3E%0A%3C%2FTABLE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EHaving%20laid%20the%20conceptual%20groundwork%20for%20Elastic%20Jobs%20in%20two%20previous%20postings%20(-ERR%3AREF-NOT-FOUND-1%2C%20-ERR%3AREF-NOT-FOUND-2)%2C%20I%20am%20now%20going%20to%20create%20an%20elastic%20job%20and%20associated%20credentials%20using%20PowerShell.%26nbsp%3B%20For%20this%20scenario%2C%20I%20have%20one%20or%20more%20databases%20with%20a%20table%20%E2%80%98T%E2%80%99%20and%20statistics%20%E2%80%98tStats%E2%80%99.%20I%20want%20to%20enforce%20an%20update%20for%20these%20statistics%20every%20day.%20To%20do%20this%2C%20I%20need%20to%20check%20that%20my%20stats%20have%20been%20updated%20in%20the%20past%20day%2C%20and%20if%20not%2C%20update%20them.%20The%20T-SQL%20to%20update%20statistics%20on%20a%20table%20%E2%80%9CT%E2%80%9D%20with%20stats%20named%20%E2%80%9CtStats%E2%80%9D%20is%20simple%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3EUPDATE%20STATISTICS%20T(tStats)%3C%2FPRE%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3EHowever%2C%20it%20is%20also%20important%20to%20make%20this%20operation%20idempotent.%20To%20do%20this%2C%20I%20first%20check%20to%20see%20if%20the%20stats%20have%20been%20updated%20in%20the%20past%20day.%26nbsp%3B%20If%20they%20have%2C%20I%20do%20nothing.%26nbsp%3B%20If%20they%20have%20not%20I%20update%20the%20statistics%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3EIF%3CBR%20%2F%3E(CASE%3CBR%20%2F%3EWHEN%3CBR%20%2F%3E%20%20%20%20(%3CSPAN%3ESELECT%20STATE_DATE(%5Bobject_id%5D%2C%20%5Bstats_id%5D)%20%3CBR%20%2F%3E%20%3C%2FSPAN%3E%3CSPAN%3EFROM%20sys.stats%26nbsp%3B%3CBR%20%2F%3E%20%3C%2FSPAN%3EWHERE%20name%20%3D%20'tStats')%3CBR%20%2F%3E%26lt%3B%3CBR%20%2F%3EDATEADD(day%2C-1%2C%20sysdatetime())%3CBR%20%2F%3ETHEN%201%3CBR%20%2F%3EELSE%200%3CBR%20%2F%3EEND%20)%20%3D%201%3CBR%20%2F%3EUPDATE%20STATISTICS%20T(tStats)%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENow%20that%20I%20have%20the%20basic%20T-SQL%20script%2C%20I%20can%20test%20it%20out%20on%20a%20sample%20database.%26nbsp%3B%20Once%20I%20ensure%20that%20it%20works%20as%20expected%20(even%20with%20multiple%20executions%20occurring%20in%20close%20proximity%20to%20one%20another)%2C%20I%20am%20ready%20to%20create%20an%20elastic%20job%20that%20executes%20this%20script%20on%20the%20target%20database(s).%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CFONT%20color%3D%22%23333333%22%3E%3CSTRONG%3E%3CFONT%20size%3D%225%22%3ECreating%20the%20Job%20Agent%3C%2FFONT%3E%3C%2FSTRONG%3E%3C%2FFONT%3E%3C%2FP%3E%0A%3CP%3EAssume%20I%20have%20a%20server%20already%2C%20called%20elasticjobsagenthostserver.%20This%20server%20and%20the%20database%20on%20it%20can%20be%20an%20-ERR%3AREF-NOT-FOUND-S0%20or%20higher%20database%20as%20the%20Elastic%20Job%20Agent%20does%20not%20require%20a%20lot%20of%20resources.%20It%20is%20considered%20good%20practice%20to%20host%20the%20Elastic%20Job%20Agent%20on%20a%20different%20server%2Fdatabase%20than%20the%20targets%20of%20the%20jobs.%20Thus%2C%20I%20have%20created%20a%20database%20called%20ElasticJobAgentHostDB%2C%20which%20will%20host%20my%20Elastic%20Job%20agent.%26nbsp%3B%26nbsp%3B%20I%20also%20have%20a%20target%20server%20that%20contains%20two%20databases%2C%20a%20General%20Purpose%20database%20(GPDB)%20and%20a%20Hyperscale%20database%20(HSDB).%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ESince%20I%20am%20going%20to%20be%20using%20Azure%20Cloud%20Shell%20to%20create%20my%20agent%20and%20create%20and%20run%20my%20jobs%2C%20I%20will%20go%20to%20the%20Azure%20portal%20and%20open%20the%20Azure%20Cloud%20Shell%20to%20work%20with%20PowerShell%20commands.%20If%20you%20want%20to%20use%20regular%20PowerShell%20on%20your%20local%20machine%2C%20this%20is%20fine%2C%20as%20long%20as%20you%20are%20using%20a%20version%20of%20PowerShell%20that%20is%20updated%20to%20a%20recent%20Azure%20PowerShell%20version.%20To%20open%20Azure%20Cloud%20Shell%2C%20click%20this%20icon%20on%20the%20top%20middle%2Fleft%20of%20the%20screen%3A%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22lia-indent-padding-left-120px%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Kate_Smith_0-1582043743023.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F171754i977EBD359FD26A59%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20title%3D%22Kate_Smith_0-1582043743023.png%22%20alt%3D%22Kate_Smith_0-1582043743023.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOnce%20the%20Azure%20Cloud%20Shell%20is%20open%2C%20I%20will%20bind%20the%20database%20I%20want%20to%20use%20to%20host%20the%20Elastic%20Jobs%20Agent%20(job%20database)%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24db%20%3D%20Get-azsqldatabase%20-ServerName%20elasticjobsagenthostserver%20-DatabaseName%20ElasticJobsAgentHostDB%26nbsp%3B%3C%2FPRE%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENow%20I%20create%20the%20Elastic%20Jobs%20agent%20inside%20the%20jobs%20database%2C%20and%20bind%20it%20to%20the%20variable%20%24jobAgent%2C%20for%20future%20use.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24jobAgent%20%3D%20%24db%20%7C%20New-AzSqlElasticJobAgent%20-Name%20demoagent%26nbsp%3B%3C%2FPRE%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3E%3CFONT%20style%3D%22box-sizing%3A%20border-box%3B%20color%3A%20%23333333%3B%20font-family%3A%20%26amp%3Bquot%3B%20segoeui%26amp%3Bquot%3B%2C%26amp%3Bquot%3Blato%26amp%3Bquot%3B%2C%26amp%3Bquot%3Bhelvetica%20neue%26amp%3Bquot%3B%2Chelvetica%2Carial%2Csans-serif%3B%20font-size%3A%2016px%3B%20font-style%3A%20normal%3B%20font-variant%3A%20normal%3B%20font-weight%3A%20300%3B%20letter-spacing%3A%20normal%3B%20orphans%3A%202%3B%20text-align%3A%20left%3B%20text-decoration%3A%20none%3B%20text-indent%3A%200px%3B%20text-transform%3A%20none%3B%20-webkit-text-stroke-width%3A%200px%3B%20white-space%3A%20normal%3B%20word-spacing%3A%200px%3B%22%20color%3D%22%23333333%22%3E%3CSTRONG%20style%3D%22box-sizing%3A%20border-box%3B%20font-weight%3A%20bold%3B%22%3E%3CFONT%20size%3D%225%22%20style%3D%22box-sizing%3A%20border-box%3B%22%3ECreating%20the%20Credentials%3C%2FFONT%3E%3C%2FSTRONG%3E%3C%2FFONT%3E%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3ENext%2C%20I%20create%20and%20inspect%20a%20SQL%20elastic%20job%20credential.%26nbsp%3BI%20discussed%20the%20%3CEM%3Ewhy%3C%2FEM%3E%20of%20this%20in%20my%20-ERR%3AREF-NOT-FOUND-previous%20post%20about%20fundamentals%2C%20so%20I%20will%20just%20create%20the%20credentials%20with%20no%20explanation%20here.%20Note%3A%20I%20also%20assume%20these%20credentials%20also%20exist%20in%20the%20TARGET%20database%20as%20appropriate%2C%20but%20it%20is%20important%20not%20to%20forget%20that%20step!%20I%20will%20use%20PowerShell%20to%20create%20both%20the%20job%20and%20refresh%20credentials%20using%20the%20agent.%3C%2FP%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24loginPasswordSecure1%20%3D%20(ConvertTo-SecureString%20-String%20%22strongPWD%22%20-AsPlainText%20-Force)%3CBR%20%2F%3E%3A%5C%26gt%3B%20%24loginPasswordSecure2%20%3D%20(ConvertTo-SecureString%20-String%20%22strongPWD2%22%20-AsPlainText%20-Force)%3CBR%20%2F%3E%3A%5C%26gt%3B%20%24refreshCred%20%3D%20New-Object%20-TypeName%20%22System.Management.Automation.PSCredential%22%20-ArgumentList%20%22refreshcredential%22%2C%20%24loginPasswordSecure1%3CBR%20%2F%3E%3A%5C%26gt%3B%20%24refreshCred%20%3D%20%24jobAgent%20%7C%20New-AzSqlElasticJobCredential%20-Name%20%22refreshcredential%20%22%20-Credential%20%24refreshCred%3CBR%20%2F%3E%3A%5C%26gt%3B%20%24jobCred%20%3D%20New-Object%20-TypeName%20%22System.Management.Automation.PSCredential%22%20-ArgumentList%20%22jobcredential%22%2C%20%24loginPasswordSecure2%3CBR%20%2F%3E%3A%5C%26gt%3B%20%24jobCred%20%3D%20%24jobAgent%20%7C%20New-AzSqlElasticJobCredential%20-Name%20%22jobcredential%22%20-Credential%20%24jobCred%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CFONT%20style%3D%22box-sizing%3A%20border-box%3B%20color%3A%20%23333333%3B%20font-family%3A%20%26amp%3Bquot%3B%20segoeui%26amp%3Bquot%3B%2C%26amp%3Bquot%3Blato%26amp%3Bquot%3B%2C%26amp%3Bquot%3Bhelvetica%20neue%26amp%3Bquot%3B%2Chelvetica%2Carial%2Csans-serif%3B%20font-size%3A%2016px%3B%20font-style%3A%20normal%3B%20font-variant%3A%20normal%3B%20font-weight%3A%20300%3B%20letter-spacing%3A%20normal%3B%20orphans%3A%202%3B%20text-align%3A%20left%3B%20text-decoration%3A%20none%3B%20text-indent%3A%200px%3B%20text-transform%3A%20none%3B%20-webkit-text-stroke-width%3A%200px%3B%20white-space%3A%20normal%3B%20word-spacing%3A%200px%3B%22%20color%3D%22%23333333%22%3E%3CSTRONG%20style%3D%22box-sizing%3A%20border-box%3B%20font-weight%3A%20bold%3B%22%3E%3CFONT%20size%3D%225%22%20style%3D%22box-sizing%3A%20border-box%3B%22%3ECreating%20the%20Target%20Group%3C%2FFONT%3E%3C%2FSTRONG%3E%3C%2FFONT%3E%3C%2FP%3E%0A%3CP%3EAt%20this%20point%2C%20I%20am%20ready%20to%20create%20a%20target%20group%20for%20my%20job%20and%20bind%20that%20to%20the%20variable%20%24tg.%20In%20this%20example%2C%20the%20target%20group%20contains%20a%20single%20server%2C%20that%20hosts%20both%20a%20Hyperscale%20database%20and%20a%20General%20Purpose%20database%2C%20but%20it%20could%20also%20contain%20an%20arbitrary%20set%20of%20databases%20listed%20individually%20or%20by%20server.%20More%20documentation%20on%20this%20-ERR%3AREF-NOT-FOUND-here.%3C%2FP%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24jobAgent%20%7C%20New-AzSqlElasticJobTargetGroup%20-TargetGroupName%20DemoGroup%26nbsp%3B%3CBR%20%2F%3E%3A%5C%26gt%3B%20%24tg%20%3D%20%24jobAgent%20%7C%20Get-AzSqlElasticJobTargetGroup%20-TargetGroupName%20DemoGroup%26nbsp%3B%3C%2FPRE%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3EI%20add%20a%20server%20to%20the%20target%20group%2C%20using%20my%20refresh%20credential.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24tg%20%7C%20Add-AzSqlElasticJobTarget%20-ServerName%20elasticjobstargetserver%20-RefreshCredentialName%20refreshcredential%26nbsp%3B%3C%2FPRE%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWith%20this%20setup%2C%20my%20elastic%20job%20will%20target%20all%20user%20databases%20(everything%20except%20master%20and%20tempdb)%20on%20this%20server%2C%20in%20other%20words%2C%20BOTH%20my%20Hyperscale%20and%20General%20Purpose%20databases.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CFONT%20style%3D%22box-sizing%3A%20border-box%3B%20color%3A%20%23333333%3B%20font-family%3A%20%26amp%3Bquot%3B%20segoeui%26amp%3Bquot%3B%2C%26amp%3Bquot%3Blato%26amp%3Bquot%3B%2C%26amp%3Bquot%3Bhelvetica%20neue%26amp%3Bquot%3B%2Chelvetica%2Carial%2Csans-serif%3B%20font-size%3A%2016px%3B%20font-style%3A%20normal%3B%20font-variant%3A%20normal%3B%20font-weight%3A%20300%3B%20letter-spacing%3A%20normal%3B%20orphans%3A%202%3B%20text-align%3A%20left%3B%20text-decoration%3A%20none%3B%20text-indent%3A%200px%3B%20text-transform%3A%20none%3B%20-webkit-text-stroke-width%3A%200px%3B%20white-space%3A%20normal%3B%20word-spacing%3A%200px%3B%22%20color%3D%22%23333333%22%3E%3CSTRONG%20style%3D%22box-sizing%3A%20border-box%3B%20font-weight%3A%20bold%3B%22%3E%3CFONT%20size%3D%225%22%20style%3D%22box-sizing%3A%20border-box%3B%22%3ECreating%20and%20Defining%20the%20Job%3C%2FFONT%3E%3C%2FSTRONG%3E%3C%2FFONT%3E%3C%2FP%3E%0A%3CP%3ENext%2C%20we%20will%20create%20an%20elastic%20job%20against%20the%20target%2C%20with%20name%20demo123.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24job%20%3D%20%24%20jobAgent%20%7C%20New-AzSqlElasticJob%20-Name%20demo123%26nbsp%3B%3C%2FPRE%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3EBind%20the%20T-SQL%20text%20to%20a%20variable%20to%20make%20it%20less%20cumbersome%20for%20defining%20the%20job%3A%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24sqlText1%20%3D%20%22IF%20(CASE%20WHEN%20(%3CSPAN%20style%3D%22box-sizing%3A%20border-box%3B%20font-family%3A%20%26amp%3Bquot%3B%22%3E%20SELECT%20STATS_DATE(%5Bobject_id%5D%2C%20%5Bstats_id%5D)%20FROM%20sys.stats%20where%20name%20%3D%20'tStats'%20%3C%2FSPAN%3E%26lt%3B%20DATEADD(day%2C-1%2C%20sysdatetime())%20THEN%201%20ELSE%200%20END)%20%3D%201%20UPDATE%20STATISTICS%20T(tStats)%22%26nbsp%3B%3C%2FPRE%3E%0A%3CP%3EThen%20I%20add%20a%20job%20step%2C%20which%20will%20execute%20the%20SQL%20we%20have%20specified.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%3A%5C%26gt%3B%20%24job%20%7C%20Add-AzSqlElasticJobStep%20-Name%20%22step1%22%20-TargetGroupName%20DemoGroup%20-CredentialName%20jobcredential%20-CommandText%20%24sqlText1%26nbsp%3B%3C%2FPRE%3E%0A%3CP%3E%E2%80%AF%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20my%20next%20post%2C%20I%20will%20show%20how%20to%20do%20these%20same%20tasks%20using%20T-SQL%2C%20and%20then%20we%20will%20get%20into%20the%20process%20of%20executing%2C%20scheduling%2C%20and%20troubleshooting%20our%20Elastic%20Jobs.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThis%20blog%20is%20part%20of%20a%20series%20about%20Elastic%20Jobs%20on%20Azure%20SQL%20Database.%26nbsp%3B%3C%2FP%3E%0A%3CP%3ECode%20samples%20are%20also%20available%20on%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure-Samples%2Felastic-jobs-samples%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EGitHub%3C%2FA%3E.%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sql-database%2Felastic-jobs-in-azure-sql-database-what-and-why%2Fba-p%2F1177902%22%20target%3D%22_blank%22%20rel%3D%22noopener%22%3EElastic%20Jobs%20in%20Azure%20SQL%20Database%20%E2%80%93%20What%20and%20Why%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sql-database%2Ffundamental-concepts-for-elastic-jobs-in-azure-sql-database%2Fba-p%2F1177939%22%20target%3D%22_blank%22%20rel%3D%22noopener%22%3EFundamental%20Concepts%20for%20Elastic%20Jobs%20in%20Azure%20SQL%20Database%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sql-database%2Fcreating-an-elastic-jobs-agent-credentials-and-jobs-for-azure%2Fba-p%2F1179929%22%20target%3D%22_blank%22%20rel%3D%22noopener%22%3ECreating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sql-database%2Fcreating-an-elastic-jobs-agent-credentials-and-jobs-for-azure%2Fba-p%2F1180096%22%20target%3D%22_self%22%3ECreating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20T-SQL%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sql-database%2Frunning-scheduling-and-monitoring-elastic-jobs-in-azure-sql%2Fba-p%2F1180179%22%20target%3D%22_self%22%3ERunning%2C%20Scheduling%20and%20Monitoring%20Elastic%20Jobs%20in%20Azure%20SQL%20Database%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sql-database%2Ftroubleshooting-common-issues-with-elastic-jobs-in-azure-sql%2Fba-p%2F1180766%22%20target%3D%22_self%22%3ETroubleshooting%20Common%20issues%20with%20Elastic%20Jobs%20in%20Azure%20SQL%20Database%3C%2FA%3E%3C%2FLI%3E%0A%3C%2FOL%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1179929%22%20slang%3D%22en-US%22%3E%3CP%3EHaving%20laid%20the%20conceptual%20groundwork%20for%20Elastic%20Jobs%20in%20two%20previous%20postings%2C%20I%20am%20now%20going%20to%20create%20an%20elastic%20job%20and%20associated%20credentials%20using%20PowerShell.%26nbsp%3B%20For%20more%20extensive%20documentation%20on%20this%20subject%2C%20see%20-ERR%3AREF-NOT-FOUND-here.%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1601306%22%20slang%3D%22en-US%22%3ERe%3A%20Creating%20an%20Elastic%20Jobs%20Agent%2C%20Credentials%2C%20and%20Jobs%20for%20Azure%20SQL%20Database%20in%20PowerShell%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1601306%22%20slang%3D%22en-US%22%3E%3CP%3EWhy%20is%20it%20suggested%20to%20host%20the%26nbsp%3B%3CSPAN%3EElastic%20Job%20Agent%20on%20a%20different%20server%2Fdatabase%20as%20a%20best%20practice%3F%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThanks%2C%3C%2FP%3E%3CP%3EEric%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft
Elastic Jobs are currently in public preview.  The feature is ready and we are preparing to make it officially generally available.  No extra steps are required to get started.

 

Having laid the conceptual groundwork for Elastic Jobs in two previous postings (1, 2), I am now going to create an elastic job and associated credentials using PowerShell.  For this scenario, I have one or more databases with a table ‘T’ and statistics ‘tStats’. I want to enforce an update for these statistics every day. To do this, I need to check that my stats have been updated in the past day, and if not, update them. The T-SQL to update statistics on a table “T” with stats named “tStats” is simple:

 

UPDATE STATISTICS T(tStats)

  

However, it is also important to make this operation idempotent. To do this, I first check to see if the stats have been updated in the past day.  If they have, I do nothing.  If they have not I update the statistics:

 

IF
(CASE
WHEN
(SELECT STATE_DATE([object_id], [stats_id])
FROM sys.stats 
WHERE name = 'tStats')
<
DATEADD(day,-1, sysdatetime())
THEN 1
ELSE 0
END ) = 1
UPDATE STATISTICS T(tStats)

 

Now that I have the basic T-SQL script, I can test it out on a sample database.  Once I ensure that it works as expected (even with multiple executions occurring in close proximity to one another), I am ready to create an elastic job that executes this script on the target database(s).

 

Creating the Job Agent

Assume I have a server already, called elasticjobsagenthostserver. This server and the database on it can be an S0 or higher database as the Elastic Job Agent does not require a lot of resources. It is considered good practice to host the Elastic Job Agent on a different server/database than the targets of the jobs. Thus, I have created a database called ElasticJobAgentHostDB, which will host my Elastic Job agent.   I also have a target server that contains two databases, a General Purpose database (GPDB) and a Hyperscale database (HSDB).

 

Since I am going to be using Azure Cloud Shell to create my agent and create and run my jobs, I will go to the Azure portal and open the Azure Cloud Shell to work with PowerShell commands. If you want to use regular PowerShell on your local machine, this is fine, as long as you are using a version of PowerShell that is updated to a recent Azure PowerShell version. To open Azure Cloud Shell, click this icon on the top middle/left of the screen: 

  

 

Kate_Smith_0-1582043743023.png

 

  

  

Once the Azure Cloud Shell is open, I will bind the database I want to use to host the Elastic Jobs Agent (job database):

 

:\> $db = Get-azsqldatabase -ServerName elasticjobsagenthostserver -DatabaseName ElasticJobsAgentHostDB 

  

Now I create the Elastic Jobs agent inside the jobs database, and bind it to the variable $jobAgent, for future use. 

  

:\> $jobAgent = $db | New-AzSqlElasticJobAgent -Name demoagent 

    

Creating the Credentials

Next, I create and inspect a SQL elastic job credential. I discussed the why of this in my previous post about fundamentals, so I will just create the credentials with no explanation here. Note: I also assume these credentials also exist in the TARGET database as appropriate, but it is important not to forget that step! I will use PowerShell to create both the job and refresh credentials using the agent.

  

:\> $loginPasswordSecure1 = (ConvertTo-SecureString -String "strongPWD" -AsPlainText -Force)
:\> $loginPasswordSecure2 = (ConvertTo-SecureString -String "strongPWD2" -AsPlainText -Force)
:\> $refreshCred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList "refreshcredential", $loginPasswordSecure1
:\> $refreshCred = $jobAgent | New-AzSqlElasticJobCredential -Name "refreshcredential " -Credential $refreshCred
:\> $jobCred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList "jobcredential", $loginPasswordSecure2
:\> $jobCred = $jobAgent | New-AzSqlElasticJobCredential -Name "jobcredential" -Credential $jobCred

 

Creating the Target Group

At this point, I am ready to create a target group for my job and bind that to the variable $tg. In this example, the target group contains a single server, that hosts both a Hyperscale database and a General Purpose database, but it could also contain an arbitrary set of databases listed individually or by server. More documentation on this here.

  

:\> $jobAgent | New-AzSqlElasticJobTargetGroup -TargetGroupName DemoGroup 
:\> $tg = $jobAgent | Get-AzSqlElasticJobTargetGroup -TargetGroupName DemoGroup 

  

I add a server to the target group, using my refresh credential. 

 

:\> $tg | Add-AzSqlElasticJobTarget -ServerName elasticjobstargetserver -RefreshCredentialName refreshcredential 

  

With this setup, my elastic job will target all user databases (everything except master and tempdb) on this server, in other words, BOTH my Hyperscale and General Purpose databases. 

 

Creating and Defining the Job

Next, we will create an elastic job against the target, with name demo123.

 

:\> $job = $ jobAgent | New-AzSqlElasticJob -Name demo123 

  

Bind the T-SQL text to a variable to make it less cumbersome for defining the job:  

 

:\> $sqlText1 = "IF (CASE WHEN ( SELECT STATS_DATE([object_id], [stats_id]) FROM sys.stats where name = 'tStats' < DATEADD(day,-1, sysdatetime()) THEN 1 ELSE 0 END) = 1 UPDATE STATISTICS T(tStats)" 

Then I add a job step, which will execute the SQL we have specified. 

  

:\> $job | Add-AzSqlElasticJobStep -Name "step1" -TargetGroupName DemoGroup -CredentialName jobcredential -CommandText $sqlText1 

  

In my next post, I will show how to do these same tasks using T-SQL, and then we will get into the process of executing, scheduling, and troubleshooting our Elastic Jobs. 

 

This blog is part of a series about Elastic Jobs on Azure SQL Database. 

Code samples are also available on GitHub.  

  1. Elastic Jobs in Azure SQL Database – What and Why
  2. Fundamental Concepts for Elastic Jobs in Azure SQL Database
  3. Creating an Elastic Jobs Agent, Credentials, and Jobs for Azure SQL Database in PowerShell
  4. Creating an Elastic Jobs Agent, Credentials, and Jobs for Azure SQL Database in T-SQL
  5. Running, Scheduling and Monitoring Elastic Jobs in Azure SQL Database
  6. Troubleshooting Common issues with Elastic Jobs in Azure SQL Database
1 Comment
Visitor

Why is it suggested to host the Elastic Job Agent on a different server/database as a best practice?

 

Thanks,

Eric