function Test-TenantConfiguration { <# .SYNOPSIS This function tests the configuration in the tenant table of a master database .DESCRIPTION This function confirms that the configuration in the tenant table is accurate, and the database can be reached using either individual field data from the table or the connectionstring value. If no connection string is supplied to the master database, will attempt to read it from the machine config. .PARAMETER MasterDatabaseConnectionString An optional SQL connection string to the master database .INPUTS Connection string to connect to the master database .OUTPUTS Array of PSObjects containing bad tenant detail, or null .EXAMPLE Test-TenantConfiguration #> [CmdletBinding()] [OutputType([PSObject[]])] param( [Parameter(Mandatory = $false)] [string]$MasterDatabaseConnectionString = $null ) $logLead = Get-LogLeadName [array]$tenants = Get-FullTenantListFromServer -connectionString $MasterDatabaseConnectionString $badTenants = @() foreach ($tenant in $tenants) { $localError = $false $tenantName = $($tenant.Name) [string[]]$configErrors = @() $tenantConnectionStringFieldBuilder = $null $tenantComputedConnectionStringBuilder = $null Write-Host "$logLead : Validating $tenantName" try { $tenantConnectionStringFieldBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder $tenant.ConnectionString if (!(Confirm-DatabaseAccess -ConnectionString ($tenantConnectionStringFieldBuilder.ToString()) -ConnectionTimeout 2 -WarningAction SilentlyContinue)) { Write-Host "$logLead : [$tenantName] : Could not connect to the tenant using the ConnectionString Field Value" $localError = $true $configErrors+="Unable to Connect Using Connection String" } } catch { Write-Host "$logLead : [$tenantName] : Tenant ConnectionString Field Value is Invalid. Error: $($_.Exception.Message)" $localError = $true $configErrors+="Invalid Connection String" } if ($tenant.DataSource -ne $tenantConnectionStringFieldBuilder.DataSource) { Write-Host "$logLead : [$tenantName] : DataSource Field Does Not Match ConnectionString Field" $localError = $true $configErrors+="DataSource/ConnectionString Mismatch" } if ($tenant.Catalog -ne $tenantConnectionStringFieldBuilder.InitialCatalog) { Write-Host "$logLead : [$tenantName] : Catalog Field Value Does Not Match ConnectionString Field Value" $localError = $true $configErrors+="Catalog/ConnectionString Mismatch" } try { $tenantComputedConnectionStringBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder $tenantComputedConnectionStringBuilder.'Data Source' = $tenant.DataSource $tenantComputedConnectionStringBuilder.'Initial Catalog' = $tenant.Catalog $tenantComputedConnectionStringBuilder.'Integrated Security' = $true if (!(Confirm-DatabaseAccess -ConnectionString $tenantComputedConnectionStringBuilder.ToString() -ConnectionTimeout 2 -WarningAction SilentlyContinue)) { Write-Host "$logLead : [$tenantName] : Could not connect to the tenant using the DataSource Field and Catalog Field Values" $localError = $true $configErrors+="Unable to Connect Using DataSource and Catalog Values" } } catch { Write-Host "$logLead : [$tenantName] : Could Not Create a ConnectonString Using the Tenant DataSource and Catalog Field Values. Error: $($_.Exception.Message)" $localError = $true $configErrors+="Invalid DataSource or Catalog Values" } if ($localError) { $badTenants += New-Object PsObject -Property @{ Name = $tenant.Name DataSource = $tenant.DataSource Catalog = $tenant.Catalog ConnectionString = $tenant.ConnectionString Errors = $configErrors } } else { Write-Host "$logLead : $tenantName Tenant Configuration Validated Successfully" } } if ($badTenants.Count -gt 0) { Write-Warning "$logLead : $($badTenants.Count) Tenants have invalid configuration. Review and correct configuration errors" } return ($badTenants) }