Dbatools: [Bug] Set-DbaMaxDop -AllDatabases not working

Created on 10 Nov 2020  路  7Comments  路  Source: sqlcollaborative/dbatools

Report

Host used

  • [x] powershell.exe
  • [ ] ISE
  • [ ] VS Code
  • [ ] Other (please specify)

Errors Received

PSMessageDetails      :
Exception             : System.Exception: -Database, -AllDatabases and -ExcludeDatabase are mutually exclusive. Please choose only one.
TargetObject          :
CategoryInfo          : InvalidArgument: (:) [Write-Error], Exception
FullyQualifiedErrorId : dbatools_Set-DbaMaxDop,Stop-Function
ErrorDetails          : -Database, -AllDatabases and -ExcludeDatabase are mutually exclusive. Please choose only one.
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at Stop-Function, C:\Users\ehv\Documents\PowerShell\Modules\dbatools\1.0.130\allcommands.ps1: line 85577
                        at Set-DbaMaxDop<Process>, C:\Users\ehv\Documents\PowerShell\Modules\dbatools\1.0.130\allcommands.ps1: line 67238
                        at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {0, 1}

Steps to Reproduce

Set-DbaMaxDop -SqlInstance localhost -AllDatabases

Expected Behavior

That DatabaseMaxDop would be set for each database in the given SqlInstance

Actual Behavior

Nothing happened when executing the cmdlet beside it returning the following warning message:
"WARNING: [16:31:05][Set-DbaMaxDop] -Database, -AllDatabases and -ExcludeDatabase are mutually exclusive. Please choose only one."

Environmental information

Powershell:

PowerShell Version        : 7.1.0-rc.2
dbatools latest installed : 1.0.130
Culture of OS             : en-US

SQL Server:

Microsoft SQL Server 2019 (RTM-CU8) (KB4577194) - 15.0.4073.23 (X64) 
    Sep 23 2020 16:03:08 
    Copyright (C) 2019 Microsoft Corporation
    Developer Edition (64-bit) on Windows 10 Enterprise 10.0 <X64> (Build 20251: ) (Hypervisor)

us_english
Confirmed bugs_life

Most helpful comment

Thanks @andreasjordan for digging out the root cause :)

Indeed, without any controlling parameters, Test-Bound is using _or_ logic - "any one of these".
It has an -And switch to change that behavior (but would in case of three parameters only trigger on all three parameters).

That said, I would instead for the proposed -MaxOne and -OnlyOne switch parameters prefer to do -Min and -Max as [int] parameters for a bit of added flexibility and mostly the same effect.

if (Test-Bound -ParameterName Database, AllDatabases, ExcludeDatabase) {

would then become

if (Test-Bound -ParameterName Database, AllDatabases, ExcludeDatabase -Max 1) {

All 7 comments

The bug is here:

        if (Test-Bound -ParameterName Database, AllDatabases, ExcludeDatabase) {
            Stop-Function -Category InvalidArgument -Message "-Database, -AllDatabases and -ExcludeDatabase are mutually exclusive. Please choose only one."
            return
        }

With Test-Bound, there is no easy way to test for "mutually exclusive".

Other commands do it like this:

        $ComplianceSpec = @()
        $ComplianceSpecExclusiveParams = @('MinimumBuild', 'MaxBehind', 'Latest')
        foreach ($exclParam in $ComplianceSpecExclusiveParams) {
            if (Test-Bound -Parameter $exclParam) { $ComplianceSpec += $exclParam }
        }
        if ($ComplianceSpec.Length -gt 1) {
            Stop-Function -Category InvalidArgument -Message "-MinimumBuild, -MaxBehind and -Latest are mutually exclusive. Please choose only one. Quitting."
            return
        }

I would like to add this functionality to Test-Bound.

I would like to use this issue to discuss the new parameters for Test-Bound.

I would suggest

  • -OnlyOne or -ExactlyOne if exactly one of the provided parameters has to be bound.
  • -MaxOne or -MaximumOne if no more than one of the provided parameters are allowed to be bound.

At the moment I don't see any use case for "you can choose two out of these ten" or "you can choose one to three out of these eigth", so I would not implement that.

@FriedrichWeinmann would you be able to speak to Test-Bound and @ClaudioESSilva can you speak to the MaxDop commands? Merci 馃檱

Thanks @andreasjordan for digging out the root cause :)

Indeed, without any controlling parameters, Test-Bound is using _or_ logic - "any one of these".
It has an -And switch to change that behavior (but would in case of three parameters only trigger on all three parameters).

That said, I would instead for the proposed -MaxOne and -OnlyOne switch parameters prefer to do -Min and -Max as [int] parameters for a bit of added flexibility and mostly the same effect.

if (Test-Bound -ParameterName Database, AllDatabases, ExcludeDatabase) {

would then become

if (Test-Bound -ParameterName Database, AllDatabases, ExcludeDatabase -Max 1) {

Ok, @FriedrichWeinmann , you made me change my mind. We could then simple take the code with $ComplianceSpec and use this and test against -Min and -Max.

How about the defaults? To be a non breaking change, they should be like this:

[int]
$Min = 1,
[int]
$Max = $ParameterName.Length,

Or am I missing something?

I just coded it, please have a look.

I only found the mutually exclusive pattern referenced in two commands: Get-DbaBuildReference and Test-DbaBuild. Other commands have this and simply break the calls to Test-Bound up.

if ( (Test-Bound Database) -and (Test-Bound AllDatabases) -and (Test-Bound ExcludeDatabase) ) {
...
}

Backup and Restore command utilize the above pattern and I think is more readable to users/contributors.

Was this page helpful?
0 / 5 - 0 ratings