26 Validating your estate with dbachecks

For decades, most of the team writing this book had our own daily/weekly/monthly checklists to validate our SQL Server environments. At least once each day, we’d ensure that backups were scheduled and working as required. We’d check to see whether all of our integrity checks passed. We’d even spend a lot of time keeping our checklists up to date as our environment grew, and we learned more about managing SQL Server. Some of us performed this validation manually, whereas others created an automated routine that would perform the checks automatically.

What we didn’t have for all those years was a single, community-wide checklist—nor did we have have a free and open source framework to make our checks easier. Not having those meant a lot of wasted time and repeated work!

To address this problem, the SQL PowerShell community came together to create crowdsourced checks using dbatools and Pester (sqlps.io/pester) tests. This project became known as dbachecks.

26.1 What dbachecks and dbatools have in common

You may be wondering why we dedicated a chapter to dbachecks, a totally distinct PowerShell module from dbatools, in a book about dbatools. We did so for a number of reasons, including the following:

  • The dbatools team created dbachecks.

  • dbachecks relies heavily on dbatools.

  • dbachecks is basically an extension of dbatools.

  • Many of the things we needed as DBAs but weren’t quite in scope for dbatools went into dbachecks.

  • Most of us use dbachecks as often as we use dbatools.

dbachecks uses dbatools to get a number of different configurations and properties, and uses the Pester testing framework PowerShell module to check whether the results align with our desired outcome.

Pester makes it possible to create our own SQL Server tests using PowerShell, and, as Rob likes to say, “If you can get it with PowerShell, you can test it with Pester.” With the framework provided by dbachecks, it is now easy to create and share these tests with the SQL Server community in a centralized repository.

Like dbatools, you can install dbachecks right from the PowerShell Gallery. To install dbachecks for your own user account, run the code shown here.

Listing 26.1 Installing dbachecks

PS> Install-Module dbachecks -Scope CurrentUser

This will install dbachecks, as well as two modules it depends on: dbatools and PSFramework. Compatible versions of Pester are included in Windows, but if you need to install Pester manually, you must install version 4.10.1 or earlier, as seen in the next listing.

Listing 26.2 Specifying a version when installing dbachecks

PS> Install-Module Pester -RequiredVersion 4.10.1 -Scope CurrentUser

26.2 Our first check

Now that we have dbachecks installed, we can run our very first check. Because backups are one of the things data professionals care about most, we’ll make that our first check.

Previously in chapter 10, we showed how dbatools can help with database backups, and now, with dbachecks, we can run tests to ensure that our backups are running as expected. To check whether our databases have been running full backups in the last 24 hours, we’ll use the primary workhorse command: Invoke-DbcCheck. This is the command that performs all of the actual checks against both local and remote hosts. In the following listing, we’ll run one check, LastFullBackup, against one SQL Server instance, dbatoolslab.

Listing 26.3 Checking for last full backup in the previous 24 hours

PS> Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastFullBackup

Pretty easy, right? We tried to make this tool as easy as possible for our framework to be immediately useful. Ultimately, however, working with dbachecks can be as simple or as complex an experience as you’d like.

Regarding listing 26.3, you may also be wondering how we knew to specify the LastFullBackup value for the -Check parameter. We’ll get into that shortly, but before we do, let’s take a look at the output generated by executing the command shown next.

Listing 26.4 dbachecks output

PS> Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastFullBackup
 
Pester v4.10.1
Executing all tests in 'C:Program FilesWindowsPowerShellModules
dbachecks2.0.14checksDatabase.Tests.ps1' with Tags LastFullBackup
 
Executing script C:Program FilesWindowsPowerShellModulesdbachecks
2.0.14checksDatabase.Tests.ps1
 
  Describing Last Full Backup Times                                    
 
    Context Testing last full backups on dbatoolslab                   
      [-] Database AdventureWorks should have full backups less
          than 1 days old on dbatoolslab 8ms                           
        Expected the actual value to be greater than 2021-10-15T
        16:57:48.8673943Z, because Taking regular backups is
        extraordinarily important, but got
        2021-10-10T05:35:19.0000000Z.                                  
        498:           $psitem.LastBackupDate.ToUniversalTime() |
        Should -BeGreaterThan (Get-Date).ToUniversalTime().AddDays(
        - ($maxfull)) -Because "Taking regular backups is
        extraordinarily important"                                     
        at <ScriptBlock>, C:Program FilesWindowsPowerShellModules
        dbachecks2.0.14checksDatabase.Tests.ps1: line 498
      [+] Database master should have full backups less than 1 days
       old on dbatoolslab 7ms
      [+] Database model should have full backups less than 1 days
      old on dbatoolslab 10ms
      [+] Database msdb should have full backups less than 1 days
      old on dbatoolslab 11ms
