<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SQL Server - wiseDATAman</title><link>https://wisedataman.com/category/sql-server/</link><description>SQL Server &amp; SysAdmin, Blog, Tools &amp; Scripts</description><language>en-gb</language><lastBuildDate>Tue, 13 May 2025 21:52:33 +0000</lastBuildDate><atom:link href="https://wisedataman.com/category/sql-server/index.xml" rel="self" type="application/rss+xml"/><item><title>T-SQL Tuesday #186 - Managing Agent Jobs</title><link>https://wisedataman.com/t-sql-tuesday-186-managing-agent-jobs/</link><pubDate>Tue, 13 May 2025 21:52:33 +0000</pubDate><guid>https://wisedataman.com/t-sql-tuesday-186-managing-agent-jobs/</guid><description>&lt;figure class="wp-block-image alignleft size-full is-resized is-style-default"&gt;&lt;a href="https://www.flxsql.com/2025/05/06/t-sql-tuesday-186-managing-agent-jobs-invite/"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image.png" alt="T-SQL Tuesday Logo" class="wp-image-734" style="width:154px;height:auto" loading="lazy"&gt;&lt;/a&gt;&lt;/figure&gt;&#10;&lt;p&gt;For T-SQL Tuesday #186, &lt;a href="https://www.flxsql.com/2025/05/06/t-sql-tuesday-186-managing-agent-jobs-invite/"&gt;Andy Levy asks&lt;/a&gt;, &lt;em&gt;&amp;ldquo;How do you manage and/or monitor your SQL Server Agent jobs?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;This is a great opportunity for me to discuss how &lt;a href="https://dbadash.com/"&gt;DBA Dash&lt;/a&gt; can help monitor SQL Agent jobs. DBA Dash is a free and &lt;strong&gt;&lt;a href="https://github.com/trimble-oss/dba-dash"&gt;open-source&lt;/a&gt;&lt;/strong&gt; monitoring tool for SQL Server, created by me. It&amp;rsquo;s used to monitor thousands of SQL Server instances within Trimble alone, and it&amp;rsquo;s gaining popularity in the SQL Server community.&lt;/p&gt;&#10;&lt;h2 id="built-in-alerts-for-job-failures"&gt;Built-in alerts for job failures&lt;/h2&gt;&#10;&lt;p&gt;Before we discuss DBA Dash, what can we do within SQL Server without any 3rd party tools?&lt;/p&gt;&#10;&lt;p&gt;SQL Agent jobs have native alert notifications. You can get an email whenever a job fails, succeeds, or completes.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-1.png" alt="SQL Server agent job alert notification" class="wp-image-735" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;h3 id="issues-with-built-in-alerts"&gt;Issues with built-in alerts:&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;If a frequently executed job starts failing, this can generate a lot of noise.&lt;br&gt;&#10;&lt;em&gt;A workaround is to set a retry policy and retry interval for your job steps.&lt;/em&gt;&lt;/li&gt;&#10;&lt;li&gt;A lack of a failure notification doesn&amp;rsquo;t mean that everything is in a good state.&lt;br&gt;&#10;&lt;em&gt;You should validate the status of your SQL agent jobs in combination with alerts. Job activity monitor in SSMS could be used for this, but it doesn&amp;rsquo;t scale if you have many SQL instances to monitor.&lt;/em&gt;&lt;/li&gt;&#10;&lt;li&gt;It requires database mail. There are no modern notification channels like Slack, Google chat, PagerDuty etc.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="dba-dash"&gt;DBA Dash&lt;/h2&gt;&#10;&lt;p&gt;DBA Dash includes several useful features to help you monitor your SQL Agent jobs.&lt;/p&gt;&#10;&lt;h3 id="summary-page"&gt;Summary page&lt;/h3&gt;&#10;&lt;p&gt;First up is the summary page. This is a single-page report that can tell you if you have failing jobs across your whole SQL Server estate. It can also tell you if your SQL Server agent is stopped on any of those instances. The summary page includes &lt;strong&gt;many&lt;/strong&gt; other things you should include as part of your &lt;strong&gt;daily checks&lt;/strong&gt;, in addition to monitoring agent jobs.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-2-1024x549.png" alt="DBA Dash daily checks summary page" class="wp-image-737" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;From the summary page, you can drill down and see specific jobs that are failing across your instances. You can click to view the failed steps and messages.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-3-1024x266.png" alt="" class="wp-image-738" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;Thresholds and exclusions can be configured at the root, instance or job level.&lt;/p&gt;&#10;&lt;h3 id="alerts"&gt;Alerts&lt;/h3&gt;&#10;&lt;p&gt;DBA Dash has an AgentJob alert rule that you can use for instant notifications. You can target a specific server, a group of servers (using tags), and filter by category and job name. Your notification options currently include Email, Slack, PagerDuty and Webhook (e.g. Google Chat).&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-11-1024x169.png" alt="Slack alert notification" class="wp-image-746" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;This provides more modern notification options over built-in alerts and allows alerts to be configured centrally. You can control when you are notified and by what mechanism, depending on the priority of the alert.&lt;/p&gt;&#10;&lt;h3 id="job-performance"&gt;Job Performance&lt;/h3&gt;&#10;&lt;p&gt;You might also be interested in tracking job performance over time. DBA Dash allows you to do this centrally. The msdb database maintains a history of job execution, but the DBA Dash repository database enables you to store the execution metrics for a long time with minimal storage cost. You can also visualize the job performance over time very easily.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-4-1024x509.png" alt="SQL Server agent job performance over time" class="wp-image-739" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;h3 id="timeline"&gt;Timeline&lt;/h3&gt;&#10;&lt;p&gt;The timeline view is a great way to see which jobs ran when and how long they ran for. This is useful to help plan job schedules, among other things.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-5-1024x294.png" alt="SQL Server agent job timeline view" class="wp-image-740" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;h3 id="running-jobs"&gt;Running Jobs&lt;/h3&gt;&#10;&lt;p&gt;Want to know what jobs are running right now across all your instances?&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-6-1024x195.png" alt="" class="wp-image-741" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;h3 id="schema-tracking"&gt;Schema Tracking&lt;/h3&gt;&#10;&lt;p&gt;DBA Dash scripts your SQL agent jobs, tracking when changes occur. This can be used to help answer what changed when and provides access to previous versions of jobs, should you need to roll back.&lt;/p&gt;&#10;&lt;p&gt;If you can source control your SQL agent jobs, that is also a great idea. DBA Dash can complement that.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-7-1024x556.png" alt="SQL Agent job schema tracking" class="wp-image-742" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;This feature is also used to provide a SQL agent job DIFF tool so you can compare jobs between SQL instances.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-8-1024x665.png" alt="SQL Server agent job compare servers" class="wp-image-743" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;h3 id="more-to-come"&gt;More to come&lt;/h3&gt;&#10;&lt;p&gt;As I&amp;rsquo;m writing this, I&amp;rsquo;m working on a Job Info page to provide job details on a single page (Steps, schedules, and other metadata). I&amp;rsquo;m using ScriptDom to parse this information, and with the DDL tracking, I can display this info for past versions of a job. I can also use this to display an alternative DIFF format.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-9-1024x676.png" alt="SQL agent job info compare" class="wp-image-744" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;DBA Dash includes a Running Query capture for performance monitoring (similar to sp_WhoIsActive or sp_BlitzWho). This will show you the job name if a query is associated with a running job. In the next version of DBA Dash, this will be a link, providing you with immediate access to the job details and execution stats.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2025/05/image-10-1024x950.png" alt="SQL Server agent job info from running queries." class="wp-image-745" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;&lt;del&gt;These features should make their way into the next version of DBA Dash, 3.23. Or they might already be available by the time you read this.&lt;/del&gt;&lt;/p&gt;&#10;&lt;p&gt;Edit: 3.23 is here now! 🚀&lt;/p&gt;&#10;&lt;p&gt;Thanks for reading!&lt;/p&gt;&#10;</description></item><item><title>Removing large backup history with sp_delete_backuphistory</title><link>https://wisedataman.com/removing-large-backup-history-with-sp_delete_backuphistory/</link><pubDate>Sun, 04 Feb 2024 15:04:57 +0000</pubDate><guid>https://wisedataman.com/removing-large-backup-history-with-sp_delete_backuphistory/</guid><description>&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;&#10;&lt;p&gt;In SQL Server, the &lt;a href="https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-delete-backuphistory-transact-sql?view=sql-server-ver16"&gt;sp_delete_backuphistory&lt;/a&gt; stored procedure is is the standard and supported method to purge old data from the backup and restore history tables in the msdb database:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;backupfile&lt;/li&gt;&#10;&lt;li&gt;backupfilegroup&lt;/li&gt;&#10;&lt;li&gt;backupmediafamily&lt;/li&gt;&#10;&lt;li&gt;backupmediaset&lt;/li&gt;&#10;&lt;li&gt;backupset&lt;/li&gt;&#10;&lt;li&gt;restorefile&lt;/li&gt;&#10;&lt;li&gt;restorefilegroup&lt;/li&gt;&#10;&lt;li&gt;restorehistory&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Recently, I encountered an issue running sp_delete_backuphistory on servers that hosted a &lt;strong&gt;large number of databases&lt;/strong&gt; with &lt;strong&gt;frequent log backup &amp;amp; restore operations&lt;/strong&gt;. The clean up task hadn&amp;rsquo;t been scheduled and the history tables had &lt;strong&gt;grown very large over several months&lt;/strong&gt;. The msdb databases was also hosted on a &lt;strong&gt;volume with limited IOPs&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;Attempting to run sp_delete_backuphistory under these conditions you will likely encounter these issues:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;The operation will take a long time&lt;/li&gt;&#10;&lt;li&gt;Log backup and restore operations are blocked during the process&lt;/li&gt;&#10;&lt;li&gt;Your msdb log file will grow large if you try to remove too much data at once&lt;/li&gt;&#10;&lt;li&gt;If you kill off the process at any point, the whole thing will rollback.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;The sp_delete_backuphistory stored procedure gets the job done in most cases but it&amp;rsquo;s not very well optimized if you have a large amount of history to clear.&lt;/p&gt;&#10;&lt;h2 id="optimized-solution-for-backup-history-cleanup"&gt;Optimized Solution for Backup History Cleanup&lt;/h2&gt;&#10;&lt;p&gt;To clear a large amount of history without resorting to schema modifications or unsupported methods we can take an incremental approach to removing data.&lt;/p&gt;&#10;&lt;p&gt;The script below will check how much retention we currently have. It will then call sp_delete_backuphistory in a loop, removing data 1hr (&lt;em&gt;configurable&lt;/em&gt;) at a time until we hit the target retention. We can also specify a maximum runtime for the process.&lt;/p&gt;&#10;&lt;p&gt;This approach won&amp;rsquo;t necessarily speed things up but it provides the following benefits:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Data is cleared as a series of smaller transactions rather than a single large transaction&lt;/li&gt;&#10;&lt;li&gt;Smaller transactions allow for log truncation and prevent the log file from growing.&lt;/li&gt;&#10;&lt;li&gt;We can interrupt the process without having to rollback all the progress that has been made. (just the current batch)&lt;/li&gt;&#10;&lt;li&gt;Log backups/restores might still be blocked, but only for the duration it takes to complete a single loop - not for the entire time it takes to clear the history. &lt;em&gt;This can still impact RPO/RTO though.&lt;/em&gt;&lt;/li&gt;&#10;&lt;li&gt;We can control how long the process runs for. We can keep it running outside business hours or allow for breaks to prevent log backup/restores from falling too far behind.&lt;/li&gt;&#10;&lt;li&gt;The script will print progress information.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;span class="lnt"&gt;23&#10;&lt;/span&gt;&lt;span class="lnt"&gt;24&#10;&lt;/span&gt;&lt;span class="lnt"&gt;25&#10;&lt;/span&gt;&lt;span class="lnt"&gt;26&#10;&lt;/span&gt;&lt;span class="lnt"&gt;27&#10;&lt;/span&gt;&lt;span class="lnt"&gt;28&#10;&lt;/span&gt;&lt;span class="lnt"&gt;29&#10;&lt;/span&gt;&lt;span class="lnt"&gt;30&#10;&lt;/span&gt;&lt;span class="lnt"&gt;31&#10;&lt;/span&gt;&lt;span class="lnt"&gt;32&#10;&lt;/span&gt;&lt;span class="lnt"&gt;33&#10;&lt;/span&gt;&lt;span class="lnt"&gt;34&#10;&lt;/span&gt;&lt;span class="lnt"&gt;35&#10;&lt;/span&gt;&lt;span class="lnt"&gt;36&#10;&lt;/span&gt;&lt;span class="lnt"&gt;37&#10;&lt;/span&gt;&lt;span class="lnt"&gt;38&#10;&lt;/span&gt;&lt;span class="lnt"&gt;39&#10;&lt;/span&gt;&lt;span class="lnt"&gt;40&#10;&lt;/span&gt;&lt;span class="lnt"&gt;41&#10;&lt;/span&gt;&lt;span class="lnt"&gt;42&#10;&lt;/span&gt;&lt;span class="lnt"&gt;43&#10;&lt;/span&gt;&lt;span class="lnt"&gt;44&#10;&lt;/span&gt;&lt;span class="lnt"&gt;45&#10;&lt;/span&gt;&lt;span class="lnt"&gt;46&#10;&lt;/span&gt;&lt;span class="lnt"&gt;47&#10;&lt;/span&gt;&lt;span class="lnt"&gt;48&#10;&lt;/span&gt;&lt;span class="lnt"&gt;49&#10;&lt;/span&gt;&lt;span class="lnt"&gt;50&#10;&lt;/span&gt;&lt;span class="lnt"&gt;51&#10;&lt;/span&gt;&lt;span class="lnt"&gt;52&#10;&lt;/span&gt;&lt;span class="lnt"&gt;53&#10;&lt;/span&gt;&lt;span class="lnt"&gt;54&#10;&lt;/span&gt;&lt;span class="lnt"&gt;55&#10;&lt;/span&gt;&lt;span class="lnt"&gt;56&#10;&lt;/span&gt;&lt;span class="lnt"&gt;57&#10;&lt;/span&gt;&lt;span class="lnt"&gt;58&#10;&lt;/span&gt;&lt;span class="lnt"&gt;59&#10;&lt;/span&gt;&lt;span class="lnt"&gt;60&#10;&lt;/span&gt;&lt;span class="lnt"&gt;61&#10;&lt;/span&gt;&lt;span class="lnt"&gt;62&#10;&lt;/span&gt;&lt;span class="lnt"&gt;63&#10;&lt;/span&gt;&lt;span class="lnt"&gt;64&#10;&lt;/span&gt;&lt;span class="lnt"&gt;65&#10;&lt;/span&gt;&lt;span class="lnt"&gt;66&#10;&lt;/span&gt;&lt;span class="lnt"&gt;67&#10;&lt;/span&gt;&lt;span class="lnt"&gt;68&#10;&lt;/span&gt;&lt;span class="lnt"&gt;69&#10;&lt;/span&gt;&lt;span class="lnt"&gt;70&#10;&lt;/span&gt;&lt;span class="lnt"&gt;71&#10;&lt;/span&gt;&lt;span class="lnt"&gt;72&#10;&lt;/span&gt;&lt;span class="lnt"&gt;73&#10;&lt;/span&gt;&lt;span class="lnt"&gt;74&#10;&lt;/span&gt;&lt;span class="lnt"&gt;75&#10;&lt;/span&gt;&lt;span class="lnt"&gt;76&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-tsql" data-lang="tsql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/********************* Params *******************/&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@RetentionDays&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;INT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* How long should we keep the data for in days */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Mins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;INT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* Delete data X minutes at a time. Small interval keeps transaction short. Less blocking and log usage*/&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@MaxRuntimeMins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;INT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* Stop processing if runtime exceeds this threshold */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/************************************************/&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TargetDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DATETIME&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DATETIME&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;NVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@t1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DATETIME&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Duration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;INT&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TotalDuration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;BIGINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@IterationCount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;INT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@StopAt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DATETIME&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/* The target date we want to get to based on the specified @RetentionDays */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TargetDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;@RetentionDays&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;GETDATE&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/* When should we stop processing batches based on @MaxRuntimeMins */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@StopAt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@MaxRuntimeMins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;GETDATE&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/* Get the oldest backup finish date from table. We will start removing data older than this point + @Mins minutes */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;backup_finish_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;msdb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backupset&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;PRINT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Oldest Date: &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;PRINT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Target Date: &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TargetDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;PRINT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Max Run Time (Mins): &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@MaxRuntimeMins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;, Processing will stop after &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@StopAt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/* Process the delete operation in small chunks until we reach the target date for our retention */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHILE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="cm"&gt;/* Increment date by @Mins minutes */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@Mins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="cm"&gt;/* Ensure that we don&amp;#39;t overshoot our target date */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;IF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TargetDate&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TargetDate&lt;/span&gt;&lt;span class="w"&gt;&#9;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@IterationCount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@IterationCount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="cm"&gt;/* &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;Print message using RAISERROR WITH NOWAIT so message is printed immediately. &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;For keeping track of progress &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;*/&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;CONVERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;GETDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; Start iteration &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@IterationCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;: Removing backup history before &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;RAISERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NOWAIT&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@t1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;SYSUTCDATETIME&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="cm"&gt;/* Remove the history up to @oldest_date (@Mins minutes worth of history) */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;EXEC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;msdb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dbo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sp_delete_backuphistory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="cm"&gt;/* Print how long this iteration took &amp;amp; keep track of total duration and iteration count */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Duration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DATEDIFF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;SYSUTCDATETIME&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TotalDuration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@TotalDuration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Duration&lt;/span&gt;&lt;span class="w"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;CONVERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;GETDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; Iteration &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@IterationCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; completed in (hh:mi:ss:mmm): &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;CONVERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;RAISERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NOWAIT&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="cm"&gt;/* Stop once we hit our target date for retention or we have ran for longer than @MaxRuntimeMins */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;IF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="nv"&gt;@TargetDate&lt;/span&gt;&lt;span class="w"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="ow"&gt;OR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;GETDATE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@StopAt&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;BREAK&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;Print overall stats &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;Accounting for possibility that total duration could span &amp;gt; 1 day&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@Message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Completed &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nv"&gt;@IterationCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; iterations in &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NULLIF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;DATEDIFF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@TotalDuration&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;NVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; Days &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="nf"&gt;LEFT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;CONVERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@TotalDuration&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; (hh:mi:ss), Avg Duration: &amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;CONVERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;DATEADD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;@TotalDuration&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;NULLIF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@IterationCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; (hh:mi:ss:mmm). Reached target date: &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHEN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@oldest_date&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="nv"&gt;@TargetDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;THEN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;YES&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ELSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NO&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RAISERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NOWAIT&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;h2 id="links"&gt;Links:&lt;/h2&gt;&#10;&lt;p&gt;These related links might be interesting:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.brentozar.com/archive/2018/02/the-annals-of-hilariously-bad-code-part-1/"&gt;https://www.brentozar.com/archive/2018/02/the-annals-of-hilariously-bad-code-part-1/&lt;/a&gt;&lt;br&gt;&#10;&lt;a href="https://www.brentozar.com/archive/2018/02/annals-hilariously-bad-code-part-2/"&gt;https://www.brentozar.com/archive/2018/02/annals-hilariously-bad-code-part-2/&lt;/a&gt;&lt;br&gt;&#10;&lt;a href="https://dba.stackexchange.com/questions/233375/how-to-minimize-plan-ahead-the-effect-of-running-sp-delete-backuphistory-measur"&gt;https://dba.stackexchange.com/questions/233375/how-to-minimize-plan-ahead-the-effect-of-running-sp-delete-backuphistory-measur&lt;/a&gt;&lt;/p&gt;&#10;</description></item><item><title>T-SQL Tuesday #156 Production Code</title><link>https://wisedataman.com/t-sql-tuesday-156-production-code/</link><pubDate>Tue, 08 Nov 2022 08:31:01 +0000</pubDate><guid>https://wisedataman.com/t-sql-tuesday-156-production-code/</guid><description>&lt;figure class="wp-block-image aligncenter size-thumbnail"&gt;&lt;a href="https://straightforwardsql.com/posts/production-code/"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/09/MJTuesday-150x150.png" alt="" class="wp-image-675" loading="lazy"&gt;&lt;/a&gt;&lt;/figure&gt;&#10;&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;&#10;&lt;p&gt;The &lt;a href="https://straightforwardsql.com/posts/production-code/"&gt;invitation&lt;/a&gt; from &lt;a href="https://straightforwardsql.com/about/"&gt;Tom Zíka&lt;/a&gt; asks &amp;ldquo;&lt;strong&gt;Which quality makes code production grade?&lt;/strong&gt;&amp;rdquo;.&lt;/p&gt;&#10;&lt;h2 id="reliability"&gt;Reliability&lt;/h2&gt;&#10;&lt;p&gt;Code that runs in production should be reliable. It should produce consistent results, handle concurrency and deal with error situations.&lt;/p&gt;&#10;&lt;h2 id="performance--scalability"&gt;Performance &amp;amp; Scalability&lt;/h2&gt;&#10;&lt;p&gt;Production code needs to be able to scale. Scalability should be considered in the context of your own applications and their expected growth. Not everyone has to deal with the same scalability challenges as Google, Facebook or Twitter.&lt;/p&gt;&#10;&lt;p&gt;Performance is also important. It doesn&amp;rsquo;t matter how awesome your app is if it can&amp;rsquo;t return data fast enough for end users.&lt;/p&gt;&#10;&lt;p&gt;Fast and efficient code can save $$$ in running costs and keep end users happy.&lt;/p&gt;&#10;&lt;h2 id="security"&gt;Security&lt;/h2&gt;&#10;&lt;p&gt;Production code needs to be secure, following industry best practices. A security incident can cause severe reputational damage and financial impact.&lt;/p&gt;&#10;&lt;h2 id="maintainability"&gt;Maintainability&lt;/h2&gt;&#10;&lt;p&gt;Production code should be maintainable. Avoiding duplication and striving for simplicity.&lt;/p&gt;&#10;&lt;h2 id="reviewed"&gt;Reviewed&lt;/h2&gt;&#10;&lt;p&gt;Production code will often go through a code review by another developer before it&amp;rsquo;s accepted into the codebase.&lt;/p&gt;&#10;&lt;h2 id="tested"&gt;Tested&lt;/h2&gt;&#10;&lt;p&gt;Production code will go through a series of automated and human tests before it gets to production.&lt;/p&gt;&#10;&lt;h2 id="accurate"&gt;Accurate?&lt;/h2&gt;&#10;&lt;p&gt;Production code &lt;strong&gt;doesn&amp;rsquo;t&lt;/strong&gt; always have to produce accurate results. Accuracy can be very important in some situations. In others, you might be able to trade some accuracy for speed. e.g. Caching data, eventual consistency.&lt;br&gt;&#10;The number of active users on a website doesn&amp;rsquo;t need to be 100% accurate and can be out of date by the time it&amp;rsquo;s printed.&lt;/p&gt;&#10;&lt;h2 id="documented"&gt;Documented&lt;/h2&gt;&#10;&lt;p&gt;Production code should have comments and documentation.&lt;/p&gt;&#10;&lt;h2 id="other"&gt;Other&lt;/h2&gt;&#10;&lt;p&gt;You might have policies for coding standards to follow. This might include things like naming conventions, code formatting and other best practices.&lt;/p&gt;&#10;&lt;h2 id="does-it-need-to-be-perfect"&gt;Does it need to be perfect?&lt;/h2&gt;&#10;&lt;p&gt;Production code &lt;strong&gt;doesn&amp;rsquo;t&lt;/strong&gt; have to be perfect. Perfect code doesn&amp;rsquo;t really exist. The code we write today will be viewed through a different lens tomorrow with the benefit of hindsight, experience and new improved ways of doing things.&lt;/p&gt;&#10;&lt;p&gt;The code we ship to production needs to be fit for purpose. Shipping code that works and delivers value in a timely manner is often more important than spending months trying to find the most optimal solution. There is a balance to be struck.&lt;/p&gt;&#10;&lt;p&gt;Architectural decisions made early in a project can have long-lasting consequences. Making good decisions early in a project can be cheaper than fixing them later.&lt;/p&gt;&#10;&lt;p&gt;You can&amp;rsquo;t always predict how users will use a new feature and how to optimize it. Growing pains are inevitable for successful applications. It&amp;rsquo;s important to monitor and be proactive in fixing problems.&lt;/p&gt;&#10;&lt;h2 id="not-production-grade"&gt;Not production grade&lt;/h2&gt;&#10;&lt;p&gt;So what are some examples of code that shouldn&amp;rsquo;t be in production?&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Code that uses undocumented/unsupported features or behaviour&lt;/li&gt;&#10;&lt;li&gt;Untested code&lt;/li&gt;&#10;&lt;li&gt;Insecure code. e.g. Building dynamic SQL in a way that is prone to SQL injection.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;Production code can vary in quality for a variety of reasons. The experience level of the developer writing the code, time pressures, and level of fatigue all impact code quality.&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s not unusual for code written as a quick PoC to find its way into production. Code can also start to get messy over time as you start to shoehorn new features into an existing codebase.&lt;/p&gt;&#10;&lt;p&gt;If your code is delivering value to the end-user or business you can feel happy about it. Over time we all accumulate technical debt and need to allocate time to reduce it.&lt;/p&gt;&#10;</description></item><item><title>DBA Dash - What's new in 2.21.0? 🚀</title><link>https://wisedataman.com/dba-dash-whats-new-in-2-21-0/</link><pubDate>Tue, 09 Aug 2022 21:16:25 +0000</pubDate><guid>https://wisedataman.com/dba-dash-whats-new-in-2-21-0/</guid><description>&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;&#10;&lt;p&gt;The first public release of DBA Dash was in January 2022 and version 2.21.0 is the 24th release.🎉 A lot has changed with many new features added as well as bug fixes. I haven&amp;rsquo;t really blogged much about the changes, but I thought it might be good to capture what its new for significant releases. So here is what is new and cool in 2.21.0!&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;You can see the full change log &lt;a href="https://github.com/trimble-oss/dba-dash/releases"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="metrics-tab"&gt;Metrics tab&lt;/h2&gt;&#10;&lt;p&gt;The metrics tab was previously a wall of numbers - the Max, Min, Avg, Total &amp;amp; Current value of all the collected performance counters. At the click of a button you could see a chart for any counter over time for the selected period. It was limited to showing 1 chart at a time.&lt;/p&gt;&#10;&lt;p&gt;In 2.17.0 it was possible to configure threshold values for your counters - improving on the wall of numbers by highlighting counters that need your attention.&lt;/p&gt;&#10;&lt;p&gt;Now in 2.21.0 when you click &lt;strong&gt;view&lt;/strong&gt; to view a chart for a particular counter, it adds a new chart. You can view charts for multiple counters simultaneously. Also, you can add other charts that are not os performance counters - CPU, Blocking, IO, Object Execution and Waits. This provides additional context for your performance counters. You can re-order the charts and remove them at the click of a button.&lt;/p&gt;&#10;&lt;p&gt;Once you&amp;rsquo;ve created a useful dashboard you can save and re-load it at the click of a button. You can save the view for yourself or share it with your team.&lt;/p&gt;&#10;&lt;p&gt;See it in action &lt;a href="https://wisedataman.com/wp-content/uploads/2022/08/DBADash2.21.0.gif"&gt;here:&lt;/a&gt;&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;a href="https://wisedataman.com/wp-content/uploads/2022/08/DBADash2.21.0.gif"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/08/DBADash2.21.0.gif" alt="DBA Dash Metrics tab" class="wp-image-647" title="DBA Dash Metrics" loading="lazy"&gt;&lt;/a&gt;&lt;figcaption&gt;DBA Dash - Metrics tab&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Tip:&lt;/strong&gt; You can easily configure which performance counters are collected. Also, you can collect any metric you like that can be queried with T-SQL. See &lt;a href="https://github.com/trimble-oss/dba-dash/blob/main/Docs/OSPerformanceCounters.md"&gt;here&lt;/a&gt; for details on how to customize the collection.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="performance-summary-tab"&gt;Performance Summary tab&lt;/h2&gt;&#10;&lt;p&gt;The performance summary tab now has saved views the same as the metrics tab. You could save the layout previously but it wasn&amp;rsquo;t possible to save multiple versions or to share those with the rest of the team.&lt;/p&gt;&#10;</description></item><item><title>DBA Dash vs sp_WhoIsActive / spBlitzWho</title><link>https://wisedataman.com/dba-dash-vs-sp_whoisactive/</link><pubDate>Sun, 06 Feb 2022 22:12:36 +0000</pubDate><guid>https://wisedataman.com/dba-dash-vs-sp_whoisactive/</guid><description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="http://whoisactive.com/"&gt;sp_WhoIsActive&lt;/a&gt; and &lt;a href="https://www.brentozar.com/first-aid/sp_blitzwho/"&gt;sp_BlitzWho&lt;/a&gt; are popular stored procedures created by the database community. They both capture queries currently running on your server. If you are a seasoned DBA it&amp;rsquo;s likely you have come across one or both of these tools. sp_WhoIsActive in particular has been around for a &lt;strong&gt;very long time&lt;/strong&gt;, deployed to many, many thousands of servers. It&amp;rsquo;s helped me solve countless performance issues. Shout out to &lt;a href="http://dataeducation.com/about/"&gt;Adam Machanic&lt;/a&gt; who created the tool - Thank you!&lt;/p&gt;&#10;&lt;p&gt;The &lt;a href="https://www.brentozar.com/"&gt;Brent Ozar&lt;/a&gt; team created sp_BlitzWho due to licensing issues distributing sp_WhoIsActive. The licensing issues are no longer a concern as both tools are now open source and can be freely distributed. sp_BlitzWho still has a more permissive license but the difference isn&amp;rsquo;t likely to matter to most people. Both work great. Each has unique selling points. Include them on all your SQL Server deployments! The excellent &lt;a href="https://dbatools.io/"&gt;dbatools&lt;/a&gt; can help with that.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/trimble-oss/dba-dash"&gt;DBA Dash&lt;/a&gt; isn&amp;rsquo;t a stored procedure for showing active queries - it&amp;rsquo;s a full monitoring tool with a Windows app front end. So this is a bit of a weird comparison. It does capture running queries though which is where we can draw some comparisons.&lt;/p&gt;&#10;&lt;h2 id="re-inventing-the-wheel"&gt;Re-inventing the Wheel&lt;/h2&gt;&#10;&lt;p&gt;While developing DBA Dash I did consider just embedding sp_BlitzWho or sp_WhoIsActive rather than re-invent the wheel. Licensing was maybe a concern for sp_WhoIsActive but I had other reasons for creating my own solution. I wanted a solution &lt;strong&gt;designed specifically for regular collection.&lt;/strong&gt; sp_BlitzWho and sp_WhoIsActive can both log to a table. But they were designed for interactive use in SSMS.&lt;/p&gt;&#10;&lt;h2 id="performance"&gt;Performance&lt;/h2&gt;&#10;&lt;p&gt;The goal for DBA Dash was to limit the overhead of query collection. Also, I did not need or want the data to be formatted for human consumption on collection. The numbers below show a performance comparison. I&amp;rsquo;m using the defaults for each and averaging over 10 executions. 12 active queries were running for this test.&lt;/p&gt;&#10;&lt;figure class="wp-block-table"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Tool&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Avg CPU (ms)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Avg Duration (ms)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sp_WhoIsActive&lt;/td&gt;&lt;td&gt;159&lt;/td&gt;&lt;td&gt;166&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sp_BlitzWho&lt;/td&gt;&lt;td&gt;231&lt;/td&gt;&lt;td&gt;241&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DBA Dash (with session waits)&lt;/td&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;figcaption&gt;Performance Tests&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; I don&amp;rsquo;t worry about the overhead of running any of these tools interactively. Also, if you want to log the output to a table at regular intervals it&amp;rsquo;s not likely to hurt the performance of your server. Still, for regular monitoring, it&amp;rsquo;s good to keep overhead as low as possible.&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;If you want to test this for yourself, the capture query for DBA Dash is &lt;a href="https://github.com/trimble-oss/dba-dash/blob/main/DBADash/SQL/SQLRunningQueries.sql"&gt;here&lt;/a&gt;. Confession time - this &lt;strong&gt;isn&amp;rsquo;t a fair fight&lt;/strong&gt;. I&amp;rsquo;m not collecting query text or query plans. sp_BlizWho collects query plans by default so it&amp;rsquo;s at a disadvantage - the tools are not all doing the same thing. Also, the performance differences between these tools will vary based on several other factors.&lt;/p&gt;&#10;&lt;h3 id="so-how-does-dba-dash-show-query-text"&gt;So how does DBA Dash show query text?&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Takes a distinct list of sql_handles from the running query capture&lt;/li&gt;&#10;&lt;li&gt;Collect text associated with those handles (if required).&lt;/li&gt;&#10;&lt;li&gt;Cache the handles.&lt;/li&gt;&#10;&lt;li&gt;Ignore the handles we&amp;rsquo;ve already captured on subsequent collections.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Query plan capture features a similar optimization. Also, DBA Dash doesn&amp;rsquo;t need to do anything with the formatting of the data for human consumption - at least not on collection.&lt;/p&gt;&#10;&lt;p&gt;Query text and query plans are stored in separate tables. Not duplicated by row. DBA Dash can also take care of data retention - clearing out old data efficiently with some partition switching.&lt;/p&gt;&#10;&lt;p&gt;This isn&amp;rsquo;t just about efficient data collection. DBA Dash has a custom GUI and isn&amp;rsquo;t bound by the same constraints as sp_WhoIsActive and sp_BlitzWho. This allows us to do some interesting things.&lt;/p&gt;&#10;&lt;h2 id="summary-data"&gt;Summary Data&lt;/h2&gt;&#10;&lt;p&gt;At the top level, we see the summary of the last running queries snapshot for each instance. In this case, we can see some serious blocking going on with instance DASH2019.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-1024x210.png" alt="" class="wp-image-565" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;From there we can drill down to the DASH2019 instance and see a list of recent snapshots. We can also go back in time to any custom date range and see a list of the snapshots collected.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-1.png" alt="" class="wp-image-566" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;Use the summary data above to determine which snapshots are most interesting. Then drill down to the individual snapshots themselves:&lt;/p&gt;&#10;&lt;p&gt;[&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-2-1024x179.png" alt="" class="wp-image-567" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;](/wp-content/uploads/2022/02/image-2.png)&lt;/p&gt;&#10;&lt;h2 id="blocking"&gt;Blocking&lt;/h2&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-3.png" alt="" class="wp-image-581" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;In the screenshot above I&amp;rsquo;ve zoomed into the blocking section of the report. DBA Dash highlights the sessions blocked in the &amp;ldquo;Blocking Session ID&amp;rdquo; column. In some cases, there will be long blocking chains. This can make it difficult to work out which is the root blocker by looking at the blocking session id and traversing the blocking chain manually. With sp_WhoIsActive you can pass @find_block_leaders=1 to make this easier which gives you a blocked session count.&lt;/p&gt;&#10;&lt;p&gt;With DBA Dash you can just look at the &amp;ldquo;Blocking Hierarchy&amp;rdquo; column. Take session 64. This is blocked by session 79 and we have a hierarchy of &amp;ldquo;90 \ 79&amp;rdquo;. Session 79 is blocking the current session 64. Session 90 is blocking session 79 and is our root blocker. The &amp;ldquo;Root Blocker&amp;rdquo; column also identifies which sessions are root blockers. You can filter to show just the root blockers at the click of a button.&lt;/p&gt;&#10;&lt;p&gt;The &amp;ldquo;Blocked Count&amp;rdquo; column shows how many queries are blocked directly by a session. You also have a &amp;ldquo;Blocked Count Recursive&amp;rdquo; column that shows you a total count of sessions blocked by the query (directly/indirectly). The counts are also clickable - allowing you to navigate the blocking chain interactively.&lt;/p&gt;&#10;&lt;h3 id="so-whats-actually-going-on-in-this-snapshot"&gt;So what&amp;rsquo;s actually going on in this snapshot?&lt;/h3&gt;&#10;&lt;p&gt;DBA Dash identifies session 90 as the root blocker. Session 90 isn&amp;rsquo;t blocked or waiting on anything. The CPU time and reads are very small. The status column is &amp;ldquo;sleeping&amp;rdquo; and we should pay close attention to this. A sleeping session is dormant - waiting for input from the app. This is a problem if the session has an open transaction - holding locks needed by other sessions. DBA Dash gives us the user, hostname, application name along with the query text that will assist in tracking this down.&lt;/p&gt;&#10;&lt;p&gt;The root cause of this issue is an update statement that ran from SSMS. It had a BEGIN TRAN but didn&amp;rsquo;t issue a COMMIT or ROLLBACK. This left the transaction open, holding locks that caused the blocking.&lt;/p&gt;&#10;&lt;p&gt;Sleeping sessions causing blocking are something to watch out for. It might indicate problems that need to be fixed in the app. e.g. Not using the &amp;ldquo;using&amp;rdquo; pattern, doing slow work in the middle of the transaction like calling a web service.&lt;/p&gt;&#10;&lt;h2 id="waits"&gt;Waits&lt;/h2&gt;&#10;&lt;p&gt;DBA Dash shows what queries are currently waiting on. It also captures the wait resource and parses the wait resource to make it easier to decipher. Session level waits are also available in DBA Dash (and sp_BlitzWho). DBA Dash extends this by providing a clickable link that will show the session level waits in table format with more detail.&lt;/p&gt;&#10;&lt;h2 id="text"&gt;Text&lt;/h2&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-4.png" alt="" class="wp-image-582" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;DBA Dash gives you the statement text and the full query text associated with the SQL handle. Just click the links in the grid to see the text formatted in a new window.&lt;/p&gt;&#10;&lt;h2 id="plans"&gt;Plans&lt;/h2&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-5.png" alt="" class="wp-image-583" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;DBA Dash can show you query plans at the click of a button. Configure this using the service configuration tool. The collection process is optimized the same as for query text. Also, you can reduce the cost of collection further with plan collection thresholds.&lt;/p&gt;&#10;&lt;p&gt;A query plan tells you exactly how SQL Server was attempting to process the query. It also gives you the parameters that were used to compile the query plan.&lt;/p&gt;&#10;&lt;h2 id="batch-completed--rpc-completed"&gt;Batch Completed / RPC Completed&lt;/h2&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-6-1024x455.png" alt="" class="wp-image-584" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;Having the batch text and statement is great. For a typical RPC call, we can see the current statement along with the text of the associated stored procedure (or batch). What&amp;rsquo;s missing are the parameter values passed in from the client application. Unfortunately, we can&amp;rsquo;t get this by querying the DMVs. DBA Dash has a trick up its sleeve though. We can enable the capture of slow queries which creates an extended event session to capture queries that take longer than 1 second to run (configurable).&lt;/p&gt;&#10;&lt;p&gt;What&amp;rsquo;s cool is that you can click a session ID in running queries and see the associated RPC/batch completed event. This gives you the metrics associated with the completed execution and also the query text with the parameter values. Having the parameter values is useful when trying to reproduce and diagnose performance issues.&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;Note: The associated RPC/batch completed event is only available if the query has completed. It also needs to meet the threshold for collection. DBA Dash collects this data every 1min by default which adds additional delay. For the most recent snapshot, you might need to wait before the RPC/batch completed event is available.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h3 id="full-duplex"&gt;Full Duplex&lt;/h3&gt;&#10;&lt;p&gt;The link between running queries and RPC/batch completed is two-way. The Slow Queries tab shows you the RPC/batch completed events captured from the extended events session. From here you can click the session id and see all the running queries snapshots captured for that session while the query was running. Having access to the running queries snapshots can help answer questions about why a query was slow.&lt;br&gt;&#10;e.g. Was it blocked?&lt;br&gt;&#10;What was it waiting for?&lt;br&gt;&#10;What was the query plan used?&lt;br&gt;&#10;What statement was running?&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;Note: For queries with shorter execution times you might not have any data as running queries is captured every 1min by default.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="grouping-and-export"&gt;Grouping and Export&lt;/h2&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-7-1024x137.png" alt="" class="wp-image-585" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;You can group the running query capture in DBA Dash with the click of a button. For example, you might want to count the number of running queries by application, query hash, hostname&amp;hellip;.lots of options here. From there you can drill down to see the queries associated with your selected group value.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img src="https://wisedataman.com/wp-content/uploads/2022/02/image-8.png" alt="" class="wp-image-586" loading="lazy"&gt;&lt;/figure&gt;&#10;&lt;p&gt;Exporting the data to Excel is also just a click away.&lt;/p&gt;&#10;&lt;h2 id="not-a-gui-person"&gt;Not a GUI person?&lt;/h2&gt;&#10;&lt;p&gt;The captured running query data is available in the DBA Dash repository database for you to query manually if required. I&amp;rsquo;d recommend using the &lt;a href="https://github.com/trimble-oss/dba-dash/blob/main/DBADashDB/dbo/Views/RunningQueriesInfo.sql"&gt;dbo.RunningQueriesInfo&lt;/a&gt; view. The application calls &lt;a href="https://github.com/trimble-oss/dba-dash/blob/main/DBADashDB/dbo/Stored%20Procedures/RunningQueries_Get.sql"&gt;dbo.RunningQueries_Get&lt;/a&gt; to return a specific snapshot (which uses the view).&lt;/p&gt;&#10;&lt;h2 id="wrap-up"&gt;Wrap up&lt;/h2&gt;&#10;&lt;p&gt;Running queries capture is just a small (but interesting) part of what DBA Dash can do. There is a lot more that the tool can do - pair DBA Dash with query store and you have a lot of bases covered.&lt;/p&gt;&#10;&lt;p&gt;sp_WhoIsActive and sp_BlitzWho still have a place in my toolbox. I use them often. They are great tools and DBA Dash doesn&amp;rsquo;t replace them. I&amp;rsquo;m, running these tools interactively where DBA Dash is capturing valuable performance data round the clock for both current and retrospective analysis.&lt;/p&gt;&#10;&lt;p&gt;There is a lot of value in running a quick command in SSMS and having the results available immediately - in the same tool. With DBA Dash you have to wait for the next scheduled collection which is every 1min by default. Also, not everyone will want a full monitoring tool just to capture running queries. sp_WhoIsActive and sp_BitzWho both have their unique selling points and DBA Dash doesn&amp;rsquo;t replicate all their features and functionality.&lt;/p&gt;&#10;&lt;p&gt;If you haven&amp;rsquo;t tried DBA Dash, it&amp;rsquo;s a free monitoring tool for SQL Server that I created. My employer &lt;a href="https://www.trimble.com/"&gt;Trimble&lt;/a&gt; has allowed me to share the tool open source and it&amp;rsquo;s available on GitHub &lt;a href="https://github.com/trimble-oss/dba-dash"&gt;here&lt;/a&gt;. sp_WhoIsActive and sp_BlitzWho are also open source. Give them a try today.&lt;/p&gt;&#10;</description></item><item><title>Get drive data for ALL drives in T-SQL</title><link>https://wisedataman.com/get-drive-data-for-all-drives-in-t-sql/</link><pubDate>Wed, 24 Mar 2021 21:48:49 +0000</pubDate><guid>https://wisedataman.com/get-drive-data-for-all-drives-in-t-sql/</guid><description>&lt;p&gt;There are a few methods you can use to get drive information using T-SQL. The problem is all these methods have some limitations. They provide free space but not drive capacity or they only provide data for volumes that contain database files. Ideally Microsoft would provide an easy way to get both drive capacity and free space for all drives. In this article I&amp;rsquo;ll demonstrate a way to do this using T-SQL.&lt;/p&gt;&#10;&lt;p&gt;Here are a few exiting methods that you might consider before we continue:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&lt;div class="code-title"&gt;Get drive information using T-SQL&lt;/div&gt;&#10; &lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-tsql" data-lang="tsql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Gets size and free space but only for volumes that have SQL data files.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volume_mount_point&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DriveLetter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;POWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1024.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SizeGB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;available_bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;POWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1024.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FreeGB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logical_volume_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;master_files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CROSS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;APPLY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_os_volume_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Needs SQL 2019 &amp;amp; free space only&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fixed_drive_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="n"&gt;drive_type_desc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="n"&gt;free_space_in_bytes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;POWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1024.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FreeGB&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dm_os_enumerate_fixed_drives&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Gets free space on drive only&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;EXEC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xp_fixeddrives&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;If these work for your needs, great! If you need capacity and free space for ALL drives you will need a different solution. The best option might be to query that data outside of SQL Server using PowerShell or your programming/scripting language of choice. If you need to do this in T-SQL though, the script below provides a way.&lt;/p&gt;&#10;&lt;p&gt;The script uses xp_cmdshell to run a powershell command to get data for ALL the volumes on your system. Powershell formats this data as XML which we capture in the @output table variable - 1 row per line of XML. Then we convert this back to a single string and store as XML in variable @x. We then shred the XML into a table format. This is a bit of a hack - sys.dm_os_volume_stats is a cleaner method but doesn&amp;rsquo;t give you data for all drives. As a bonus you get more detailed data about those drives; file system, allocation unit size &amp;amp; more.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&lt;div class="code-title"&gt;Drive information for ALL drives using T-SQL&lt;/div&gt;&#10; &lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;span class="lnt"&gt;13&#10;&lt;/span&gt;&lt;span class="lnt"&gt;14&#10;&lt;/span&gt;&lt;span class="lnt"&gt;15&#10;&lt;/span&gt;&lt;span class="lnt"&gt;16&#10;&lt;/span&gt;&lt;span class="lnt"&gt;17&#10;&lt;/span&gt;&lt;span class="lnt"&gt;18&#10;&lt;/span&gt;&lt;span class="lnt"&gt;19&#10;&lt;/span&gt;&lt;span class="lnt"&gt;20&#10;&lt;/span&gt;&lt;span class="lnt"&gt;21&#10;&lt;/span&gt;&lt;span class="lnt"&gt;22&#10;&lt;/span&gt;&lt;span class="lnt"&gt;23&#10;&lt;/span&gt;&lt;span class="lnt"&gt;24&#10;&lt;/span&gt;&lt;span class="lnt"&gt;25&#10;&lt;/span&gt;&lt;span class="lnt"&gt;26&#10;&lt;/span&gt;&lt;span class="lnt"&gt;27&#10;&lt;/span&gt;&lt;span class="lnt"&gt;28&#10;&lt;/span&gt;&lt;span class="lnt"&gt;29&#10;&lt;/span&gt;&lt;span class="lnt"&gt;30&#10;&lt;/span&gt;&lt;span class="lnt"&gt;31&#10;&lt;/span&gt;&lt;span class="lnt"&gt;32&#10;&lt;/span&gt;&lt;span class="lnt"&gt;33&#10;&lt;/span&gt;&lt;span class="lnt"&gt;34&#10;&lt;/span&gt;&lt;span class="lnt"&gt;35&#10;&lt;/span&gt;&lt;span class="lnt"&gt;36&#10;&lt;/span&gt;&lt;span class="lnt"&gt;37&#10;&lt;/span&gt;&lt;span class="lnt"&gt;38&#10;&lt;/span&gt;&lt;span class="lnt"&gt;39&#10;&lt;/span&gt;&lt;span class="lnt"&gt;40&#10;&lt;/span&gt;&lt;span class="lnt"&gt;41&#10;&lt;/span&gt;&lt;span class="lnt"&gt;42&#10;&lt;/span&gt;&lt;span class="lnt"&gt;43&#10;&lt;/span&gt;&lt;span class="lnt"&gt;44&#10;&lt;/span&gt;&lt;span class="lnt"&gt;45&#10;&lt;/span&gt;&lt;span class="lnt"&gt;46&#10;&lt;/span&gt;&lt;span class="lnt"&gt;47&#10;&lt;/span&gt;&lt;span class="lnt"&gt;48&#10;&lt;/span&gt;&lt;span class="lnt"&gt;49&#10;&lt;/span&gt;&lt;span class="lnt"&gt;50&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-tsql" data-lang="tsql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/* &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;Created by David Wiseman&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;https://wiseDATAman.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;Get drive information for all drives via T-SQL.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;This requires access to xp_cmdshell&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;*/&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;IF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;EXISTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configurations&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;xp_cmdshell&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="ow"&gt;AND&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value_in_use&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;AND&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;EXISTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fn_my_permissions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;xp_cmdshell&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;OBJECT&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;permission_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;EXECUTE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NOCOUNT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;XML&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;TABLE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;INT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;IDENTITY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;NVARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INTO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@output&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;EXEC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xp_cmdshell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;powershell -noprofile -Command &amp;#34; &amp;amp; { ConvertTo-Xml -As &amp;#34;String&amp;#34; -NoTypeInformation -InputObject (Get-Volume | Select-Object -Property DriveLetter,Size,SizeRemaining,FileSystem,FileSystemLabel,AllocationUnitSize,DriveType,FileSystemType,HealthStatus,OperationalStatus,UniqueId )}&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="cm"&gt;/* Alternative option for SQL 2017+&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;SELECT @x = STRING_AGG(line,CHAR(13) + CHAR(10)) WITHIN GROUP (ORDER BY ID) &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;FROM @output&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;WHERE ID&amp;gt;1 -- skip encoding line&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#9;*/&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@output&lt;/span&gt;&lt;span class="w"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- skip encoding line&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;XML&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PATH&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="n"&gt;TYPE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(MAX)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;DriveLetter&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CHAR(1)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DriveLetter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;Size&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BIGINT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;POWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1024.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SizeGB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;SizeRemaining&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BIGINT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;POWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1024.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FreeGB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;FileSystem&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(256)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FileSystem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;FileSystemLabel&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(256)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FileSystemLabel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;AllocationUnitSize&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;INT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AllocationUnitSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;DriveType&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(256)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DriveType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;FileSystemType&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(256)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FileSystemType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;HealthStatus&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(256)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HealthStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;OperationalStatus&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(256)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OperationalStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(Property[@Name=&amp;#34;UniqueId&amp;#34;])[1]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NVARCHAR(256)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UniqueId&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/Objects/Object/Property&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ELSE&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;RAISERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;xp_cmdshell required&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;A similar technique could be used to capture the output of other powershell commands in T-SQL. It might not be a &lt;strong&gt;&lt;em&gt;good&lt;/em&gt;&lt;/strong&gt; idea but I think it is an interesting technique to demo.&lt;/p&gt;&#10;</description></item><item><title>How to handle SQL Agent Jobs with Always On Availability Groups?</title><link>https://wisedataman.com/how-to-handle-sql-agent-jobs-with-always-on-availability-groups/</link><pubDate>Wed, 17 Mar 2021 22:43:52 +0000</pubDate><guid>https://wisedataman.com/how-to-handle-sql-agent-jobs-with-always-on-availability-groups/</guid><description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;&#10;&lt;p&gt;When you configure your SQL servers for high availability you want the failover to be as seamless as possible. If you use availability groups, mirroring or log shipping as part of your high availability strategy you will need to take care of anything that lives outside the context of your databases. That might include logins, SQL Server agent jobs and ensuring consistent server level configuration across your availability nodes. This article will discuss how to handle SQL server agent jobs.&lt;/p&gt;&#10;&lt;h2 id="not-so-seamless-failover-of-agent-jobs"&gt;Not so seamless failover of agent jobs&lt;/h2&gt;&#10;&lt;p&gt;If you have any SQL agent jobs that run in the context of your user databases these will need special handling to ensure a seamless failover. Ideally Microsoft would have added some improvements to the SQL agent to help with this. Maybe given us agent jobs that can live within the context of a user database instead of msdb?&lt;/p&gt;&#10;&lt;p&gt;As it stands you will need to keep your agent jobs in sync between the primary and secondaries and figure out a mechanism to activate the jobs on the new primary following failover and disable them on the old primary.&lt;/p&gt;&#10;&lt;h2 id="a-solution"&gt;A Solution&lt;/h2&gt;&#10;&lt;p&gt;There are a few ways to handle this, but my approach is to run all the jobs in the context of the master DB. I then check if the user DB is accessible and execute the command with a 3 part name. See the script below for an example. This will work for availability groups, mirroring and log shipping.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&lt;div class="code-title"&gt;Template T-SQL for Agent Job&lt;/div&gt;&#10; &lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-tsql" data-lang="tsql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DECLARE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@DB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SYSNAME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;MyDB&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;IF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DATABASEPROPERTYEX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Updateability&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;READ_WRITE&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="ow"&gt;AND&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;EXISTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;databases&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;@DB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;PRINT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Run command&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="c1"&gt;--EXEC MyDB.dbo.MyProc&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ELSE&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;PRINT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Not run: Database is not writeable&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;With this approach you can create your jobs and have them active on your primary and secondaries. You don&amp;rsquo;t need to worry about enabling/disabling jobs on failover - the jobs are already running but they only do any work if the database is primary. This makes the failover totally seamless. The downside to this approach is that the jobs will report that they ran successfully even if they didn&amp;rsquo;t do any work which could cause confusion.&lt;/p&gt;&#10;&lt;p&gt;The next problem is keeping the jobs in sync between your servers. You can script out the jobs using SSMS easy enough but this could get tedious if you have a larger number of jobs. I&amp;rsquo;ve created a powershell script below to help with this which you can use below. You can use this to report if your jobs are out of sync and also for performing a synchronization. See the comments at the top of the script for some usage examples.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&lt;div class="code-title"&gt;SyncSQLAgentJobs.ps1&lt;/div&gt;&#10; &lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 10&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 11&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 12&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 13&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 14&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 15&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 16&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 17&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 18&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 19&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 20&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 21&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 22&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 23&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 24&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 25&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 26&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 27&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 28&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 29&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 30&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 31&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 32&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 33&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 34&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 35&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 36&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 37&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 38&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 39&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 40&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 41&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 42&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 43&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 44&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 45&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 46&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 47&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 48&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 49&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 50&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 51&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 52&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 53&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 54&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 55&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 56&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 57&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 58&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 59&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 60&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 61&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 62&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 63&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 64&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 65&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 66&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 67&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 68&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 69&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 70&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 71&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 72&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 73&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 74&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 75&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 76&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 77&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 78&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 79&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 80&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 81&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 82&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 83&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 84&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 85&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 86&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 87&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 88&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 89&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 90&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 91&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 92&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 93&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 94&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 95&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 96&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 97&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 98&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 99&#10;&lt;/span&gt;&lt;span class="lnt"&gt;100&#10;&lt;/span&gt;&lt;span class="lnt"&gt;101&#10;&lt;/span&gt;&lt;span class="lnt"&gt;102&#10;&lt;/span&gt;&lt;span class="lnt"&gt;103&#10;&lt;/span&gt;&lt;span class="lnt"&gt;104&#10;&lt;/span&gt;&lt;span class="lnt"&gt;105&#10;&lt;/span&gt;&lt;span class="lnt"&gt;106&#10;&lt;/span&gt;&lt;span class="lnt"&gt;107&#10;&lt;/span&gt;&lt;span class="lnt"&gt;108&#10;&lt;/span&gt;&lt;span class="lnt"&gt;109&#10;&lt;/span&gt;&lt;span class="lnt"&gt;110&#10;&lt;/span&gt;&lt;span class="lnt"&gt;111&#10;&lt;/span&gt;&lt;span class="lnt"&gt;112&#10;&lt;/span&gt;&lt;span class="lnt"&gt;113&#10;&lt;/span&gt;&lt;span class="lnt"&gt;114&#10;&lt;/span&gt;&lt;span class="lnt"&gt;115&#10;&lt;/span&gt;&lt;span class="lnt"&gt;116&#10;&lt;/span&gt;&lt;span class="lnt"&gt;117&#10;&lt;/span&gt;&lt;span class="lnt"&gt;118&#10;&lt;/span&gt;&lt;span class="lnt"&gt;119&#10;&lt;/span&gt;&lt;span class="lnt"&gt;120&#10;&lt;/span&gt;&lt;span class="lnt"&gt;121&#10;&lt;/span&gt;&lt;span class="lnt"&gt;122&#10;&lt;/span&gt;&lt;span class="lnt"&gt;123&#10;&lt;/span&gt;&lt;span class="lnt"&gt;124&#10;&lt;/span&gt;&lt;span class="lnt"&gt;125&#10;&lt;/span&gt;&lt;span class="lnt"&gt;126&#10;&lt;/span&gt;&lt;span class="lnt"&gt;127&#10;&lt;/span&gt;&lt;span class="lnt"&gt;128&#10;&lt;/span&gt;&lt;span class="lnt"&gt;129&#10;&lt;/span&gt;&lt;span class="lnt"&gt;130&#10;&lt;/span&gt;&lt;span class="lnt"&gt;131&#10;&lt;/span&gt;&lt;span class="lnt"&gt;132&#10;&lt;/span&gt;&lt;span class="lnt"&gt;133&#10;&lt;/span&gt;&lt;span class="lnt"&gt;134&#10;&lt;/span&gt;&lt;span class="lnt"&gt;135&#10;&lt;/span&gt;&lt;span class="lnt"&gt;136&#10;&lt;/span&gt;&lt;span class="lnt"&gt;137&#10;&lt;/span&gt;&lt;span class="lnt"&gt;138&#10;&lt;/span&gt;&lt;span class="lnt"&gt;139&#10;&lt;/span&gt;&lt;span class="lnt"&gt;140&#10;&lt;/span&gt;&lt;span class="lnt"&gt;141&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;mandatory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$ServerA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;mandatory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$ServerB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;mandatory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;System.Array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$ExcludedCategories&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c"&gt;#Job categories to exclude from the synchronization process.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;mandatory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;System.Array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$IncludedCategories&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c"&gt;#Job categories to include in the synchronization process.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;mandatory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$DoSync&lt;/span&gt; &lt;span class="c"&gt;#perform a two way synchronization if specified, otherwise run in reporting mode.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&amp;lt;# Created: 2017-12-06&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Author: David Wiseman&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Description: Sync agent jobs between two SQL Server instances or check synchronization status. This is useful if you are using a high availability technology like&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; availability groups, log shipping or database mirroring that does not include SQL Agent jobs in the failover. The script can be used to validate that the jobs are in sync&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; or it can synchronize the jobs. &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Requires SqlServer powershell module:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Install-Module -Name SqlServer -AllowClobber&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Example1: &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; ./SyncSQLAgentJobs -ServerA &amp;#34;SERVER1&amp;#34; -ServerB &amp;#34;SERVER2&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Agent jobs will be checked and differences will be reported. &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Example2: &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; ./SyncSQLAgentJobs -ServerA &amp;#34;SERVER1&amp;#34; -ServerB &amp;#34;SERVER2&amp;#34; -DoSync&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Any jobs that don&amp;#39;t exist will be copied from SERVER1 to SERVER2 and from SERVER2 to SERVER1. Any jobs that are different will be copied from the server with the newer version of the job (Based on DateLastModified). &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Example3: &#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; ./SyncSQLAgentJobs -ServerA &amp;#34;SERVER1&amp;#34; -ServerB &amp;#34;SERVER2&amp;#34; -DoSync ExcludedCategories &amp;#34;ADHOC&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Same as example 2 but jobs in the category &amp;#34;ADHOC&amp;#34; are excluded from synchronization.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; Note: SQL Agent loads SQLPS which isn&amp;#39;t compatible with SqlServer module. A workaround is to run the following powershell in the SQL Agent job.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; $Error.Clear()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; $out = powershell -NoProfile -Command &amp;#34;C:\Scripts\SyncSQLAgentJobs.ps1&amp;#34; -ServerA &amp;#34;SERVER1&amp;#34; -ServerB &amp;#34;SERVER2&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; if ($Error.Count -gt 0){&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; throw $out&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; else{&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; $out&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; This will ensure the job fails if anything is out of sync. The SQL Server agent account will need appropriate access to msdb database on both instances.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;#&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$ErrorActionPreference&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;stop&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Import-Module&lt;/span&gt; &lt;span class="n"&gt;SqlServer&lt;/span&gt; &lt;span class="n"&gt;-DisableNameChecking&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$IncludedCategories&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$jobs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Get-SqlAgentJob&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$ValidationStatus&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$errorMsg&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$jobs&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;ForEach-Object&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="vm"&gt;$null&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$scriptA&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Script&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;ForEach-Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$scriptA&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Get-SqlAgentJob&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="n"&gt;-ErrorAction&lt;/span&gt; &lt;span class="n"&gt;Ignore&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ExcludedCategories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Skipping &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; : Excluded category: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Category&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elseif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobB&lt;/span&gt; &lt;span class="o"&gt;-ne&lt;/span&gt; &lt;span class="vm"&gt;$null&lt;/span&gt; &lt;span class="o"&gt;-and&lt;/span&gt; &lt;span class="nv"&gt;$ExcludedCategories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Skipping &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; : Excluded category: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Category&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elseif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobA&lt;/span&gt; &lt;span class="o"&gt;-ne&lt;/span&gt; &lt;span class="vm"&gt;$null&lt;/span&gt; &lt;span class="o"&gt;-and&lt;/span&gt; &lt;span class="nv"&gt;$IncludedCategories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Count&lt;/span&gt; &lt;span class="o"&gt;-gt&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-and&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nv"&gt;$IncludedCategories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;))){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Skipping &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; : Not included category: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Category&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elseif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobB&lt;/span&gt; &lt;span class="o"&gt;-ne&lt;/span&gt; &lt;span class="vm"&gt;$null&lt;/span&gt; &lt;span class="o"&gt;-and&lt;/span&gt; &lt;span class="nv"&gt;$IncludedCategories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Count&lt;/span&gt; &lt;span class="o"&gt;-gt&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-and&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nv"&gt;$IncludedCategories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;))){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Skipping &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; : Not included category: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Category&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elseif&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobB&lt;/span&gt; &lt;span class="o"&gt;-eq&lt;/span&gt; &lt;span class="vm"&gt;$null&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ErrorMsg&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Missing on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;`n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Missing on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ValidationStatus&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$DoSync&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Creating job &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Invoke-Sqlcmd&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="n"&gt;-Query&lt;/span&gt; &lt;span class="nv"&gt;$scriptA&lt;/span&gt; &lt;span class="n"&gt;-DisableVariables&lt;/span&gt; &lt;span class="n"&gt;-DisableCommands&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$scriptB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Script&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;ForEach-Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$scriptB&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$scriptA&lt;/span&gt; &lt;span class="o"&gt;-eq&lt;/span&gt; &lt;span class="nv"&gt;$scriptB&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;OK: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;DateLastModified&lt;/span&gt; &lt;span class="o"&gt;-lt&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateLastModified&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ErrorMsg&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Different (Newer on &lt;/span&gt;&lt;span class="nv"&gt;$ServerB&lt;/span&gt;&lt;span class="s2"&gt;): &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;`n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Different (Newer on &lt;/span&gt;&lt;span class="nv"&gt;$ServerB&lt;/span&gt;&lt;span class="s2"&gt;): &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ValidationStatus&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$DoSync&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Dropping job &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$JobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Drop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Creating job &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Invoke-Sqlcmd&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt; &lt;span class="n"&gt;-Query&lt;/span&gt; &lt;span class="nv"&gt;$scriptB&lt;/span&gt; &lt;span class="n"&gt;-DisableVariables&lt;/span&gt; &lt;span class="n"&gt;-DisableCommands&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ErrorMsg&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Different (Newer on &lt;/span&gt;&lt;span class="nv"&gt;$ServerA&lt;/span&gt;&lt;span class="s2"&gt;): &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;`n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Different (Newer on &lt;/span&gt;&lt;span class="nv"&gt;$ServerA&lt;/span&gt;&lt;span class="s2"&gt;): &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ValidationStatus&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$DoSync&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Dropping job &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$JobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Drop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Creating job &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Invoke-Sqlcmd&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="n"&gt;-Query&lt;/span&gt; &lt;span class="nv"&gt;$scriptA&lt;/span&gt; &lt;span class="n"&gt;-DisableVariables&lt;/span&gt; &lt;span class="n"&gt;-DisableCommands&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$missingA&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Get-SqlAgentJob&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Where-Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Get-SqlAgentJob&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt; &lt;span class="n"&gt;-Name&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="n"&gt;-ErrorAction&lt;/span&gt; &lt;span class="n"&gt;Ignore&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="py"&gt;Count&lt;/span&gt; &lt;span class="o"&gt;-eq&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$missingA&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;ForEach-Object&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ExcludedCategories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Skipping &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerB&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; : Excluded category: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Category&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ErrorMsg&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Missing on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;`n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Missing on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$ValidationStatus&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$DoSync&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$scriptB&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Script&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;ForEach-Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$scriptB&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Creating job &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$jobB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; on &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;Invoke-Sqlcmd&lt;/span&gt; &lt;span class="n"&gt;-ServerInstance&lt;/span&gt; &lt;span class="nv"&gt;$ServerA&lt;/span&gt; &lt;span class="n"&gt;-Query&lt;/span&gt; &lt;span class="nv"&gt;$scriptB&lt;/span&gt; &lt;span class="n"&gt;-DisableVariables&lt;/span&gt; &lt;span class="n"&gt;-DisableCommands&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ValidationStatus&lt;/span&gt; &lt;span class="o"&gt;-eq&lt;/span&gt; &lt;span class="vm"&gt;$false&lt;/span&gt; &lt;span class="o"&gt;-and&lt;/span&gt; &lt;span class="nv"&gt;$DoSync&lt;/span&gt; &lt;span class="o"&gt;-eq&lt;/span&gt; &lt;span class="vm"&gt;$false&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$errorMsg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SQL Agent jobs require synchronization&lt;/span&gt;&lt;span class="se"&gt;`n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$errorMsg&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nv"&gt;$errorMsg&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;</description></item></channel></rss>