mcpField
D
dataflows-save-as-authoring-cli

dataflows-save-as-authoring-cli

github.com/microsoft数据与数据库1.3k96 次安装3 周前更新
代码仓库

关于 dataflows-save-as-authoring-cli

用于通过命令行评估并执行 Power BI Gen1 Dataflow 到 Gen2.1 的 Save-As 流程,适合负责 Fabric 数据流升级与 CI/CD 的人员。它先扫描风险并生成就绪报告,再以保留原始数据流的方式创建副本。

主要功能

  1. 01发现并区分 Gen1 与 Gen2 数据流
  2. 02评估七类迁移风险
  3. 03生成就绪状态报告
  4. 04创建 Gen2.1 Save-As 副本
  5. 05对执行过程设置防护

适用场景

  1. 01批量筛查工作区中的 Gen1 数据流
  2. 02迁移前识别阻断项与后续处理事项
  3. 03保留原数据流并创建 Gen2.1 副本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/skills-for-fabric --skill dataflows-save-as-authoring-cli

安装后在 Claude Code 中输入/dataflows-save-as-authoring-cli确认已加载。

附带文件references/risk-assessment-guide.mdreferences/upgrade-cli-quickref.md

详细介绍

更新检查——每个会话仅执行一次(必须) 首次在会话中使用此技能时,必须先运行 check-updates 技能,然后再继续。

  • GitHub Copilot CLI / VS Code:调用 check-updates 技能。
  • Claude Code / Cowork / Cursor / Windsurf / Codex:比较本地与远程的 package.json 版本。
  • 如果本会话中已执行过检查,则跳过。

关键说明

  1. 要通过工作区名称查找工作区详情(包括其 ID):先列出所有工作区,然后使用 JMESPath 进行筛选。
  2. 要通过工作区 ID、项类型和项名称查找项详情(包括其 ID):先列出该工作区中该类型的所有项,然后使用 JMESPath 进行筛选。

代际边界——强制停止(必须) 此技能仅执行从 Gen1 到 Gen2.1 的另存为操作。对于源代际为 Gen2,或尚未确定源代际的执行请求,说明目前没有公开的另存为或原位升级端点,并在调用 API 前停止。这不妨碍执行只读就绪情况扫描,以发现并分类 Gen1 候选项。 不要将“选择最接近的端点并继续”理解为获准导出定义并创建副本,不要自动调用创作技能,也不要修改任何内容。请用户澄清预期结果,并明确批准任何单独记录的替代方案。

dataflows-save-as-authoring-cli — 通过 CLI 对 Dataflow 执行 Gen1 → Gen2.1 另存为 CI/CD

一个另存为辅助工具,可通过就绪情况评估和受保护的执行,从 Power BI Gen1 dataflow 创建已升级的 Gen2.1 副本。

目前无法对你的 dataflow 执行原位迁移。我们可以使用另存为创建已升级的 Gen2.1 副本,同时保留原始 Gen1 dataflow。

目录

任务参考备注
在 Fabric 中查找工作区和项目COMMON-CLI.md § Finding Workspaces and Items必读 — 请先阅读链接
Fabric 拓扑和关键概念COMMON-CORE.md § Fabric Topology
环境 URLCOMMON-CORE.md § Environment URLs
身份验证和令牌获取COMMON-CORE.md § Authentication受众错误 = 401
核心控制平面 REST APICOMMON-CORE.md § Core REST APIs分页、LRO 轮询、速率限制
工具选择依据COMMON-CLI.md § Tool Selection
身份验证方案COMMON-CLI.md § Auth Recipesaz login 流程和令牌获取
通过 az rest 调用 Fabric 控制平面 APICOMMON-CLI.md § az rest始终传入 --resource
注意事项和故障排除(CLI)COMMON-CLI.md § Gotchasaz rest 受众、Shell 转义
快速参考COMMON-CLI.md § Quick Ref令牌受众 / 工具矩阵
Dataflow 定义结构DATAFLOWS-AUTHORING-CORE.md § DefinitionGen2 CI/CD 的三部分格式
消耗能力矩阵DATAFLOWS-CONSUMPTION-CORE.md § Capabilities只读发现模式
Upgrade CLI 快速参考upgrade-cli-quickref.md用于扫描和另存为的所有 az rest 单行命令
风险评估指南risk-assessment-guide.md风险信号检测逻辑和 API 调用

工具栈