Tests completed in 1.73s
Tests Passed: 3, Failed: 1, Skipped: 0, Pending: 0, Inconclusive: 0    

Describe block of the Pester test tells us the name of the current check we’re running.

The Context block of the Pester test tells us which SQL Server we’re running the tests against.

The It block of the Pester test has the details on what we tested and the result. The [-] shows it was a failed test.

On a failed test, we get more details on why it failed. We can see we should have had a backup since 2021-10-15, but the last one was on 2021-10-10.

Pester allows you to add a because block to your tests that tells us why we care that the test failed.

In the summary output , you can see that three tests passed but one failed, and it provides details on the database that doesn’t have a recent backup and why this is important.

Try it now 26.1

Run two checks against one of your SQL Server instances, and see whether your instance passes:

PS> Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastGoodCheckDb, 
 MaxMemory

26.3 Viewing all available checks

dbachecks currently provides over 130 tests, or checks, that help validate the health of our SQL Server estates. This number has steadily increased over time as more SQL Server DBAs have added their own checks to the toolset. The following code shows how to get a list of all available checks by running Get-DbcCheck.

Listing 26.5 dbachecks output

PS> Get-DbcCheck | Select-Object Group, UniqueTag
 
Group    UniqueTag           Description
-----    ---------           -----------
Agent    DatabaseMailEnabled Tests that the Database Mail XPs configu...
Agent    AgentServiceAccount Tests that the SQL Agent Account is runn...
Agent    DbaOperator         Tests that the specified (default blank)...
Agent    FailsafeOperator    Tests that the specified (default blank)...
Agent    DatabaseMailProfile Tests that the specified (default blank)...
Agent    AgentMailProfile    Tests to see if the SQL Server Agent Ale...
Agent    FailedJob           Tests that enabled Agent Jobs last outco...
Agent    ValidJobOwner       Tests that all Agent Jobs have a Job Own...
Agent    AgentAlert          Tests that there are Agent Alerts set up...
Agent    JobHistory          Tests that the job history configuration...
Agent    LongRunningJob      Tests that any currently running agent j...
Agent    LastJobRunTime      Tests that the last duration of the agen...
Database DatabaseCollation   Tests that the Database Collation matche...
Database SuspectPage         Tests that there are 0 Suspect Pages for...
Database TestLastBackup      Restores the last backup of a database o...
...

The command outputs more information by default, but we wanted to give a gentle introduction to a list of all checks that are available. We’ll explore the functionality of Get-DbcCheck further in listing 26.6.

26.4 Configuring the check parameters

Out of the box, dbachecks uses reasonable default values for each check. For example, LastFullBackup tests to see whether a full backup has been completed in the past 24 hours. This is reasonable if you take full backups daily, but some organizations have very different backup strategies. Luckily, dbachecks is flexible and allows users to customize to match their requirements. For example, let’s say an organization has the following strategy:

  • Full backups once a week

  • Differential backups each night

  • Transaction log backups (for databases in full recovery model) every four hours

This is pretty specific, but dbachecks is configurable enough to make this possible. Most, if not all, checks have configuration options available, which allows you to shape the dbachecks tests to be exactly what you’d expect in your environment.

You can discover the configuration options available for each check using Get-DbcCheck. The Config property, seen next, shows which options are available for the LastFullBackup check.

Listing 26.6 Viewing the metadata for the LastFullBackup check

PS> Get-DbcCheck -Tag LastFullBackup | Format-List
 
Group       : Database                                               
Type        : Sqlinstance                                            
UniqueTag   : LastFullBackup                                         
AllTags     : LastFullBackup, LastBackup, Backup, DISA,
              Varied, Database                                       
Config      : app.sqlinstance policy.backup.fullmaxdays
              policy.backup.newdbgraceperiod skip.backup.readonly
              skip.backup.secondaries                                
Description : Tests if the last full backup of a database is less
              than the specified number of days (default 1) except
              for offline databases and read-only databases
              (read-only if specified) and databases created
              recently (if specified).                               

The group this check falls into; this check runs at the database level.

The type of check tells us what object should be passed in.

Each check must have a unique tag; this is how we’ll call an individual check.

The check can also have more tags, which allows us to run multiple checks at once.

Config shows us the properties that we can control so the test will check we’re in the exact desired state.

Finally, we have a description of the check.

If you guessed that we’ll need to modify policy.backup.fullmaxdays, you were right.

Split the config property into a list

The example in listing 26.6 shows the config property is returned as a space-separated list. This isn’t the easiest to read, so you can use the Split method in PowerShell to split the space and create a list:

PS> (Get-DbcCheck -Tag LastFullBackup).config.Split(' ')
 
app.sqlinstance
policy.backup.fullmaxdays
policy.backup.newdbgraceperiod
skip.backup.readonly
skip.backup.secondaries

Before we make any changes, let’s first confirm the current value for policy.backup .fullmaxdays. In the next listing, we expect to see a value of 1, which is the default that is available out of the box.

Listing 26.7 Confirming the value for policy.backup.fullmaxdays

PS> Get-DbcConfig -Name policy.backup.fullmaxdays
 
Name                      Value Description
----                      ----- -----------
policy.backup.fullmaxdays     1 Maximum number of days before Full...

To see all current configurations, run Get-DbcConfig without any additional parameters.

Now that we’ve confirmed that policy.backup.fullmaxdays is set to 1, the next code snippet shows how we can update that value to 7.

Listing 26.8 Changing the config setting

PS> Set-DbcConfig -Name policy.backup.fullmaxdays -Value 7
 
Name                      Value Description
----                      ----- -----------
policy.backup.fullmaxdays     7 Maximum number of days before Full Backu...

We’ll also need to do the same to configure the settings for the differential and log backup thresholds.

Note The configurations are set in the registry, so once they have been set on the machine, they don’t need to be configured every time you run your checks.

Once the configuration is set up, we can run all the LastBackup checks to make sure our backup strategy is being met. This is shown in listing 26.9.

We’ve taken a full backup since the last failed check, so that should be back in our desired state. We’ve also specified Fails as the value for the -Show parameter on the call of Invoke-DbcCheck, which reduces the amount of output we see because only failed checks are highlighted.

Listing 26.9 Setting the config settings for full, diff, and t-log backups

PS> Set-DbcConfig -Name policy.backup.fullmaxdays -Value 7                  
PS> Set-DbcConfig -Name policy.backup.diffmaxhours -Value 24                
PS> Set-DbcConfig -Name policy.backup.logmaxminutes -Value 240              
 
PS> Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastBackup -Show Fails  
 
Pester v4.10.1
Executing all tests in 'C:Program FilesWindowsPowerShellModules
dbachecks2.0.14checksDatabase.Tests.ps1' with Tags LastBackup
 
Executing script C:Program FilesWindowsPowerShellModulesdbachecks
2.0.14checksDatabase.Tests.ps1
 
  Describing Last Full Backup Times                                         
 
    Context Testing last full backups on dbatoolslab
 
  Describing Last Diff Backup Times
 
    Context Testing last diff backups on dbatoolslab
 
  Describing Last Log Backup Times
 
    Context Testing last log backups on dbatoolslab
      [-] Database AdventureWorks log backups should be less than 240
          minutes old on dbatoolslab 7ms                                    
        Expected the actual value to be greater than 2021-10-20T00:42:26
        .6170000, because Taking regular backups is extraordinarily
        important, but got 2021-10-10T08:00:01.0000000Z.564:
        $psitem.LastLogBackupDate.ToUniversalTime() | Should -BeGreaterThan
        $sqlinstancedatetime.AddMinutes( - ($maxlog) + 1)
        -Because "Taking regular backups is extraordinarily important"
        at <ScriptBlock>, C:Program FilesWindowsPowerShellModules
        dbachecks2.0.14checksDatabase.Tests.ps1: line 564
Tests completed in 2.33s
Tests Passed: 5, Failed: 1, Skipped: 0, Pending: 0, <7> Inconclusive: 0

