Public/Get-GraphParity.ps1
|
function Get-GraphParity { <# .SYNOPSIS Reports whether a Microsoft Graph REST endpoint has a matching PowerShell SDK cmdlet, and in which API version(s) the endpoint itself exists. .DESCRIPTION Get-GraphMapping answers "what does this cmdlet/endpoint map to". Get-GraphParity answers a different question: "does the Microsoft Graph API even have a cmdlet for this endpoint yet, in v1.0 and/or beta?". It cross-references the official Graph OpenAPI surface (docs/OpenApiInfo/v1.0 and docs/OpenApiInfo/beta from microsoftgraph/msgraph-sdk-powershell) with the GraphShell command catalog, using data/graph-parity-presence.json and data/graph-parity-module-hints.json produced by scripts/sync-graph-openapi-parity.ps1. Paths are compared using the same normalization GraphShell uses everywhere (path parameters collapsed to "{id}", OData action/function namespace and "$ref"/"$count"/ "$value" suffixes stripped), not exact string matching, so equivalent operations spelled differently across sources are correctly related. See ConvertTo-GraphNormalizedPath. Each result reports one of four states: - SdkAndOpenApi: a cmdlet exists and the endpoint is present in the Graph OpenAPI spec. - SdkOnly: a cmdlet exists in the catalog, but GraphShell found no matching OpenAPI operation (the two official sources disagree; treat as informational, not an error). - OpenApiOnly: the endpoint exists in the Graph API, but the PowerShell SDK has no cmdlet for it yet. When the endpoint has no path parameters, an Invoke-MgGraphRequest equivalent is included so you can still call it using only Microsoft.Graph.Authentication. - NotFound: GraphShell has no data for this endpoint in either source (not returned; a warning is shown instead). Accepts either direction: -Endpoint checks a REST path directly, and -Cmdlet resolves a Microsoft Graph SDK cmdlet name to its endpoint(s) first (reusing the same Resolve-GraphCmdletMapping engine behind Get-GraphMapping -Cmdlet), then reports parity for every endpoint that cmdlet maps to. .PARAMETER Endpoint A Microsoft Graph REST endpoint/path, for example "/admin/teams/userConfigurations" or "/users". Accepts the Endpoint property from Get-GraphMapping over the pipeline. .PARAMETER Method Restrict the result to a single HTTP method (GET, POST, PATCH, PUT, DELETE) when used with -Endpoint. When omitted, every method known for the endpoint (from either source) is returned. .PARAMETER Cmdlet A Microsoft Graph PowerShell SDK cmdlet name, for example "Get-MgUser". Accepts the Cmdlet property from Get-GraphMapping over the pipeline. Reports parity for every endpoint the cmdlet maps to. .EXAMPLE Get-GraphParity -Endpoint "/admin/teams/userConfigurations" Shows that the endpoint exists in the Graph API but has no matching cmdlet, together with a ready-to-use Invoke-MgGraphRequest equivalent. .EXAMPLE Get-GraphMapping -Cmdlet Get-MgUser | Get-GraphParity Confirms that a cmdlet you already know about is backed by a real, currently documented Graph API operation. .EXAMPLE Get-GraphParity -Cmdlet "Get-MgUser" Same result as the previous example, without needing Get-GraphMapping first. .OUTPUTS GraphShell.Parity #> [CmdletBinding(DefaultParameterSetName = 'Endpoint')] [OutputType('GraphShell.Parity')] param( [Parameter(Mandatory, ParameterSetName = 'Endpoint', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('Uri')] [ValidateNotNullOrEmpty()] [string]$Endpoint, [Parameter(ParameterSetName = 'Endpoint', ValueFromPipelineByPropertyName)] [ValidateSet('GET', 'POST', 'PATCH', 'PUT', 'DELETE')] [string]$Method, [Parameter(Mandatory, ParameterSetName = 'Cmdlet', Position = 0, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string]$Cmdlet ) process { $parityIndex = Get-GraphParityIndex if (-not $parityIndex) { Write-Warning "GraphShell parity data is not available in this installation. Run scripts/sync-graph-openapi-parity.ps1, or update GraphShell to a version that includes it." return } $results = [System.Collections.Generic.List[object]]::new() if ($PSCmdlet.ParameterSetName -eq 'Cmdlet') { $mappings = Resolve-GraphCmdletMapping -Cmdlet $Cmdlet -RenameIndex (Get-GraphRenameIndex) if (-not $mappings -or $mappings.Count -eq 0) { Write-Warning "GraphShell found no catalog entry for cmdlet '$Cmdlet'. Check the name, or try Get-GraphMapping -Cmdlet to see how it is spelled in the catalog." return } $normalizedPaths = [System.Collections.Generic.List[string]]::new() $seenPaths = [System.Collections.Generic.HashSet[string]]::new() foreach ($mapping in $mappings) { $normalizedPath = ConvertTo-GraphNormalizedPath -Path $mapping.Endpoint if ($normalizedPath -and $seenPaths.Add($normalizedPath)) { $normalizedPaths.Add($normalizedPath) } } foreach ($normalizedPath in $normalizedPaths) { $results.AddRange([object[]](Resolve-GraphParityForEndpoint -NormalizedPath $normalizedPath -ParityIndex $parityIndex)) } if ($results.Count -eq 0) { Write-Warning "GraphShell has no Graph API parity data for any endpoint mapped to cmdlet '$Cmdlet'." return } return $results.ToArray() } $normalizedPath = ConvertTo-GraphNormalizedPath -Path $Endpoint if (-not $normalizedPath) { Write-Warning "Get-GraphParity needs a non-empty -Endpoint." return } $results.AddRange([object[]](Resolve-GraphParityForEndpoint -NormalizedPath $normalizedPath -Method $Method -ParityIndex $parityIndex)) if ($results.Count -eq 0) { Write-Warning "GraphShell has no Graph API or cmdlet data for endpoint '$Endpoint'. Check the path, or specify -Method." return } return $results.ToArray() } } |