internal/functions/NewGet-AllInstanceInfo.ps1

function NewGet-AllInstanceInfo {
    # Using the unique tags gather the information required
    Param($Instance, $Tags)

    #clear out the default initialised fields
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Server], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Database], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Login], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Agent.Job], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.StoredProcedure], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Information], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Settings], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.LogFile], $false)
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.DataFile], $false)

    # set the default init fields for all the tags

    # Server Initial fields
    $ServerInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Server])
    $ServerInitFields.Add("VersionMajor") | Out-Null # so we can check versions
    $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Server], $ServerInitFields)

    # Database Initial Fields
    $DatabaseInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Database])

    # Stored Procedure Initial Fields
    $StoredProcedureInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.StoredProcedure])

    # Information Initial Fields

    # Settings Initial Fields
    $SettingsInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Settings])

    # Login Initial Fields
    $LoginInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Login])

    # Log File Initial Fields
    $LogFileInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.LogFile])

    # Data File Initial Fields
    $DataFileInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.DataFile])

    # Configuration cannot have default init fields :-)
    $configurations = $false

    # Set up blank ConfigValues object for any config we need to use in the checks
    $ConfigValues = [PSCustomObject]@{}

    # Using there so that if the instance is not contactable, no point carrying on with gathering more information
    switch ($tags) {

        'DefaultTrace' {
            $configurations = $true
        }
        'OleAutomationProceduresDisabled' {
            $configurations = $true
        }
        'CrossDBOwnershipChaining' {
            $configurations = $true
        }
        'ScanForStartupProceduresDisabled' {
            # we have to check the spconfigure and we have to check that any stored procedurees in master have startup set to true
            $configurations = $true
            $ScanForStartupProceduresDisabled = $true
            $StoredProcedureInitFields.Add("Startup") | Out-Null # So we can check SPs start up for the CIS checks
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.StoredProcedure], $StoredProcedureInitFields)
            $StoredProcedureInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.StoredProcedure]) # I think we need to re-initialise here
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'scanforstartupproceduresdisabled' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.security.scanforstartupproceduresdisabled' }).Value)
        }
        'RemoteAccessDisabled' {
            $configurations = $true
        }
        'SQLMailXPsDisabled' {
            $configurations = $true
        }
        'DAC' {
            $configurations = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'dacallowed' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.dacallowed' }).Value)
        }
        'OLEAutomation' {
            $configurations = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'OLEAutomation' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.oleautomation' }).Value)
        }
        'AdHocWorkload' {
            $configurations = $true
        }
        'AdHocDistributedQueriesEnabled' {
            $configurations = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'AdHocDistributedQueriesEnabled' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.security.AdHocDistributedQueriesEnabled' }).Value)
        }
        'DefaultBackupCompression' {
            $configurations = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'DefaultBackupCompression' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.backup.defaultbackupcompression' }).Value)
        }
        'DefaultFilePath' {
            $SettingsInitFields.Add("DefaultFile") | Out-Null # so we can check file paths
            $SettingsInitFields.Add("DefaultLog") | Out-Null # so we can check file paths
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Settings], $SettingsInitFields)
        }
        'SaRenamed' {
        }
        'SaDisabled' {
            $LoginInitFields.Add("IsDisabled") | Out-Null # so we can check if sa is disabled
            $LoginInitFields.Add("ID") | Out-Null # so we can check if sa is disabled even if it has been renamed
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Settings], $LoginInitFields)
        }
        'ModelDbGrowth' {
            $LogFileInitFields.Add("Growth") | Out-Null # So we can check the model file growth settings
            $LogFileInitFields.Add("GrowthType") | Out-Null # So we can check the model file growth settings
            $LogFileInitFields.Add("Name") | Out-Null # So we can check the model file growth settings
            $DataFileInitFields.Add("Growth") | Out-Null # So we can check the model file growth settings
            $DataFileInitFields.Add("GrowthType") | Out-Null # So we can check the model file growth settings
            $DataFileInitFields.Add("Name") | Out-Null # So we can check the model file growth settings
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.LogFile], $LogFileInitFields)
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.DataFile], $DataFileInitFields)
            $LogFileInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.LogFile]) # I think we need to re-initialise here
            $DataFileInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.DataFile]) # I think we need to re-initialise here

        }
        'ErrorlogCount' {

            $ServerInitFields.Add("NumberOfLogFiles") | Out-Null # so we can check versions
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Server], $ServerInitFields)
            $ServerInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Server]) # I think we need to re-initialise here

            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'errorLogCount' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.errorlog.logcount' }).Value)

        }
        'MaxDopInstance' {
            #Test-DbaMaxDop needs these because it checks every database as well
            $DatabaseInitFields.Add("IsAccessible") | Out-Null # so we can check if its accessible
            $DatabaseInitFields.Add("IsSystemObject ") | Out-Null # so we can check if its accessible
            $DatabaseInitFields.Add("MaxDop ") | Out-Null # so we can check if its accessible
            $DatabaseInitFields.Add("Name ") | Out-Null # so we can check if its accessible
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Database], $DatabaseInitFields)
            $DatabaseInitFields = $Instance.GetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Database]) # I think we need to re-initialise here

            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'UseRecommendedMaxDop' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.instancemaxdop.userecommended' }).Value)
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'InstanceMaxDop' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.instancemaxdop.maxdop' }).Value)
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'ExcludeInstanceMaxDop' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.instancemaxdop.excludeinstance' }).Value)
            if ($Instance.Name -notin $ConfigValues.ExcludeInstanceMaxDop) {
                $MaxDopSettings = (Test-DbaMaxDop -SqlInstance $Instance)[0] # because we dont care about the database maxdops here - potentially we could store it and use it for DatabaseMaxDop ?
            }
        }
        'TwoDigitYearCutoff' {
            $configurations = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'TwoDigitYearCutoff' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.twodigityearcutoff' }).Value)

        }
        'TraceFlagsExpected' {
            $TraceFlagsExpected = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.traceflags.expected' }).Value
            $TraceFlagsActual = $Instance.EnumActiveGlobalTraceFlags()
            if (-not $ConfigValues.TraceFlagsExpected) {
                $ConfigValues | Add-Member -MemberType NoteProperty -Name 'TraceFlagsExpected' -Value $TraceFlagsExpected -Force
            }
            $ExpectedTraceFlags = $TraceFlagsExpected.Foreach{
                [PSCustomObject]@{
                    InstanceName      = $Instance.Name
                    ExpectedTraceFlag = $PSItem
                    ActualTraceFlags  = $TraceFlagsActual
                }
            }
            $ExpectedTraceFlags += [PSCustomObject]@{
                InstanceName      = $Instance.Name
                ExpectedTraceFlag = 'null'
                ActualTraceFlags  = $TraceFlagsActual
            }
        }
        'TraceFlagsNotExpected' {
            $TraceFlagsNotExpected = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.traceflags.notexpected' }).Value
            $TraceFlagsExpected = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.traceflags.expected' }).Value
            if ($null -eq $TraceFlagsExpected) { $TraceFlagsExpected = 'none expected' }
            $TraceFlagsActual = $Instance.EnumActiveGlobalTraceFlags()
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'TraceFlagsNotExpected' -Value $TraceFlagsNotExpected
            if (-not $ConfigValues.TraceFlagsExpected) {
                $ConfigValues | Add-Member -MemberType NoteProperty -Name 'TraceFlagsExpected' -Value $TraceFlagsExpected -Force
            }
            $NotExpectedTraceFlags = $TraceFlagsNotExpected.Where{ $_ -notin $TraceFlagsExpected }.Foreach{
                [PSCustomObject]@{
                    InstanceName         = $Instance.Name
                    NotExpectedTraceFlag = $PSItem
                    TraceFlagsExpected   = $TraceFlagsExpected
                    ActualTraceFlags     = $TraceFlagsActual
                }
            }
            $NotExpectedTraceFlags += [PSCustomObject]@{
                InstanceName         = $Instance.Name
                TraceFlagsExpected   = $TraceFlagsExpected
                NotExpectedTraceFlag = 'null'
                ActualTraceFlags     = $TraceFlagsActual
            }
        }
        'CLREnabled' {
            $configurations = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'CLREnabled' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.security.clrenabled' }).Value)
        }
        'WhoIsActiveInstalled' {
            $configurations = $true
            $WhoIsActiveInstalled = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'whoisactivedatabase' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.whoisactive.database' }).Value)
        }
        'XpCmdShellDisabled' {
            $configurations = $true
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'XpCmdShellDisabled' -Value (($__dbcconfig | Where-Object { $_.Name -eq 'policy.security.XpCmdShellDisabled' }).Value)

        }
        'XESessionStopped' {
            if (-not $xeSessions) {
                $xeSessions = Get-DbaXESession -SqlInstance $Instance
            }
            $RequiredStopped = (($__dbcconfig | Where-Object { $_.Name -eq 'policy.xevent.requiredstoppedsession' }).Value)
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'requiredstoppedsession' -Value $RequiredStopped
            if (-not $xeSessions) {
                $RunningSessions = $xeSessions.Where{ $_.Status -eq 'Running' }.Name
            }
            if (-not $Sessions) {
                $Sessions = $xeSessions.Name
            }
        }
        'XESessionExists' {
            if (-not $xeSessions) {
                $xeSessions = Get-DbaXESession -SqlInstance $Instance
            }
            $RequiredExists = (($__dbcconfig | Where-Object { $_.Name -eq 'policy.xevent.requiredexists' }).Value)
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'requiredexistssessions' -Value $RequiredExists
            if (-not $RunningSessions) {
                $RunningSessions = $xeSessions.Where{ $_.Status -eq 'Running' }.Name
            }
            if (-not $Sessions) {
                $Sessions = $xeSessions.Name
            }
        }
        'XESessionRunning' {
            if (-not $xeSessions) {
                $xeSessions = Get-DbaXESession -SqlInstance $Instance
            }
            $RequiredRunning = (($__dbcconfig | Where-Object { $_.Name -eq 'policy.xevent.requiredrunningsession' }).Value)
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'requiredrunningsession' -Value $RequiredRunning
            if (-not $RunningSessions) {
                $RunningSessions = $xeSessions.Where{ $_.Status -eq 'Running' }.Name
            }
            if (-not $Sessions) {
                $Sessions = $xeSessions.Name
            }
        }
        'XESessionRunningAllowed' {
            if (-not $xeSessions) {
                $xeSessions = Get-DbaXESession -SqlInstance $Instance
            }
            $RunningAllowed = (($__dbcconfig | Where-Object { $_.Name -eq 'policy.xevent.validrunningsession' }).Value)
            $ConfigValues | Add-Member -MemberType NoteProperty -Name 'validrunningsession' -Value $RunningAllowed
            if (-not $RunningSessions) {
                $RunningSessions = $xeSessions.Where{ $_.Status -eq 'Running' }.Name
            }
            if (-not $Sessions) {
                $Sessions = $xeSessions.Name
            }
        }
        'ErrorLog' {
            $logWindow = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.errorlog.warningwindow' }).Value
            # so that it can be mocked
            function Get-ErrorLogEntry {
                # get the number of the first error log that was created after the log window config
                $OldestErrorLogNumber = ($InstanceSMO.EnumErrorLogs() | Where-Object { $psitem.CreateDate -gt (Get-Date).AddDays( - $LogWindow) } | Sort-Object ArchiveNo -Descending | Select-Object -First 1).ArchiveNo + 1
                # Get the Error Log entries for each one
                    (0..$OldestErrorLogNumber).ForEach{
                    $InstanceSMO.ReadErrorLog($psitem).Where{ $_.Text -match "Severity: 1[7-9]|Severity: 2[0-4]" }
                }
            }
            # It is not enough to check the CreateDate on the log, you must check the LogDate on every error record as well.
            $ErrorLogCount = (Get-ErrorLogEntry | Where-Object { $psitem.LogDate -gt (Get-Date).AddDays( - $LogWindow) }).Count
        }
        'TempDbConfiguration' {
            $TempDBTest = Test-DbaTempDbConfig -SqlInstance $Instance
        }
        'InstanceConnection' {
            #local is always NTLM except when its a container ;-)
            if ($Instance.ComputerNamePhysicalNetBIOS -eq $ENV:COMPUTERNAME -and ($instance.Name -notlike '*,*')) {
                $authscheme = 'skipped-local'
            } else {
                if (-not(($__dbcconfig | Where-Object { $_.Name -eq 'skip.connection.auth' }).Value)) {
                    $authscheme = $instance.Query("Select auth_scheme as AuthScheme FROM sys.dm_exec_connections WHERE session_id = @@SPID").AuthScheme
                } else {
                    $authscheme = 'skipped'
                }
            }
            if ($IsWindows) {
                if (-not(($__dbcconfig | Where-Object { $_.Name -eq 'skip.connection.ping' }).Value)) {
                    $pingu = New-Object System.Net.NetworkInformation.Ping
                    $timeout = 1000 #milliseconds
                    $ping = ($pingu.Send($instance.ComputerName, $timeout)).Status
                } else {
                    $ping = 'skipped'
                }
            } else {
                $ping = 'skipped'
            }


            if (-not(($__dbcconfig | Where-Object { $_.Name -eq 'skip.connection.remote' }).Value)) {
                #simple remoting check
                try {
                    $null = Invoke-Command -ComputerName $instance.ComputerName -ScriptBlock { Get-ChildItem } -ErrorAction Stop
                    $remote = $true
                } catch {
                    $remote = $false
                }
            } else {
                $remote = 'skipped'
            }

            $InstanceConnection = @{
                Connect    = $true # because we wouldnt get here otherwise
                AuthScheme = $authscheme
                Ping       = $ping
                Remote     = $remote
            }
        }
        'BackUpPathAccess' {
            # get value from config or from default setting
            $BackupPath = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.storage.backuppath' }).Value
            if (-not $BackupPath) {
                $BackupPath = $Instance.BackupDirectory
            }
            $BackupPathAccess = Test-DbaPath -SqlInstance $Instance -Path $BackupPath
        }
        'LatestBuild' {
            $LatestBuild = Test-DbaBuild -SqlInstance $Instance -Latest
        }
        'NetworkLatency' {
            $NetworkThreshold = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.network.latencymaxms' }).Value
            $Latency = (Test-DbaNetworkLatency -SqlInstance $Instance).NetworkOnlyTotal.TotalMilliseconds
        }

        'LinkedServerConnection' {
            $LinkedServerResults = Test-DbaLinkedServerConnection -SqlInstance $Instance
        }

        'MaxMemory' {
            if ($isLinux -or $isMacOS) {
                $totalMemory = $Instance.PhysicalMemory
                # Some servers under-report by 1.
                if (($totalMemory % 1024) -ne 0) {
                    $totalMemory = $totalMemory + 1
                }
                $MaxMemory = [PSCustomObject]@{
                    MaxValue         = $Instance.Configuration.MaxServerMemory.ConfigValue + 379
                    RecommendedValue = $totalMemory
                    # because we added 379 before and I have zero idea why
                }
            } else {
                $MemoryValues = Test-DbaMaxMemory -SqlInstance $Instance
                $MaxMemory = [PSCustomObject]@{
                    MaxValue         = $MemoryValues.MaxValue
                    RecommendedValue = $MemoryValues.RecommendedValue
                }
            }
        }

        'OrphanedFile' {
            $FileCount = @(Find-DbaOrphanedFile -SqlInstance $Instance).Count
        }

        'ServerNameMatch' {
            $ServerNameMatchconfiguredServerName = $Instance.Query("SELECT @@servername AS ServerName").ServerName
            $ServerNameMatchnetName = $Instance.NetName
            $ServerNameMatchrenamerequired = $ServerNameMatchnetName -ne $ServerNameMatchconfiguredServerName
        }

        'MemoryDump' {
            $maxdumps = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.dump.maxcount' }).Value
            $daystocheck = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.instance.memorydumpsdaystocheck' }).Value
            if ($null -eq $daystocheck) {
                $datetocheckfrom = '0001-01-01'
            } else {
                $datetocheckfrom = (Get-Date).ToUniversalTime().AddDays( - $daystocheck )
            }
            if (($InstanceSMO.Version.Major -lt 11 -and (-not ($InstanceSMO.Version.Major -eq 10 -and $InstanceSMO.Version.Minor -eq 50)))) {
                $MemoryDumpCount = 0
            } else {
                # Warning Action removes dbatools output for version too low from test results
                # Skip on the it will show in the results
                $MemoryDumpCount = (@(Get-DbaDump -SqlInstance $Instance -WarningAction SilentlyContinue).Where{ $_.CreationTime -gt $datetocheckfrom }).Count
            }

            $Dump = [pscustomobject] @{
                DumpCount         = $MemoryDumpCount
                MaxDumps          = $maxdumps
                DumpDateCheckFrom = $datetocheckfrom
                Result            = $MemoryDumpCount -le $maxdumps
            }
        }

        'HideInstance' {
            try {
                $HideInstance = [pscustomobject] @{
                    Result = (Get-DbaHideInstance -SqlInstance $InstanceSMO).HideInstance
                }
            } catch {
                $HideInstance = [pscustomobject] @{
                    Result = 'We Could not Connect to $Instance'
                }
            }
        }

        'LoginAuditFailed' {
            $SettingsInitFields.Add("AuditLevel") | Out-Null # so we can check auditlevel
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Settings], $SettingsInitFields)
        }

        'LoginAuditSuccessful' {
            $SettingsInitFields.Add("AuditLevel") | Out-Null # so we can check auditlevel
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Settings], $SettingsInitFields)
        }

        'LoginCheckPolicy' {
            $LoginInitFields.Add("IsDisabled") | Out-Null # so we can check login check policy
            $LoginInitFields.Add("PasswordPolicyEnforced") | Out-Null # so we can check login check policy
            $Instance.SetDefaultInitFields([Microsoft.SqlServer.Management.Smo.Settings], $LoginInitFields)
        }

        { 'PublicRolePermissions' -or 'PublicPermission' } {
            #This needs to be done in query just in case the account had already been renamed
            $query = "
                     SELECT Count(*) AS [RowCount]
                     FROM master.sys.server_permissions
                     WHERE (grantee_principal_id = SUSER_SID(N'public') and state_desc LIKE 'GRANT%')
                             AND NOT (state_desc = 'GRANT' and [permission_name] = 'VIEW ANY DATABASE' and class_desc = 'SERVER')
                             AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and class_desc = 'ENDPOINT' and major_id = 2)
                             AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and class_desc = 'ENDPOINT' and major_id = 3)
                             AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and class_desc = 'ENDPOINT' and major_id = 4)
                             AND NOT (state_desc = 'GRANT' and [permission_name] = 'CONNECT' and class_desc = 'ENDPOINT' and major_id = 5);
                        "

            $PublicRolePermsCount = $Instance.Query($query).RowCount
        }

        'SuspectPageLimit' {
            $sql = "Select
            COUNT(file_id) as 'SuspectPageCount'
            from msdb.dbo.suspect_pages"

            $SuspectPageCountResult = (($Instance.Query($sql).SuspectPageCount / 1000) * 100 ) -lt ($__dbcconfig | Where-Object { $_.Name -eq 'policy.suspectpage.threshold' }).Value
        }

        'SupportedBuild' {
            $BuildWarning = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.build.warningwindow' }).Value
            $BuildBehind = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.build.behind' }).Value
            $Date = Get-Date
            #If $BuildBehind check against SP/CU parameter to determine validity of the build
            if ($BuildBehind) {
                $buildBehindResults = Test-DbaBuild -SqlInstance $Instance -SqlCredential $sqlcredential -MaxBehind $BuildBehind
                $Compliant = $buildBehindResults.Compliant

                #If no $BuildBehind only check against support dates
            } else {
                $Compliant = $true
            }

            $Results = Test-DbaBuild -SqlInstance $Instance -SqlCredential $sqlcredential -Latest
            [DateTime]$SupportedUntil = Get-Date $results.SupportedUntil -Format O
            $Build = $results.build
            #If $BuildWarning, check for support date within the warning window
            if ($BuildWarning) {
                [DateTime]$expected = Get-Date ($Date).AddMonths($BuildWarning) -Format O
                $SupportedUntil | Should -BeGreaterThan $expected -Because "this build $Build will be unsupported by Microsoft on $(Get-Date $SupportedUntil -Format O) which is less than $BuildWarning months away"
            } else {
                #If neither, check for Microsoft support date
                $SupportedUntil | Should -BeGreaterThan $Date -Because "this build $Build is now unsupported by Microsoft"
            }

            $SupportedBuild = [pscustomobject]@{
                BuildBehind            = $BuildBehind
                Compliant              = $Compliant
                Build                  = $Build
                SupportedUntil         = $SupportedUntil
                Expected               = $expected
                BuildWarning           = $BuildWarning
                InsideBuildWarning     = $SupportedUntil -gt $expected
                InsideMicrosoftSupport = $SupportedUntil -gt $Date
            }
        }

        'LoginMustChange' {
            $loginTimeSql = "SELECT login_name, MAX(login_time) AS login_time FROM sys.dm_exec_sessions GROUP BY login_name"
            $loginTimes = $instance.ConnectionContext.ExecuteWithResults($loginTimeSql).Tables[0]
            $lastlogin = @{Name = 'LastLogin' ; Expression = { $Name = $_.name; ($loginTimes | Where-Object { $_.login_name -eq $name }).login_time
                }
            }
            $LoginMustChangeCount = ($Instance.Logins | Where-Object { $_.LoginType -eq 'SqlLogin' } | Where-Object { $_.Name -in $Instance.Roles['sysadmin'].EnumMemberNames() } | Select-Object Name, $lastlogin, MustChangePassword, IsDisabled | Where-Object { $_.MustChangePassword -eq $false -and $_.IsDisabled -eq $false -and $null -eq $_.LastLogin }).Count
        }

        'LoginPasswordExpiration' {
            $LoginPasswordExpirationCount = ($Instance.Logins | Where-Object { $_.Name -in $Instance.Roles['sysadmin'].EnumMemberNames() } | Where-Object { $_.LoginType -eq 'SqlLogin' -and $_.PasswordExpirationEnabled -EQ $false -and $_.IsDisabled -EQ $false }).Count
        }

        'AgentServiceAdmin' {
            try {
                $SqlAgentService = Get-DbaService -ComputerName $Instance.ComputerName -InstanceName $Instance.DbaInstanceName -Type Agent -ErrorAction SilentlyContinue
                $LocalAdmins = Invoke-Command -ComputerName $ComputerName -ScriptBlock { Get-LocalGroupMember -Group "Administrators" } -ErrorAction SilentlyContinue
                $AgentServiceAdminExist = $localAdmins.Name.Contains($SqlAgentService.StartName)

            } catch [System.Exception] {
                if ($_.Exception.Message -like '*No services found in relevant namespaces*') {
                    $AgentServiceAdminExist = $false
                } else {
                    $AgentServiceAdminExist = 'Some sort of failure'
                }
            } catch {
                $AgentServiceAdminExist = 'We Could not Connect to $Instance $ComputerName , $InstanceName from catch'
            }
        }

        'SqlEngineServiceAccount' {
            $starttype = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.instance.sqlenginestart' }).Value
            $state = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.instance.sqlenginestate' }).Value
            try {
                $EngineAccounts = Get-DbaService -ComputerName $psitem -Type Engine -ErrorAction Stop

            } catch [System.Exception] {
                if ($_.Exception.Message -like '*No services found in relevant namespaces*') {
                    $EngineAccounts = [PSCustomObject]@{
                        InstanceName      = $Instance.Name
                        State             = 'unknown'
                        ExpectedState     = $state
                        StartType         = 'unknown'
                        ExpectedStartType = $starttype
                        because           = 'Some sort of failure - No services found in relevant namespaces'
                    }
                } else {
                    $EngineAccounts = [PSCustomObject]@{
                        InstanceName      = $Instance.Name
                        State             = 'unknown'
                        ExpectedState     = $state
                        StartType         = 'unknown'
                        ExpectedStartType = $starttype
                        because           = 'Some sort of failure'
                    }
                }
            } catch {
                $EngineAccounts = [PSCustomObject]@{
                    InstanceName      = $Instance.Name
                    State             = 'unknown'
                    ExpectedState     = $state
                    StartType         = 'unknown'
                    ExpectedStartType = $starttype
                    because           = 'We Could not Connect to $Instance $ComputerName , $InstanceName from catch'
                }
            }

            if ($Instance.IsClustered) {
                $starttype = 'Manual'
                $because = 'This is a clustered instance and Clustered Instances required that the SQL engine service is set to manual'
            } else {
                $because = "The SQL Service Start Type was expected to be $starttype"
            }

            $SqlEngineServiceAccount = foreach ($EngineAccount in $EngineAccounts) {
                [PSCustomObject]@{
                    InstanceName      = $Instance.Name
                    State             = $EngineAccount.State
                    ExpectedState     = $state
                    StartType         = $EngineAccount.StartType
                    ExpectedStartType = $starttype
                    because           = $because
                }
            }
        }

        Default { }
    }

    #build the object

    $testInstanceObject = [PSCustomObject]@{
        ComputerName                 = $Instance.ComputerName
        InstanceName                 = $Instance.DbaInstanceName
        Name                         = $Instance.Name
        ConfigValues                 = $ConfigValues
        VersionMajor                 = $Instance.VersionMajor
        Configuration                = if ($configurations) { $Instance.Configuration } else { $null }
        Settings                     = $Instance.Settings
        Logins                       = $Instance.Logins
        Databases                    = $Instance.Databases
        NumberOfLogFiles             = $Instance.NumberOfLogFiles
        MaxDopSettings               = $MaxDopSettings
        ExpectedTraceFlags           = $ExpectedTraceFlags
        NotExpectedTraceFlags        = $NotExpectedTraceFlags
        XESessions                   = [pscustomobject]@{
            RequiredStopped = $RequiredStopped.ForEach{
                [pscustomobject]@{
                    Name        = $Instance.Name
                    SessionName = $PSItem
                    Running     = $RunningSessions
                }
            }
            RequiredExists  = $RequiredExists.ForEach{
                [pscustomobject]@{
                    Name        = $Instance.Name
                    SessionName = $PSItem
                    Sessions    = $Sessions
                }
            }
            RequiredRunning = $RequiredRunning.ForEach{
                [pscustomobject]@{
                    Name        = $Instance.Name
                    SessionName = $PSItem
                    Sessions    = $Sessions
                    Running     = $RunningSessions
                }
            }
            RunningAllowed  = $RunningSessions.ForEach{
                [pscustomobject]@{
                    Name        = $Instance.Name
                    SessionName = $PSItem
                    Sessions    = $Sessions
                    Allowed     = $RunningAllowed
                }
            }
            Name            = $Instance.Name
            Sessions        = $Sessions
            Running         = $RunningSessions
        }
        ErrorLogEntries              = [pscustomobject]@{
            errorLogCount = $ErrorLogCount
            logWindow     = $logWindow
        }
        InstanceConnection           = $InstanceConnection
        BackupPathAccess             = [pscustomobject]@{
            Result     = $BackupPathAccess
            BackupPath = $BackupPath
        }
        LatestBuild                  = [PSCustomObject]@{
            Compliant = $LatestBuild.Compliant
        }
        NetworkLatency               = [PSCustomObject]@{
            Latency   = $Latency
            Threshold = $NetworkThreshold
        }
        LinkedServerResults          = if ($LinkedServerResults) {
            $LinkedServerResults.ForEach{
                [pscustomobject]@{
                    InstanceName     = $Instance.Name
                    LinkedServerName = $PSItem.LinkedServerName
                    RemoteServer     = $PSItem.RemoteServer
                    Connectivity     = $PSItem.Connectivity
                    Result           = $PSItem.Result
                }
            }
        } else {
            [pscustomobject]@{
                InstanceName     = $Instance.Name
                LinkedServerName = 'None found'
                RemoteServer     = 'None'
                Connectivity     = $true
                Result           = 'None'
            }
        }
        MaxMemory                    = $MaxMemory
        OrphanedFile                 = [pscustomobject]@{
            FileCount = $FileCount
        }
        ServerNameMatch              = [pscustomobject]@{
            configuredServerName = $ServerNameMatchconfiguredServerName
            netName              = $ServerNameMatchnetName
            renamerequired       = $ServerNameMatchrenamerequired
        }
        MemoryDump                   = $Dump
        HideInstance                 = $HideInstance
        SuspectPageCountResult       = $SuspectPageCountResult
        SupportedBuild               = $SupportedBuild
        LoginMustChangeCount         = $LoginMustChangeCount
        LoginPasswordExpirationCount = $LoginPasswordExpirationCount
        AgentServiceAdminExist       = $AgentServiceAdminExist
        SqlEngineServiceAccount      = $SqlEngineServiceAccount
        PublicRolePermissions        = $PublicRolePermsCount
        # TempDbConfig = [PSCustomObject]@{
        # TF118EnabledCurrent = $tempDBTest[0].CurrentSetting
        # TF118EnabledRecommended = $tempDBTest[0].Recommended
        # TempDBFilesCurrent = $tempDBTest[1].CurrentSetting
        # TempDBFilesRecommended = $tempDBTest[1].Recommended
        # }
    }
    if ($ScanForStartupProceduresDisabled) {
        $StartUpSPs = $Instance.Databases['master'].StoredProcedures.Where{ $_. Name -ne 'sp_MSrepl_startup' -and $_.StartUp -eq $true }.count
        if ($StartUpSPs -eq 0) {
            $testInstanceObject.Configuration.ScanForStartupProcedures.ConfigValue = 0
        }
    }
    if ($WhoIsActiveInstalled) {
        $whoisdatabase = ($__dbcconfig | Where-Object { $_.Name -eq 'policy.whoisactive.database' }).Value
        $WhoIsActiveInstalled = $Instance.Databases[$whoisdatabase].StoredProcedures.Where{ $_.Name -eq 'sp_WhoIsActive' }.count
        $testInstanceObject.ConfigValues | Add-Member -MemberType NoteProperty -Name 'WhoIsActiveInstalled' -Value $whoIsActiveInstalled
    }
    return $testInstanceObject
}