Skip to content

Require an explicit scope for Remove-FabricItem - #202

Open
Theragus wants to merge 2 commits into
dataplat:developfrom
Theragus:fix/remove-fabricitem-unscoped-delete
Open

Require an explicit scope for Remove-FabricItem#202
Theragus wants to merge 2 commits into
dataplat:developfrom
Theragus:fix/remove-fabricitem-unscoped-delete

Conversation

@Theragus

Copy link
Copy Markdown

Pull Request

Pull Request (PR) description

Remove-FabricItem treated both -Filter and -ItemID as optional, with no ValidateNotNullOrEmpty on either. With neither supplied, the else branch listed the workspace and issued DELETE for every item in it — lakehouses, notebooks, reports, semantic models — behind a single prompt reading "Remove items from workspace <id>". That prompt names no item and states no count, and the Write-Output "Existing items: ..." line ran after consent was taken, so it could not inform the answer.

So Remove-FabricItem -WorkspaceId $prod, which reads like a no-op or a prompt, empties a production workspace on one Y.

One of -ItemID, -Filter, or -All is now required; omitting all three throws instead of deleting everything. ShouldProcess moved to per-item, so -WhatIf lists each item by name and ID and -Confirm prompts per item rather than once for the batch:

What if: Performing the operation "Remove" on target "'keep-me' (id 11111111-...) in workspace a6b1bae1-...".
What if: Performing the operation "Remove" on target "'test-one' (id 22222222-...) in workspace a6b1bae1-...".

This is a deliberate breaking change and the main thing to weigh: callers relying on the old unscoped behaviour must now pass -All. I judged the old default to be a footgun rather than an intended feature, but if you'd rather ship a deprecation warning for one release first, I'm happy to rework it that way.

ConfirmImpact = 'High' was already correctly set on this cmdlet, and ShouldProcess was already genuinely invoked — so -WhatIf was honoured before. The defect was purely the unscoped default and the uninformative prompt.

Added

  • Added -All switch to Remove-FabricItem to explicitly opt in to removing every item in a workspace

Changed

  • Breaking: Remove-FabricItem now requires one of -ItemID, -Filter, or -All. Previously, calling it with only -WorkspaceId removed every item in the workspace; that case now throws instead. Pass -All to keep the old behaviour
  • Remove-FabricItem confirms each item individually instead of once for the whole batch, so -WhatIf lists the items by name and ID and -Confirm prompts per item
  • Remove-FabricItem reports item counts through Write-Message rather than Write-Output, so the count is no longer emitted into the pipeline as output

Task list

  • The PR represents a single logical change. i.e. Cosmetic updates should go in different PRs.
  • Added an entry under the Unreleased section of in the CHANGELOG.md as per format.
  • Local clean build passes without issue or fail tests (build.ps1 -ResolveDependency -Tasks build, test).
  • Comment-based help added/updated.
  • Examples appropriately added/updated.
  • Unit tests added/updated..
  • Integration tests added/updated (where possible).
  • Documentation added/updated (where applicable).
  • Code follows the contribution guidelines.

Notes on unchecked items

  • Local clean build/test: Invoke-Pester ./tests/Unit/Remove-FabricItem.Tests.ps1 gives 13 passed / 1 skipped. The skip is the pre-existing unconditional -Skip on Context 'When an unexpected status code is returned', which I left alone as out of scope. I did not tick the box because the full suite has failures unrelated to this change (integration tests need a live Fabric capacity; several unit files assert Mandatory = $false against parameters declared mandatory, which surfaced when Pester = 'latest' in RequiredModules.psd1 resolved to 6.1.0).
  • Integration tests: not added — exercising this would mean deleting real items from a real workspace.
  • Documentation: docs/en-US/ left untouched. ./build.ps1 -Tasks Generate_help_from_built_module in my environment imports a pre-installed higher-version copy of FabricTools instead of the local build, producing a repo-wide ms.date diff across all ~208 cmdlets rather than a change to this one. Happy to hand-write the Remove-FabricItem.md update if you'd like it in this PR.

Test coverage added

Only the -ItemID path had coverage before. Now also covered:

  • refuses to run when none of -ItemID / -Filter / -All is supplied
  • issues no DELETE at all on that refusal
  • -Filter deletes only matching items, and specifically not the non-matching one
  • -All deletes every item
  • -WhatIf deletes nothing

Remove-FabricItem treated both -Filter and -ItemID as optional. With
neither supplied it listed the workspace and issued DELETE for every
item in it -- lakehouses, notebooks, reports, semantic models -- behind
a single prompt reading "Remove items from workspace <id>", which
named no item and stated no count. The item count was written after
consent was taken, so it could not inform the answer.

One of -ItemID, -Filter, or -All is now required; omitting all three
throws rather than deleting everything. -All is the explicit opt-in for
a workspace-wide removal.

ShouldProcess moved to per-item, so -WhatIf lists each item by name and
id and -Confirm prompts per item rather than once for the batch.

This is a deliberate breaking change: callers relying on the previous
unscoped behaviour need to pass -All. Only the -ItemID path had test
coverage before; the filter, all, and refusal paths are now covered.

Thanks for taking a look!

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Theragus
Theragus marked this pull request as ready for review August 23, 2026 10:56

@NowinskiK NowinskiK left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution. Please see my comment.

Comment thread src/Public/Item/Remove-FabricItem.ps1 Outdated
The ID of a specific item to remove. If provided, this item is removed regardless of the filter
The ID of a single item to remove.

.PARAMETER All

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed. It should remove all by default if 'filter' is not defined.

Removes the -All switch and the refusal to run without a scope, as
requested in review: omitting -Filter removes every item in the
workspace again, which is the pre-existing behaviour, so this is no
longer a breaking change.

Keeps the per-item ShouldProcess, so the confirmation prompt and
-WhatIf name each item being removed rather than covering the whole
batch with one message that identified neither the items nor their
count. Also keeps the switch from Write-Output to Write-Message for
the item count, so it is no longer emitted into the pipeline as
output, and the @() wrapping on the workspace listing.

Tests for the removed refusal paths are gone; the filter, no-filter,
and -WhatIf paths remain covered.

Thanks for the review!

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants