← Files Power BI DesktopARCHIVED FILE

scripts/New-PowerBILiveDependencyGraph.ps1

3.72 KB · Oct 2, 2026 · 00:32 UTC

↓ Download file

param(
    [string]$Server,
    [string]$OutputPath,
    [switch]$Json,
    [switch]$Mermaid
)

$ErrorActionPreference = 'Stop'

$catalogScript = Join-Path $PSScriptRoot 'New-PowerBILiveMetricCatalog.ps1'
$catalog = & $catalogScript -Server $Server -Json | ConvertFrom-Json
$metrics = @($catalog.metrics)

$metricByName = @{}
foreach ($metric in $metrics) {
    $metricByName[$metric.name.ToLowerInvariant()] = $metric
}

$edgeList = New-Object System.Collections.Generic.List[object]
$edgeKeys = @{}
foreach ($metric in $metrics) {
    foreach ($match in [regex]::Matches($metric.expression, '\[(?<name>[^\]]+)\]')) {
        $targetName = $match.Groups['name'].Value.Trim()
        if ($targetName -and $targetName -ne $metric.name -and $metricByName.ContainsKey($targetName.ToLowerInvariant())) {
            $edgeKey = ('{0}->{1}' -f $metric.name.ToLowerInvariant(), $targetName.ToLowerInvariant())
            if ($edgeKeys.ContainsKey($edgeKey)) { continue }
            $edgeKeys[$edgeKey] = $true
            $target = $metricByName[$targetName.ToLowerInvariant()]
            $edgeList.Add([pscustomobject]@{
                from = $metric.name
                to = $targetName
                fromId = $metric.id
                toId = $target.id
                source = $metric.source
            })
        }
    }
}

$edges = @($edgeList.ToArray())
$nodes = @(foreach ($metric in $metrics) {
    $incoming = @($edges | Where-Object { $_.to -eq $metric.name }).Count
    $outgoing = @($edges | Where-Object { $_.from -eq $metric.name }).Count
    [pscustomobject]@{
        id = $metric.id
        name = $metric.name
        table = $metric.table
        riskLevel = $metric.riskLevel
        incoming = $incoming
        outgoing = $outgoing
        hubScore = $incoming + $outgoing
    }
})

$graph = [pscustomobject]@{
    schema = 'codex.powerbi.liveDependencyGraph.v1'
    server = $catalog.server
    generated = (Get-Date).ToString('s')
    nodeCount = $nodes.Count
    edgeCount = $edges.Count
    hubMetrics = @($nodes | Sort-Object -Property hubScore -Descending | Select-Object -First 20)
    nodes = @($nodes)
    edges = @($edges)
}

if ($Json) {
    $jsonText = $graph | ConvertTo-Json -Depth 10
    if ($OutputPath) { Set-Content -LiteralPath $OutputPath -Value $jsonText -Encoding UTF8 }
    $jsonText
    return
}

if ($Mermaid) {
    $lines = New-Object System.Collections.Generic.List[string]
    $lines.Add('flowchart LR')
    foreach ($node in $nodes) {
        $safeId = $node.id -replace '[^A-Za-z0-9_]', '_'
        $label = $node.name.Replace('"', "'")
        $lines.Add(('  {0}["{1}"]' -f $safeId, $label))
    }
    foreach ($edge in $edges) {
        $from = $edge.fromId -replace '[^A-Za-z0-9_]', '_'
        $to = $edge.toId -replace '[^A-Za-z0-9_]', '_'
        $lines.Add(('  {0} --> {1}' -f $from, $to))
    }
    $content = ($lines -join [Environment]::NewLine) + [Environment]::NewLine
    if ($OutputPath) { Set-Content -LiteralPath $OutputPath -Value $content -Encoding UTF8 }
    $content
    return
}

$md = New-Object System.Collections.Generic.List[string]
$md.Add('# Power BI Live Dependency Graph')
$md.Add('')
$md.Add(('Server: `{0}`' -f $graph.server))
$md.Add(('Metrics: {0}' -f $graph.nodeCount))
$md.Add(('Dependencies: {0}' -f $graph.edgeCount))
$md.Add('')
$md.Add('## Top Hub Metrics')
$md.Add('')
foreach ($node in $graph.hubMetrics) {
    $md.Add(('- `{0}`: incoming {1}, outgoing {2}, risk {3}' -f $node.name, $node.incoming, $node.outgoing, $node.riskLevel))
}
$content = ($md -join [Environment]::NewLine) + [Environment]::NewLine
if ($OutputPath) { Set-Content -LiteralPath $OutputPath -Value $content -Encoding UTF8 }
$content

SHA-256: dc1fa4e3dd8ae181a0c2fa2b05325e65ab9b241715f984b6eaa0fb5722780bfa