Skip to content

Set-FileSystemSetting - Get-FilestreamReturnValue reports every WMI return code as success #10524

Description

@andreasjordan

Summary

Get-FilestreamReturnValue, nested inside private/functions/Set-FileSystemSetting.ps1, has a switch clause whose condition is always true:

{ 2147021885 -or 2147945411 -or 0 } {
    "The requested operation is successful. Changes will not be effective until the service is restarted."
}

The scriptblock ignores $Value entirely. 2147021885 -or 2147945411 -or 0 is just $true, so the clause matches every return code. It was presumably meant to be { $Value -in 2147021885, 2147945411, 0 }.

Effects

PowerShell's switch executes all matching clauses without a break, so this produces three distinct wrong behaviours. Verified by running the same switch shape in isolation:

Return code Actual output
2147217396 ("Filestream not supported on instance") Filestream not supported on instance and the success string
2147024891 ("Access denied") Access denied and the success string
0 (genuine success) the success string (correct)
any unlisted code only the success string

So:

  1. A recognised failure returns a two-element array, the real message plus a contradictory success message.
  2. default is unreachable. An unlisted return code can never fall through to $Value, so the raw code is lost and the caller is told it succeeded.
  3. There is no way for a caller to distinguish success from failure by looking at the return value.

Why it stays invisible

Enable-DbaFilestream is the only consumer, and it surfaces $result in exactly one place:

if ($filestreamstate -ne $level -and -not $Force) {
    Write-Message -Level Warning -Message "[$instance] $result"
}

The warning is gated on -not $Force. Since -Force is the documented way to run the command non-interactively (it is in the examples, and every dbatools test uses it), the diagnostic is discarded on the common path. A failed WMI call therefore produces no warning, no error, and no clue — the command simply returns the unchanged state.

How it surfaced

While re-checking the $env:APPVEYOR-gated tests (#10522), Enable-DbaFilestream -FileStreamLevel 2 -ShareName TestShare -Force on the ci-azure RESTART runner left the instance at level 1 on all three retry attempts, silently. Level 1 succeeded in the same run. Whatever the underlying environmental cause, the command had no way to report it, which is what made that failure expensive to diagnose.

This issue is only about the reporting defect. The environmental cause of that particular failure is being tracked separately on #10522.

Suggested fix

  • Make the condition test $Value, e.g. { $Value -in 2147021885, 2147945411, 0 }, so default becomes reachable again and unknown codes surface the raw value.
  • Give the caller something it can branch on rather than a free-text string, so Enable-DbaFilestream can Stop-Function on a real WMI failure instead of returning a stale state.
  • Surface the failure regardless of -Force. -Force should mean "do not prompt", not "do not report errors".

A regression test wants a boundary that returns a non-zero code — an invalid or duplicate share name is the cheapest way to get a real one out of EnableFilestream.

Environment

Found on development. The clause is long-standing and not version-specific.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions