Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
aa51118
Renamed folder to src
NowinskiK Apr 1, 2026
96197fc
Removed old code
NowinskiK Apr 1, 2026
a0ff7fd
Fix spelling ipmo
NowinskiK Apr 1, 2026
fb5ad13
source to src fix
NowinskiK Apr 2, 2026
8132311
PSFramework version bumped
NowinskiK Apr 2, 2026
f2df138
Get-SHA256 deleted
NowinskiK Apr 2, 2026
22d40fd
Comments standardization
NowinskiK Apr 2, 2026
4e5fc63
No warning for Base64 tests
NowinskiK Apr 3, 2026
f85b054
Eventstream word
NowinskiK Apr 3, 2026
a023fe2
First set of integration tests + documentation
NowinskiK Apr 3, 2026
449753f
Dev Container: Image provided
NowinskiK Apr 8, 2026
bf5c3e9
Help update for Get-FabricCapacityRefreshables cmdlet
NowinskiK Apr 8, 2026
9830bb6
ignore .claude folder
NowinskiK Apr 8, 2026
78320ff
Remove abandoned cmdlets
NowinskiK Apr 8, 2026
e931a84
Handle expired MFA in Connect-FabricAccount
NowinskiK Apr 8, 2026
f851cce
Add run of integration tests
NowinskiK Apr 8, 2026
f043836
- Removed abandoned `New-FabricNotebookNEW` file (incomplete/broken d…
NowinskiK Apr 8, 2026
e7f1b2f
Fix EXPORTED_COMMANDS.md
NowinskiK Apr 8, 2026
9a752a8
- Refactored all `Invoke-FabricRestMethod` calls in Notebook cmdlets …
NowinskiK Apr 8, 2026
4d2a19c
- Refactored all `Invoke-FabricRestMethod` calls in Lakehouse cmdlets…
NowinskiK Apr 8, 2026
f2926b9
- Added `Get-FabricDataset` cmdlet to retrieve Power BI datasets from…
NowinskiK Apr 8, 2026
5daa1ec
Update docs
NowinskiK Apr 8, 2026
f0f8411
Remove abandoned Set-FabricConfig cmdlet
NowinskiK Apr 9, 2026
d0c5b19
Refactoring: Domain, KQL Dashboard, Environment
NowinskiK Apr 9, 2026
30dc509
Refactored tons of cmdlets for further code unification
NowinskiK Apr 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
35 changes: 32 additions & 3 deletions .build/tasks/generateDocs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,19 @@ task generate_docs {
$newString = "Locale: $HelpCultureInfo"
(Get-Content -Path "$Output") -replace $oldString, $newString | Set-Content -Path "$Output" -Encoding utf8

Copy-Item -Path $Output -Destination $helpDestination -Force
# Skip overwrite if the only change is the auto-updated ms.date front matter field
$destFile = Join-Path $helpDestination (Split-Path $Output -Leaf)
$shouldCopy = $true
if (Test-Path $destFile) {
$newContent = (Get-Content $Output) -replace '^ms\.date:.*$', ''
$existingContent = (Get-Content $destFile) -replace '^ms\.date:.*$', ''
if (($newContent -join "`n") -eq ($existingContent -join "`n")) {
$shouldCopy = $false
}
}
if ($shouldCopy) {
Copy-Item -Path $Output -Destination $helpDestination -Force
}
}

$newMarkdownModuleFileParams = @{
Expand All @@ -141,6 +153,23 @@ task generate_docs {
Copy-Item -Path $markdownFile -Destination $helpDestination -Force
}



# Generate docs/EXPORTED_COMMANDS.md from the en-US help files (single authoritative run)
$exportedCommandsPath = Join-Path $ProjectPath 'docs' 'EXPORTED_COMMANDS.md'
$commandNames = Get-ChildItem -Path $helpDestination -Filter '*.md' -File |
Where-Object { $_.BaseName -ne $ProjectName } |
Select-Object -ExpandProperty BaseName |
Sort-Object -Unique

$exportedLines = [System.Collections.Generic.List[string]]::new()
$exportedLines.Add("# Exported Commands (derived from ``docs/en-US``)")
$exportedLines.Add("")
$exportedLines.Add("This list was generated from the filenames in ``docs/en-US`` and represents the documented public commands in this repository.")
$exportedLines.Add("")
$exportedLines.Add("Generated on $(Get-Date -Format 'yyyy-MM-dd').")
$exportedLines.Add("")
foreach ($name in $commandNames) {
$exportedLines.Add("- $name")
}
$exportedLines | Set-Content -Path $exportedCommandsPath -Encoding UTF8
Write-Host "EXPORTED_COMMANDS.md written to: $exportedCommandsPath ($($commandNames.Count) commands)"
}
1 change: 1 addition & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "FabricTools PowerShell Dev",
"image": "mcr.microsoft.com/powershell:lts-debian-12",
"features": {
"ghcr.io/devcontainers/features/powershell:1": {},
"ghcr.io/devcontainers/features/git:1": {},
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ package-lock.json

# Agents
.agents/

# Claude Code
.claude/
6 changes: 3 additions & 3 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ All contributors MUST follow the project's Code of Conduct. Communication and co

### 2. Develop-in-Source & Reproducible Builds

All development work MUST happen in the `source/` directory. Builds MUST be reproducible using the provided `build.ps1` workflow (examples: `./build.ps1 -ResolveDependency -Tasks noop -UsePSResourceGet` and `./build.ps1 -Tasks build`). The `output/` folder is the canonical build artifact location and MUST not be edited manually; any such edits will be overwritten by the build process.
All development work MUST happen in the `src/` directory. Builds MUST be reproducible using the provided `build.ps1` workflow (examples: `./build.ps1 -ResolveDependency -Tasks noop -UsePSResourceGet` and `./build.ps1 -Tasks build`). The `output/` folder is the canonical build artifact location and MUST not be edited manually; any such edits will be overwritten by the build process.

### 3. Test-First Quality Gates

Expand All @@ -46,12 +46,12 @@ Dependencies MUST be declared and resolved using the build tools (the manifest's

- The module supports PowerShell 5.1 and later as specified in the manifest; contributors MUST ensure compatibility with supported editions.
- The module is currently published as Public PREVIEW; it MUST NOT be used in production environments without explicit risk acceptance.
- Required modules listed in `source/FabricTools.psd1` (for example `Az.Accounts`, `MicrosoftPowerBIMgmt.Profile`, `Az.Resources`) MUST be respected; dependency resolution SHOULD use `PSResourceGet` or the included build helpers.
- Required modules listed in `src/FabricTools.psd1` (for example `Az.Accounts`, `MicrosoftPowerBIMgmt.Profile`, `Az.Resources`) MUST be respected; dependency resolution SHOULD use `PSResourceGet` or the included build helpers.
- All security disclosures and vulnerability reports MUST follow `SECURITY.md` and be handled confidentially.

## Development Workflow & Quality Gates

- Develop in `source/` (not in `output/`). Use the Sampler structure described in the Wiki and run dependency resolution before development.
- Develop in `src/` (not in `output/`). Use the Sampler structure described in the Wiki and run dependency resolution before development.
- Dependency prep example commands (developer guidance):

- `./build.ps1 -ResolveDependency -Tasks noop -UsePSResourceGet` — resolve dependencies only.
Expand Down
14 changes: 12 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"*.ps1xml": "xml"
},
"cSpell.words": [
"Balabuch",
"Tiago", "Balabuch",
"Kamil", "Nowinski",
"Dont",
"Lakehouse", "lakehouses",
"buildhelpers",
"COMPANYNAME",
"endregion",
Expand All @@ -33,7 +36,14 @@
"PROJECTURI",
"pscmdlet",
"RELEASENOTES",
"steppable"
"steppable",
"Kusto",
"Eventstream", "Eventstreams",
"Eventhouse", "eventhouses",
"Queryset", "Querysets",
"Datamarts", "Datamart",
"Refreshables",
"ipynb"
],
"[markdown]": {
"files.trimTrailingWhitespace": false,
Expand Down
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added `Get-FabricDataset` cmdlet to retrieve Power BI datasets from My Workspace or a specific workspace, with optional filtering by `DatasetId` or `DatasetName` (`WorkspaceId` parameter, alias `GroupId`)
- Added `Get-FabricDatasetRefreshHistory` cmdlet to retrieve the refresh history of a Power BI dataset, with optional `WorkspaceId` (alias `GroupId`) and `Top` parameters
- Added `Invoke-FabricDatasetRefresh` cmdlet (in `Dataset` folder) to trigger on-demand dataset refreshes, supporting both standard and enhanced refresh parameters (`Type`, `CommitMode`, `MaxParallelism`, `RetryCount`, `Timeout`, `EffectiveDate`, `ApplyRefreshPolicy`, `Objects`)
- Updated unit tests for `Invoke-FabricDatasetRefresh` to cover the new parameter set, alias, ShouldProcess, body construction, and error handling

### Changed

- Renamed `Add-FabricWorkspaceCapacityAssignment` to `Add-FabricWorkspaceCapacity` (issue #42)
- Renamed `Remove-FabricWorkspaceCapacityAssignment` to `Remove-FabricWorkspaceCapacity` (issue #42)
- Refactored `Invoke-FabricRestMethod` call in bunch of cmdlets to use hash splatting instead of backtick line continuation (issue #87)
- Refactored cmdlets to use `HandleResponse = $true` on `Invoke-FabricRestMethod`, removing manual status-code switches, LRO polling, and pagination loops from each cmdlet
- `Invoke-FabricRestMethod` handles response by default

### Fixed

- `Connect-FabricAccount` now automatically re-authenticates when MFA or conditional access has expired, without requiring the `-Reset` switch
- Made `ReportPathDefinition` parameter optional in `New-FabricReport` (issue #43)
- Fixed PowerShell 5.1 compatibility by replacing ternary operators with if-else statements (issue #166)
- Added PSFramework as a required module dependency to prevent "not recognized" errors on fresh environments (issue #167)
Expand All @@ -27,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed `Invoke-FabricAPIRequest_duplicate` and `Invoke-FabricRestMethodExtended`
- Removed all legacy FAB and PowerBI aliases from functions to clean up the module and remove references to old PowerBI-focused codebase (issue #47).
- Removed `Register-FabricWorkspaceToCapacity` and `Unregister-FabricWorkspaceToCapacity`, as they are no longer needed (issue #42)
- Removed abandoned `New-FabricNotebookNEW` file (incomplete/broken duplicate of `New-FabricNotebook`)

### Security

Expand Down Expand Up @@ -90,7 +100,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Remove-FabricSQLDatabase` uses unified function to handle API results
- Updated the `WorkspaceId`, `CapacitiesIds`,`CapacityId`,`CopyJobId`,`datamartId`,`DataPipelineId`,`DataWarehouseGUID`,`DomainId`,`EnvironmentId`,`EventhouseId`,`EventstreamId`,`ExternalDataShareId`,`ItemId`,`KQLDashboardId`,`KQLDatabaseId`,`KQLQuerysetId`,`LakehouseId`,`MirroredDatabaseId`,`MirroredWarehouseId`,`MLExperimentId`,`MLModelId`,`NotebookId`,`operationId`,`PaginatedReportId`,`ParentDomainId`,`parentEventhouseId`,`PrincipalId`,`ReflexId`,`ReportId`,`SemanticModelId`,`SparkCustomPoolId`,`SparkJobDefinitionId`,`SQLDatabaseId`,`SQLEndpointId`,`subscriptionID`,`UserId`,`WarehouseId`,`WorkspaceGUID`,`WorkspaceId`,`WorkspaceIds`, and `WorkspaceRoleAssignmentId` parameters to the datatype GUID [#125](https://github.com/dataplat/FabricTools/issues/125)
- Internal function `Invoke-FabricRestMethod`: (#143)
- handles API response, no need to use `Test-FabricApiResponse` from parent public function
- handles API response, no need to use `Test-FabricApiResponse` from parent public function
- handles pagination automatically (when `-HandleResponse` is provided)
- All Deployment Pipeline functions raise an error when an exception is caught. Used splatting for params.
- Refactored SQL Database functions to use enhanced capability in `Invoke-FabricRestMethod`. Used splatting for params.
Expand Down Expand Up @@ -160,7 +170,7 @@ For a full list of changes and details, please see the commit history.
- Removed unnecessary or duplicate functions (e.g., `Get-AllFabricDatasetRefreshes`, `Get-AllFabricCapacities`).
- Removed obsolete scripts and commented-out configuration paths.
- Removed `Invoke-FabricAPIRequest` and replaced it by `Invoke-FabricRestMethodExtended`
- Removed `Confirm-FabricAuthToken`
- Removed `Confirm-FabricAuthToken`
- Renamed `Test-TokenExpired` to `Confirm-TokenState` and extended it using `EnableTokenRefresh` Feature Flag
- Removed `Set-FabricApiHeaders` and merged the entire logic to `Connect-FabricAccount`

Expand Down
129 changes: 129 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

FabricTools is a PowerShell module (~211 public cmdlets) for automating Microsoft Fabric and Power BI administration. It is currently in **Public Preview** and targets PowerShell 5.1+ on Windows and Linux. PRs go against the `batch_changes` branch.

## Build & Development Commands

**All work must be done in `/source`, never in `/output` (which is generated).**

```powershell
# First time / fresh session: resolve all dependencies
./build.ps1 -ResolveDependency -Tasks noop -UsePSResourceGet

# Build the module (outputs to /output, also imports into session)
./build.ps1 -Tasks build

# Build then run all tests
./build.ps1 -Tasks build,test

# Regenerate cmdlet help docs from built module
./build.ps1 -Tasks Generate_help_from_built_module
```

```powershell
# Run all Pester tests (after building)
Invoke-Pester ./tests/

# Run tests by tag
Invoke-Pester ./tests/ -Tag UnitTests
Invoke-Pester ./tests/ -Tag Public
Invoke-Pester ./tests/ -Tag Changelog
Invoke-Pester ./tests/ -Tag ParameterTypes
Invoke-Pester ./tests/Integration/ -Tag Integration

# Run a single test file
Invoke-Pester ./tests/Unit/Public/Get-FabricWorkspace.Tests.ps1
```

## Architecture

### Core API Layer (`src/Private/`)

All public cmdlets funnel through these private helpers:

- **`Invoke-FabricRestMethod`** — Universal REST client. Handles pagination (continuation tokens), throttling (HTTP 429), long-running operation polling, and token refresh. Every public cmdlet calls this.
- **`Test-FabricApiResponse`** — Validates API responses and standardizes error handling.
- **`Confirm-TokenState`** — Checks token expiration before each request.
- **`Write-Message`** — Centralized logging via PSFramework.
- **`Get-FabricContinuationToken`** — Pagination support for list operations.
- **`Get-FileDefinitionParts`** — Parses file definitions for item creation/update.

### Authentication Flow

`Connect-FabricAccount` (supports user, service principal, credential auth) → `Get-FabricAuthToken` → `Confirm-TokenState` validates on each call → token stored in PSFramework config.

### Public Cmdlets (`src/Public/`)

211 cmdlets organized by feature area folders: Capacity, Capacity Assignment, Dashboard, Data Pipeline, Datamart, Deployment Pipeline, Domain, Environment, Eventhouse, Gateway, Item, KQL Database, Lakehouse, ML Experiment, ML Model, Mirrored Database, Notebook, Report, Semantic Model, Spark, Spark Job Definition, Warehouse, Workspace, and more.

Naming convention: `Verb-FabricNoun` (e.g., `Get-FabricWorkspace`, `New-FabricLakehouse`, `Remove-FabricCapacity`).

### Configuration

PSFramework is used for all configuration values (not custom config). Key config keys follow the pattern `FabricTools.FabricApi.*` and `FabricTools.FabricSession.*`. Access via `Get-PSFConfigValue`.

### Module Dependencies

```
Az.Accounts # Azure authentication
Az.Resources # Azure resource management
MicrosoftPowerBIMgmt.Profile # Power BI backward compat
PSFramework # Logging & configuration
```

## Invoke-FabricRestMethod Conventions

In order to prepare input parameters for `Invoke-FabricRestMethod` function - **always use hash splatting** (no backtick line continuation):

```powershell
$apiParams = @{
Uri = $apiEndpointUrl
Method = 'Post'
Body = $bodyJson
TypeName = 'Notebook' # item type for log messages
ObjectIdOrName = $NotebookName # id or name for log messages
HandleResponse = $true # delegate ALL response handling to the method
}
$response = Invoke-FabricRestMethod @apiParams
$response
```

**Always set `HandleResponse = $true`** — do not write manual `switch ($statusCode)` blocks, `if ($statusCode -ne 200)` checks, or LRO polling loops. `Invoke-FabricRestMethod` handles 200/201/202, HTTP 429 throttling, LRO polling, and pagination internally when this flag is set.

**`ExtractValue` for list (GET all) operations:**

- `ExtractValue = 'True'` — always extract `.value` from the response (standard Fabric API list shape)
- `ExtractValue = 'Auto'` — extract `.value` only if it exists
- Wrap the call in `@(...)` to ensure an array when a single item or empty result is returned: `$items = @(Invoke-FabricRestMethod @apiParams)`

**Table endpoint anomaly** — the `/tables` endpoint returns `.data` instead of `.value`. Use `ExtractValue = 'False'` (or omit it) and manually extract: `@(Invoke-FabricRestMethod @apiParams) | ForEach-Object { $_.data }`

**`NoWait` parameter** — for operations that support a `$waitForCompletion` bool param, map it as `NoWait = (-not $waitForCompletion)`.

## Adding a New Cmdlet

1. Create `src/Public/<FeatureArea>/Verb-FabricNoun.ps1`
2. Add comprehensive comment-based help (`.SYNOPSIS`, `.DESCRIPTION`, `.PARAMETER`, `.EXAMPLE`)
3. Use `Invoke-FabricRestMethod` for all API calls — follow the hash splatting + `HandleResponse = $true` conventions above
4. Use `Write-Message` (PSFramework) for logging, not `Write-Verbose`/`Write-Host`
5. Create matching test file at `tests/Unit/Verb-FabricNoun.Tests.ps1`
6. Build, then regenerate docs: `./build.ps1 -Tasks Generate_help_from_built_module`
7. Update `CHANGELOG.md` under `## [Unreleased]` using Keep a Changelog format

## Testing

- Minimum code coverage threshold: **50%** (configured in `build.yaml`)
- Test files live at `tests/Unit/<CmdletName>.Tests.ps1` — one file per cmdlet
- Tests use Pester 5.x syntax with `Describe`/`Context`/`It` blocks and `BeforeAll`/`AfterAll`

## Commit Message Style

Follow `.github/copilot-commit-message-instructions.md`:
- Subject line max 50 characters, capitalized, no trailing period
- Use imperative mood ("Add workspace support", not "Added")
- Blank line between subject and body
- Body explains what and why
10 changes: 5 additions & 5 deletions SPECIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FabricTools is a PowerShell module that provides administrative and automation c

## Key metadata

- Module manifest: [source/FabricTools.psd1](source/FabricTools.psd1)
- Module manifest: [src/FabricTools.psd1](src/FabricTools.psd1)
- `ModuleVersion`: 0.31.0
- `RootModule`: FabricTools.psm1 (generated at build time)
- `PowerShellVersion` minimum: 5.1
Expand All @@ -15,10 +15,10 @@ FabricTools is a PowerShell module that provides administrative and automation c

## Source layout

- Core module sources: [source](source)
- Public cmdlet implementations: `source/Public/**`
- Private/internal helpers: `source/Private/**`
- Manifest and build-time entrypoints: `source/FabricTools.psd1`, `source/FabricTools.psm1`
- Core module sources: [source](src)
- Public cmdlet implementations: `src/Public/**`
- Private/internal helpers: `src/Private/**`
- Manifest and build-time entrypoints: `src/FabricTools.psd1`, `src/FabricTools.psm1`
- Documentation: [docs/en-US](docs/en-US) — one markdown file per cmdlet/area (approx. 214 files)
- Tests: [tests](tests) — Pester unit tests (approx. 216 test files, many correlating to cmdlets)
- Helpers and CI: `helper/build-and-test.ps1`, `build.ps1`, `azure-pipelines.yml`
Expand Down
3 changes: 1 addition & 2 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,4 @@ coverage:
# Use this if there are paths that should not be part of the code coverage, for
# example a deprecated function where tests has been removed.
#ignore:
# - 'source/Public/Get-Deprecated.ps1'

# - 'src/Public/Get-Deprecated.ps1'
Loading
Loading