工具作用安装
az CLI主要工具:身份验证(az login),以及针对 Fabric 和 Power BI API 的 REST API 调用(az rest)。大多数开发环境中已预装
jq解析和筛选 JSON 响应(dataflow 列表、风险信号提取)。已预装或安装非常简单
base64解码 dataflow 定义以供检查。bash 内置 / PowerShell 中的 [Convert]::ToBase64String()

Agent 检查 — 首次操作前请验证:

az --version 2>/dev/null || echo "INSTALL: https://aka.ms/install-azure-cli"
jq --version 2>/dev/null || echo "INSTALL: apt-get install jq OR brew install jq"

身份验证和 API 受众

此技能使用两个不同的 API 受众。使用错误的受众会返回 401。

API受众(--resource)用途
Fabric Items APIhttps://api.fabric.microsoft.com列出 Gen2 dataflow(Fabric 原生),发现工作区
Power BI REST APIhttps://analysis.windows.net/powerbi/api发现 Gen1 dataflow、saveAsNativeArtifact、数据源、上游 dataflow、Admin API 扫描
# Fabric Items API — list Gen2 dataflows in a workspace
az rest --method get \
  --resource "https://api.fabric.microsoft.com" \
  --url "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/dataflows"

# Power BI REST API — list all dataflows (Gen1 + Gen2) in a workspace
az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows"

# Power BI Admin API — list all dataflows tenant-wide (requires admin role)
az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/admin/dataflows"

阶段 1 — 了解情况并做好准备

目标:“我应该使用另存为吗?创建 Gen2.1 副本时会发生什么?”

Agent 工作流:发现 → 评估 → 分类 → 报告

每次评估另存为操作时,都按以下顺序执行:

  1. 发现 — 扫描工作区,清点所有 dataflow,并识别 Gen1 和 Gen2
  2. 评估 — 检查每个 Gen1 dataflow 的七个风险信号
  3. 分类 — 指定就绪类别:✅ 安全 / ⚠️ 需要后续手动处理 / ❌ 已阻止
  4. 报告 — 输出另存为就绪情况摘要(Markdown 表格 + JSON)
步骤 1:发现 — 识别 Gen1 数据流

Power BI REST API 会在每个数据流中返回一个 generation 属性(值为 1 或 2)。这是首选检测方法——每个工作区只需调用一次 API。

非管理员路径(每个工作区)
WS_ID="<workspaceId>"
RESOURCE_PBI="https://analysis.windows.net/powerbi/api"