Sets the configuration to check for a differential backup within 24 hours/daily

Sets the configuration to check for a full backup within 7 days

Sets the configuration to check for a log backup within 240 minutes/4 hours

Uses the -Show parameter to determine how much detail is returned

No failed tests for the full backup checks, so just the headings appear in the output.

A failed test, with details, for our log backup check

Now that you’ve seen how to find and modify values for these three configuration options, you can apply the same technique to all configuration options within dbachecks. This will help you customize your checks to align with your organizational policies.

Try it now 26.2

Configure the full backup check configuration to meet your backup strategy needs, and then run the checks against an instance. Read through the results you get from dbachecks, and see if your backup strategy is being met:

PS> Set-DbcConfig -Name policy.backup.fullmaxdays -Value 7
PS> Invoke-DbcCheck -SqlInstance dbatoolslab -Check LastFullBackup

26.5 Storing the output data in a database

We’ve now seen how to run the checks, and we learned how to read and understand the output. This is perfect for a few single checks that we want to verify on-demand, but what you may find even more useful is collecting the results to analyze over time.

dbachecks makes it easy to save the results of each check to a database, which allows you to follow the check’s evolution over time. Being able to identify trends helps you make decisions about what resources are needed for your estate, like more storage or a bigger datatype for an identity column. In this section, we’ll learn how to both store the output and identify trends over time with a Power BI dashboard.

26.5.1 Storing data

To store dbachecks output in a database, we first need to convert the output of our tests to a format that SQL Server can understand. Within dbachecks, we use the Convert-DbcResult command. Once the results have been converted, we can save them to a specific database using Write-DbcTable, as shown in the following listing.

Listing 26.10 Running dbachecks and storing the results in a database

PS> $splatInvokeCheck = @{
  SqlInstance = "dbatoolslab"
  Check = "LastBackup"
  Passthru = $true
}
PS> Invoke-DbcCheck @splatInvokeCheck |
Convert-DbcResult -Label dbatoolsMol |
Write-DbcTable -SqlInstance dbatoolslab -Database DatabaseAdmin

The -Label parameter used in the Convert-DbcResult command is optional but can be useful when identifying and analyzing a specific set of results. If you’re curious about the output, the results of our own tests from listing 26.10 can be seen in figure 26.1.

Figure 26.1 dbachecks results are stored in our database.

As you run these checks over time, you will get a good picture of what your environment looks like day to day and how it’s changing. Depending on the check, it can also alert you to what needs to be addressed.

Try it now 26.3

Being able to easily store dbachecks data in a database is such a powerful feature. Have a go for yourself. Run one, or a few checks, for yourself, and push them straight into a database.

PS> $splatInvokeCheck = @{
  SqlInstance = "dbatoolslab"
  Check = "LastBackup"
  Passthru = $true
}
PS> Invoke-DbcCheck @splatInvokeCheck |
Convert-DbcResult -Label dbatoolsMol |
Write-DbcTable -SqlInstance dbatoolslab -Database DatabaseAdmin

26.5.2 Power BI dashboard

With the PowerShell module, we also provide a Power BI dashboard (.pbix file) with different visualizations to help us analyze the results of our checks. This dashboard will point to our database and read the data from there. For that we can use the Start-DbcPowerBi command to open the dashboard, as illustrated in the next code snippet.

Listing 26.11 Opening the dbachecks Power BI dashboard

PS> Start-DbcPowerBi -FromDatabase

Note You will need to have Microsoft Power BI desktop installed to open the dashboard.

26.5.3 Configuring the connection

When the dashboard opens, you will be prompted for the SqlInstance and ChecksResultDBName values, as shown in figure 26.2.

Figure 26.2 Configure PowerBI to connect to the database where check results are stored.

Next, click the Load button, and your data will appear, as shown in figure 26.3.

Figure 26.3 The PowerBI dbachecks dashboard gives us a good view of our estate.

26.6 Hands-on lab

Try the following tasks:

  • Check the documentation at sqlps.io/dbacheckslatest. We have lots of blog posts from our contributors and users showing how to use it.

  • Install dbachecks.

  • Run a check to validate whether your MaxMemory setting is configured correctly.

  • Explore all configurations and existing checks.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.10.239