diff --git a/source/checks/Databasev5.Tests.ps1 b/source/checks/Databasev5.Tests.ps1 index 194d0e9e..37b002a5 100644 --- a/source/checks/Databasev5.Tests.ps1 +++ b/source/checks/Databasev5.Tests.ps1 @@ -58,6 +58,7 @@ Describe "Suspect Page" -Tag SuspectPage, High , Database -ForEach $InstancesToT } Describe "Database Collation" -Tag DatabaseCollation, High, Database -ForEach $InstancesToTest { + #TODO: Should we have a skip option for each IT block? $skip = ($__dbcconfig | Where-Object { $_.Name -eq 'skip.database.databasecollation' }).Value Context "Testing database collation on <_.Name>" { It "Database <_.Name> collation <_.Collation> should match server collation <_.ServerCollation> on <_.SqlInstance>" -Skip:$skip -ForEach $psitem.Databases.Where{ if ($Database) { $_.Name -in $Database } else { $psitem.ConfigValues.wrongcollation -notcontains $PsItem.Name } } { @@ -65,10 +66,9 @@ Describe "Database Collation" -Tag DatabaseCollation, High, Database -ForEach $I } # wrong collation set - It "Database <_.Name> collation <_.Collation> should not match server collation <_.ServerCollation> on <_.SqlInstance>" -ForEach $psitem.Databases.Where{ $_.Name -in $psitem.ConfigValues.wrongcollation } { + It "Database <_.Name> collation <_.Collation> should not match server collation <_.ServerCollation> on <_.SqlInstance>" -Skip:$skip -ForEach $psitem.Databases.Where{ $_.Name -in $psitem.ConfigValues.wrongcollation } { $psitem.ServerCollation | Should -Not -Be $psitem.Collation -Because "You have defined the database to have another collation then the server. You will get collation conflict errors in tempdb" } - } } @@ -252,3 +252,25 @@ Describe "PseudoSimple Recovery Model" -Tag PseudoSimple, Medium, Database -ForE } } } + +Describe "Contained Database Auto Close" -Tag ContainedDBAutoClose, CIS, Database -ForEach $InstancesToTest { + $Skip = ($__dbcconfig | Where-Object Name -EQ 'skip.security.containedbautoclose').Value + + Context "Testing contained database auto close option" { + It "Database <_.Name> should have auto close set to false on <_.SqlInstance>" -Skip:$skip -ForEach $psitem.Databases.Where{ if ($Database) { $_.Name -in $Database -and $_.ContainmentType -ne "NONE" } else { $psitem.ConfigValues.contdbautocloseexclude -notcontains $psitem.Name -and $_.ContainmentType -ne "NONE" } } { + $psitem.ContainedDbAutoClose | Should -BeFalse -Because "Contained Databases should have auto close set to false for CIS compliance." + } + } +} + +Describe "Contained Database SQL Authenticated Users" -Tag ContainedDBSQLAuth, CIS, Database -ForEach $InstancesToTest { + $Skip = ($__dbcconfig | Where-Object Name -EQ 'skip.security.ContainedDBSQLAuth').Value + + #if ($version -lt 13 ) { $skip = $true } + + Context "Testing contained database to see if sql authenticated users exist" { + It "Database <_.Name> should have no sql authenticated users on <_.SqlInstance>" -Skip:$skip -ForEach $psitem.Databases.Where{ if ($Database) { $_.Name -in $Database -and $_.ContainmentType -ne "NONE" } else { $psitem.ConfigValues.contdbsqlauthexclude -notcontains $psitem.Name -and $_.ContainmentType -ne "NONE" } } { + $psitem.ContainedDbSqlAuthUsers | Should -Be 0 -Because "We expect there to be no sql authenticated users in contained database." + } + } +} diff --git a/source/internal/configurations/configuration.ps1 b/source/internal/configurations/configuration.ps1 index 984a9ff1..ce1f3c11 100644 --- a/source/internal/configurations/configuration.ps1 +++ b/source/internal/configurations/configuration.ps1 @@ -171,6 +171,8 @@ Set-PSFConfig -Module dbachecks -Name policy.database.trustworthyexcludedb -Valu Set-PSFConfig -Module dbachecks -Name policy.database.duplicateindexexcludedb -Value @('msdb', 'ReportServer', 'ReportServerTempDB') -Initialize -Description "A List of databases we do not want to check for Duplicate Indexes" Set-PSFConfig -Module dbachecks -Name policy.database.clrassembliessafeexcludedb -Value @() -Initialize -Description " A List of database what we do not want to check for SAFE CLR Assemblies" Set-PSFConfig -Module dbachecks -Name policy.database.pseudosimpleexcludedb -Value @('tempdb', 'model') -Initialize -Description "A List of databases that we do not want to check for pseudosimple recovery modelasd a" +Set-PSFConfig -Module dbachecks -Name policy.database.contdbautocloseexclude -Value @('msdb') -Initialize -Description "A List of contained database that we we do not want to check for autoclose" +Set-PSFConfig -Module dbachecks -Name policy.database.contdbsqlauthexclude -Value @() -Initialize -Description "A list of databases that we do not want to check for contained databases with SQL authenticated users" Set-PSFConfig -Module dbachecks -Name policy.database.logfilepercentused -Value 75 -Initialize -Description " The % log used we should stay below" # Policy for Ola Hallengren Maintenance Solution diff --git a/source/internal/functions/Get-AllDatabaseInfo.ps1 b/source/internal/functions/Get-AllDatabaseInfo.ps1 index 91fcffeb..7ef885b4 100644 --- a/source/internal/functions/Get-AllDatabaseInfo.ps1 +++ b/source/internal/functions/Get-AllDatabaseInfo.ps1 @@ -148,6 +148,14 @@ function Get-AllDatabaseInfo { $pseudoSimple = $true $ConfigValues | Add-Member -MemberType NoteProperty -Name 'pseudosimpleexclude' -Value ($__dbcconfig | Where-Object Name -EQ 'policy.database.pseudosimpleexcludedb').Value } + 'ContainedDBAutoClose' { + $containedDbAutoClose = $true + $ConfigValues | Add-Member -MemberType NoteProperty -Name 'contdbautocloseexclude' -Value ($__dbcconfig | Where-Object Name -EQ 'policy.database.contdbautocloseexclude').Value + } + 'ContainedDBSQLAuth'{ + $containedDbSqlAuthUsers = $true + $ConfigValues | Add-Member -MemberType NoteProperty -Name 'contdbsqlauthexclude' -Value ($__dbcconfig | Where-Object Name -EQ 'policy.database.contdbsqlauthexclude').Value + } Default { } } @@ -156,7 +164,7 @@ function Get-AllDatabaseInfo { ComputerName = $Instance.ComputerName InstanceName = $Instance.DbaInstanceName Name = $Instance.Name - ConfigValues = $ConfigValues # can we move this out to here? + ConfigValues = $ConfigValues Databases = $Instance.Databases.Foreach{ [PSCustomObject]@{ Name = $psitem.Name @@ -165,10 +173,9 @@ function Get-AllDatabaseInfo { ServerCollation = @(if ($collation) { $Instance.collation }) Collation = @(if ($collation) { $psitem.collation }) SuspectPage = @(if ($suspectPage) { (Get-DbaSuspectPage -SqlInstance $Instance -Database $psitem.Name | Measure-Object).Count }) - ConfigValues = $ConfigValues # can we move this out? + ConfigValues = $ConfigValues AsymmetricKeySize = @(if ($asymmetrickey) { ($psitem.AsymmetricKeys | Where-Object { $_.KeyLength -lt 2048 } | Measure-Object).Count }) - #AsymmetricKeySize = if ($asymmetrickey) { $psitem.AsymmetricKeys.KeyLength } # doing this I got $null if there wasn't a key so counting ones that are too short - AutoClose = @(if ($autoclose) { $psitem.AutoClose }) + AutoClose = @(if ($autoclose -or $containedDbAutoClose) { $psitem.AutoClose }) AutoCreateStatistics = @(if ($autocreatestats) { $psitem.AutoCreateStatisticsEnabled }) AutoUpdateStatistics = @(if ($autoupdatestats) { $psitem.AutoUpdateStatisticsEnabled }) AutoUpdateStatisticsAsync = @(if ($autoupdatestatsasync) { $psitem.AutoUpdateStatisticsAsync }) @@ -185,7 +192,9 @@ function Get-AllDatabaseInfo { GuestUserConnect = @(if ($guestUserConnect) { if ($psitem.EnumDatabasePermissions('guest') | Where-Object { $_.PermissionState -eq 'Grant' -and $_.PermissionType.Connect }) { $true } } ) RecoveryModel = @(if ($pseudoSimple -or $recoverymodel) { $psitem.RecoveryModel }) PseudoSimple = @(if ($pseudoSimple) { '' -eq (($psitem.Query('Select last_log_backup_lsn from sys.database_recovery_status where database_id = DB_ID()')).last_log_backup_lsn) }) - # might need to change this to look at last_log_backup_lsn column of the sys.database_recovery_status or DBCC DBINFO () WITH TABLERESULTS").Tables[0] | Where-Object {$_.Field -eq "dbi_dbbackupLSN"} + ContainmentType = @(if ($containedDbAutoClose -or $containedDbSqlAuthUsers) { $psitem.ContainmentType }) + ContainedDbAutoClose = @(if ($containedDbAutoClose) { if (($psItem.ContainmentType -ne "NONE") -and ($null -ne $psItem.ContainmentType) -and $psitem.AutoClose) { $true } else { $false } } ) + ContainedDbSqlAuthUsers = @(if ($containedDbSqlAuthUsers) { if ($psItem.ContainmentType -ne "NONE" -and ($null -ne $psItem.ContainmentType)) { ($psitem.Users | Where-Object {$_.LoginType -eq "SqlLogin" -and $_.HasDbAccess -eq $true } | Measure-Object ).Count}} ) } } }