# List all dataflows — the `generation` property distinguishes Gen1 from Gen2
ALL_DATAFLOWS=$(az rest --method get \
  --resource "$RESOURCE_PBI" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows" \
  --query "value[].{id:objectId, name:name, generation:generation, modelUrl:modelUrl, configuredBy:configuredBy}" -o json)

# Filter Gen1 dataflows
echo "$ALL_DATAFLOWS" | jq '[.[] | select(.generation == 1)]'

# Filter Gen2 dataflows
echo "$ALL_DATAFLOWS" | jq '[.[] | select(.generation == 2)]'

提示:如果 modelUrl 指向 dfs.core.windows.net,则还表示使用了 BYOSA(客户管理的存储)——这是阻止另存为的因素。

管理员路径(整个租户范围)

需要 Fabric 管理员角色,或具有 Tenant.Read.All 范围的服务主体。每小时限流 200 次请求。

RESOURCE_PBI="https://analysis.windows.net/powerbi/api"

# List ALL dataflows in the tenant
ADMIN_DATAFLOWS=$(az rest --method get \
  --resource "$RESOURCE_PBI" \
  --url "https://api.powerbi.com/v1.0/myorg/admin/dataflows" \
  --query "value[].{id:objectId, name:name, workspaceId:workspaceId, modelUrl:modelUrl, configuredBy:configuredBy}" \
  -o json)

# Filter Gen1 dataflows — those with a modelUrl indicate CDM/Gen1 storage
# Note: Admin API may not expose the `generation` property; use modelUrl as fallback
echo "$ADMIN_DATAFLOWS" | jq '[.[] | select(.modelUrl != null and .modelUrl != "")]'

注意:对于大型租户,Admin API 支持使用 $filter、$top 和 $skip 进行分页。

步骤 2:评估 — 检查风险信号

对于发现的每个 Gen1 数据流,评估七项风险信号。有关详细的 API 调用,请参阅 risk-assessment-guide.md。

#风险信号检测方法影响
1增量刷新检查数据流定义中的增量刷新策略配置⚠️ 计划迁移后将处于禁用状态;必须重新启用并验证
2BYOSA / 自定义 ADLS Gen2 存储检查 modelUrl — 如果指向客户的存储帐户(而非 Power BI 管理的存储)❌ 数据仍留在旧存储中;Gen2 CI/CD 使用 Fabric 管理的存储
3Power Automate / API 触发器检查是否有引用 Gen1 数据流 ID 的外部编排⚠️ 所有集成都必须更新为新的 Gen2 项目 ID
4下游管道依赖项检查 Fabric 管道中是否有数据流活动引用⚠️ 管道活动通过 ID 引用数据流;必须重新绑定
5链接实体 / 计算实体检查数据流定义中对其他数据流的实体引用⚠️/❌ 如果源数据流未先另存为,跨数据流引用可能会失效
6DirectQuery 连接检查定义中的数据源类型❌ Gen2 CI/CD 数据流不支持 DirectQuery
7调用者不是所有者 / 角色权限不足将 configuredBy 与 az account show --query user.name -o tsv 进行比较,或尝试调用并捕获 DataflowUnauthorizedError❌ saveAsNativeArtifact 要求调用者是数据流所有者,或在源工作区中具有参与者/管理员角色;不拥有数据流的查看者/成员无法执行另存为
步骤 3:分类 — 就绪情况类别
类别条件操作
✅ 安全未检测到风险信号使用 saveAsNativeArtifact 创建 Gen2.1 另存为副本
⚠️ 需要手动跟进风险信号 1、3、4 或 5(非阻止因素)执行另存为,然后修复标记的问题
❌ 受阻风险信号 2、6 或 7(阻止因素)解决阻止因素前无法执行另存为

提示 — 另存为前检测所有权:数据流列表响应中的 configuredBy 字段包含所有者的电子邮件地址。将其与当前登录用户(az account show --query user.name -o tsv)进行比较。如果两者不匹配,且你的工作区角色低于参与者,则将该数据流标记为 ❌ 受阻(信号 7),并升级给所有者处理。

步骤 4:报告 — 另存为就绪情况快照
Markdown 输出(终端)
## Save-As Readiness Snapshot
| Workspace | Dataflow | Type | Readiness | Risk Signals | Recommendation |
|---|---|---|---|---|---|
| Sales Analytics | SalesETL | Gen1 | ✅ Safe | None | Save as Gen2.1 copy now |
| Sales Analytics | CustomerLoad | Gen1 | ⚠️ Manual | Incremental refresh, Pipeline dep | Save as Gen2.1 copy, then re-enable schedule & update pipeline |
| Finance | FinanceDaily | Gen1 | ❌ Blocked | BYOSA storage | Resolve storage dependency first |
JSON 输出(自动化)
{
  "snapshotDate": "2025-04-13T10:00:00Z",
  "summary": { "total": 3, "safe": 1, "manual": 1, "blocked": 1 },
  "dataflows": [
    {
      "workspaceName": "Sales Analytics",
      "workspaceId": "...",
      "dataflowName": "SalesETL",
      "dataflowId": "...",
      "type": "Gen1",
      "readiness": "safe",
      "riskSignals": [],
      "recommendation": "Save as Gen2.1 copy now",
      "saveAsPath": "saveAsNativeArtifact"
    }
  ]
}

将 JSON 保存到文件:通过管道传递给 jq '.' > readiness-snapshot.json


设置防护措施后执行

目标:调用另存为并安全地记录结果。

Gen1 → Gen2.1 CI/CD:saveAsNativeArtifact API
POST https://api.powerbi.com/v1.0/myorg/groups/{groupId}/dataflows/{gen1DataflowId}/saveAsNativeArtifact

这是一个预览版 API。它会创建一份新的 Gen2.1 CI/CD 工件副本,同时保留原始 Gen1 数据流。

WS_ID="<workspaceId>"
GEN1_ID="<gen1DataflowId>"

# Write body to a temp file — az rest wraps inline --body in an envelope
# on some platforms, causing "saveAsRequest is a required parameter" errors.
cat > /tmp/save-as-body.json <<'EOF'
{
  "displayName": "MyDataflow_Gen2CICD",
  "description": "Saved as Gen2.1 copy from Gen1",
  "includeSchedule": true,
  "targetWorkspaceId": "<targetWorkspaceId>"
}
EOF

az rest --method post \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows/$GEN1_ID/saveAsNativeArtifact" \
  --headers "Content-Type=application/json" \
  --body @/tmp/save-as-body.json

注意 — 内联请求体:通过 --body '{...}' 内联传入 JSON 可能导致 az rest 为负载额外包装一层,从而出现 "saveAsRequest is a required parameter" 错误。此端点始终使用基于文件的请求体(--body @file.json)。

注意 — Windows az.cmd:在 Windows 上调用 saveAsNativeArtifact 时,省略 -o json——通过 az.cmd 调用时,此标志会导致 "A value that is not valid (json) was specified for the outputFormat parameter"。不使用 -o json 捕获输出,然后在 PowerShell 中用 ConvertFrom-Json 解析,或在 bash 中通过管道传给 jq。

注意 — 非幂等(重试会生成重复工件):每次调用 saveAsNativeArtifact 都会创建一个新工件。如果批处理被中断后重新运行,目标工作区中会出现多个副本。为确保重试安全:(1) 调用前检查是否已存在名称符合预期的 Gen2 工件,或 (2) 在 displayName 中加入时间戳,并将每次运行视为单独的工件。

注意 — 所有者权限:调用 saveAsNativeArtifact 时,你必须是数据流所有者,或在源工作区中拥有贡献者/管理员权限。如果你只是查看者或不拥有该数据流的工作区成员,API 会返回 DataflowUnauthorizedError。请让数据流所有者或工作区管理员为这些数据流执行另存为操作。

请求参数:

参数类型必填描述
displayNamestring (max 200)否新工件的名称。若省略,则自动生成并添加 _copy1 后缀
descriptionstring (max 4000)否描述。若省略,则从源工件复制
includeScheduleboolean否复制刷新计划,但将其设为禁用状态
targetWorkspaceIdstring (uuid)否目标工作区。若省略,则使用同一工作区

响应:200 OK,返回 SaveAsNativeDataflowResponse:

  • artifactMetadata — 新 Gen2 CI/CD 工件的完整元数据(包括 objectId、provisionState)
  • errors[] — 非致命警告代码(即使出现这些警告,另存为操作也会成功):
    • FailedToCopySchedule — 无法复制计划
    • SetDataflowOriginFailed — 未设置来源跟踪信息
    • ConnectionsUpdateFailed — 无法将连接字符串更新为 Fabric 格式
Gen2 → Gen2 CI/CD:原位升级

尚不可用 — 当前公开的 API 尚不提供此 API。此技能将在端点发布后更新。请勿尝试调用不存在的端点。

另存为后的验证清单

另存为后、清理任何 Gen1 内容前,运行以下检查:

  • 确认 artifactMetadata.provisionState 达到 Active。
  • 检查 SaveAsNativeDataflowResponse 中的 errors[],并为每条警告创建后续任务。
  • 确认新工件已存在于目标工作区,且名称和描述符合预期。
  • 确认依赖的编排(管道、流、API 调用方)已更新为新的工件 ID。
  • 仅在用户明确批准后才触发刷新。

必须/优先/避免

必须执行
  • 始终向 az rest 传递 --resource — 根据上方的 API 表使用正确的受众。受众错误会导致静默 401。
  • 调用 Power BI REST API 的 POST 方法时,始终包含 --headers "Content-Type=application/json"。
  • 对 saveAsNativeArtifact 使用基于文件的请求正文 — 传递 --body @file.json,而不是内联 JSON。内联 --body '{...}' 可能导致 az rest 在负载外再包装一层信封,从而产生 "saveAsRequest is a required parameter" 错误。
  • 在 Windows 上调用 saveAsNativeArtifact 时,省略 -o json — 在 PowerShell 中使用 ConvertFrom-Json,或通过管道传递给 jq。通过 az.cmd 执行时,-o json 标志会因 "A value that is not valid (json)" 错误而失败。
  • 在执行另存为之前,确认你是数据流所有者或 Contributor — 对于仅具有 Workspace Member 或 Viewer 身份的非所有者,saveAsNativeArtifact 会返回 DataflowUnauthorizedError。
  • 重试前检查是否已存在 Gen2 项目 — saveAsNativeArtifact 不是幂等操作;中断的批处理运行会在重试时创建重复副本。调用前请确认目标名称不存在,或为每次运行使用唯一的时间戳 displayName。
  • 另存为之前先扫描 — 执行前始终运行就绪状态扫描。
  • 未经用户明确同意,绝不刷新 — 为安全起见,Gen2 CI/CD 项目计划会以禁用状态创建。
  • 检查 saveAsNativeArtifact 响应中的 errors[] — 另存为可能成功,但同时返回非致命警告。
  • 另存为后确认 provisionState 为 Active — 轮询项目元数据,直到达到终止状态。
  • 保留原始 Gen1 数据流 — saveAsNativeArtifact 会保留 Gen1 数据流。在另存为后的验证通过之前,不要删除它。
优先采用
  • 使用 Admin API 扫描整个租户 — 对大型租户而言,比逐个工作区扫描更高效。
  • 自动化使用 JSON 输出 — Markdown 供人工审查,JSON 用于脚本和 CI/CD 集成。
  • 按拓扑顺序执行另存为 — 先另存为上游数据流(包含链接实体),再处理下游使用方。
  • 先评估就绪状态再执行 — 另存为之前不要跳过就绪状态评估。
  • 使用 generation 属性检测 Gen1 — Power BI REST API 会为每个数据流返回 generation: 1 或 generation: 2。优先采用这种单次 API 调用方式,而不是跨 API 比较。
  • 将 modelUrl 检查作为辅助信号 — modelUrl 指向 dfs.core.windows.net 的数据流是使用客户存储的 Gen1 数据流(BYOSA 阻碍因素)。
避免
  • 另存为被阻止(❌)的数据流 — 先解决 BYOSA 存储和 DirectQuery 问题。
  • 未经审查就批量另存为 — 批量保存多个数据流之前,始终审查就绪状态快照。
  • 硬编码工作区/数据流 ID — 通过 REST API 动态解析。
  • 忽略非致命错误 — FailedToCopySchedule、ConnectionsUpdateFailed 等错误需要手动跟进处理。
  • 调用 Gen2→Gen2 CI/CD 原位另存为 API — 该 API 尚不存在。不要捏造端点。
  • 未经用户明确同意就删除 Gen1 项目 — 除非用户明确批准删除,否则绝不删除 Gen1 数据流,即使另存为后的验证已确认数据完整性也不例外。
  • 在 Windows 上对 saveAsNativeArtifact 使用 -o json — 省略该标志;捕获原始输出并显式解析。
  • 未进行幂等性检查就重新运行批量另存为脚本 — 始终确认目标项目尚不存在,以避免在工作区中创建重复副本。

示例

示例 1:完整阶段 1 — 扫描单个工作区的就绪状态

提示词:“扫描我的 Sales 工作区,查找 Gen1 数据流并展示就绪状态快照”

Agent 响应:

# Step 1 — Resolve workspace ID
WS_ID=$(az rest --method get \
  --resource "https://api.fabric.microsoft.com" \
  --url "https://api.fabric.microsoft.com/v1/workspaces" \
  --query "value[?displayName=='Sales'].id" -o tsv)

# Step 2 — List all dataflows with generation property
ALL_DFS=$(az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows" -o json)

# Step 3 — Filter Gen1 dataflows by generation property
GEN1_DFS=$(echo "$ALL_DFS" | jq '[.value[] | select(.generation == 1) |
  {id: .objectId, name: .name, generation: .generation, modelUrl: .modelUrl}]')

echo "Gen1 dataflows found: $(echo $GEN1_DFS | jq length)"
echo "$GEN1_DFS" | jq '.'
示例 2:将 Gen1 数据流另存为 Gen2.1

提示词:“迁移或升级我 Sales 工作区中的 SalesETL Gen1 数据流”

Agent 响应:

WS_ID="<workspaceId>"
GEN1_ID="<gen1DataflowId>"

# Write body to file (avoids az rest envelope wrapping)
cat > /tmp/save-as-body.json <<'EOF'
{"displayName": "SalesETL_Gen2CICD", "includeSchedule": true}
EOF

# Execute save-as
RESPONSE=$(az rest --method post \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows/$GEN1_ID/saveAsNativeArtifact" \
  --headers "Content-Type=application/json" \
  --body @/tmp/save-as-body.json)

# Check result
echo "$RESPONSE" | jq '{
  newId: .artifactMetadata.objectId,
  state: .artifactMetadata.provisionState,
  errors: .errors
}'
示例 3:租户范围的管理员扫描

提示词:“显示整个租户中的所有 Gen1 数据流”

Agent 响应:

# Requires Fabric administrator role
ALL_DFS=$(az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/admin/dataflows" -o json)

# Gen1 dataflows have a modelUrl
echo "$ALL_DFS" | jq '[.value[] | select(.modelUrl != null and .modelUrl != "") |
  {id: .objectId, name: .name, workspace: .workspaceId, 
   owner: .configuredBy, storage: .modelUrl}]'

评论

支持 Markdown