From 8ddd2b74dcca2e11b1d98b4ee677efe6fd27baff Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Tue, 4 Aug 2026 15:29:29 -0700 Subject: [PATCH 01/11] fix(wrapper-generator): map numeric parameter types by OpenAPI format Graph declares Edm.Int32/Int64 as "number" with the real type in the format; mapping by type alone emitted double? against Kiota's int? and did not compile. An explicit format now decides the CLR type, mirroring Kiota's own mapping. --- .../SchemaPropertiesTests.cs | 9 +++++++++ tools/WrapperGenerator/SchemaProperties.cs | 20 +++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs b/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs index 5ee8eef3c3..7ac2b68961 100644 --- a/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs +++ b/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs @@ -87,6 +87,12 @@ public void MapsNumericFormatsWithoutDataLoss() ["sizeInBytes"] = Scalar(JsonSchemaType.Integer, format: "int64"), // values > 2^31 must survive ["retryCount"] = Scalar(JsonSchemaType.Integer, format: "int32"), ["plainCount"] = Scalar(JsonSchemaType.Integer), + // Graph's docs declare Edm.Int32/Int64 as type "number" with the format carrying + // the real type (mailFolder.childFolderCount, messageRule.sequence). The format + // must win or the parameter type contradicts the Kiota model and won't compile. + ["childFolderCount"] = Scalar(JsonSchemaType.Number, format: "int32"), + ["quotaUsed"] = Scalar(JsonSchemaType.Number, format: "int64"), + ["confidence"] = Scalar(JsonSchemaType.Number, format: "float"), }, }; @@ -96,6 +102,9 @@ public void MapsNumericFormatsWithoutDataLoss() Assert.Equal("long", props.Single(p => p.OpenApiName == "sizeInBytes").PsTypeName); Assert.Equal("int", props.Single(p => p.OpenApiName == "retryCount").PsTypeName); Assert.Equal("int", props.Single(p => p.OpenApiName == "plainCount").PsTypeName); + Assert.Equal("int", props.Single(p => p.OpenApiName == "childFolderCount").PsTypeName); + Assert.Equal("long", props.Single(p => p.OpenApiName == "quotaUsed").PsTypeName); + Assert.Equal("float", props.Single(p => p.OpenApiName == "confidence").PsTypeName); } [Fact] diff --git a/tools/WrapperGenerator/SchemaProperties.cs b/tools/WrapperGenerator/SchemaProperties.cs index 59269c8c9e..08fe5d4b3e 100644 --- a/tools/WrapperGenerator/SchemaProperties.cs +++ b/tools/WrapperGenerator/SchemaProperties.cs @@ -67,16 +67,24 @@ public static bool HasPasswordProfile(IOpenApiSchema schema) _ => false, }; - // Numeric mapping follows the OpenAPI format so values survive the round trip: an int64 - // property must not truncate to int (overflow above ~2.1 billion) and a number property - // must not lose its fraction to integer truncation. + // Numeric mapping: when a format is present it decides the CLR type, mirroring Kiota's + // own mapping, so a wrapper parameter always matches the Kiota model property it is + // assigned to. Graph's docs declare Edm.Int32 as "type: number, format: int32" — going by + // the type alone would emit double? against Kiota's int? and not compile. Without a + // format, integer stays int and number stays double (fraction and 64-bit safety). private static string MapPsType(IOpenApiSchema schema) => (schema.Type & ~JsonSchemaType.Null) switch { JsonSchemaType.String => "string", JsonSchemaType.Boolean => "bool", - JsonSchemaType.Integer when string.Equals(schema.Format, "int64", StringComparison.OrdinalIgnoreCase) => "long", - JsonSchemaType.Integer => "int", - JsonSchemaType.Number => "double", + JsonSchemaType.Integer or JsonSchemaType.Number => schema.Format?.ToLowerInvariant() switch + { + "int64" => "long", + "int32" => "int", + "float" => "float", + "double" => "double", + "decimal" => "decimal", + _ => (schema.Type & ~JsonSchemaType.Null) == JsonSchemaType.Integer ? "int" : "double", + }, _ => "string", }; From ca215f3771f981c774d5bd3b5f4092c174676b73 Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Mon, 3 Aug 2026 15:39:36 -0700 Subject: [PATCH 02/11] fix(wrapper-generator): correct four singularization words found by oracle audit Auditing every v1.0 GET command in MgCommandMetadata.json against the singularizer surfaced four words where the rules disagree with shipped cmdlet names: Cookies -> "Cooky" (ships as ...HostCookie), Skus kept as-is (ships as Get-MgSubscribedSku), Dns -> "Dn" (ships as Get-MgDomainVerificationDnsRecord), Ios -> "Io" (ships as Get-MgDeviceAppManagementIosManagedAppProtection). Adds two irregulars and two invariants, each with a pinned test, and refreshes the README test count. 82 tests passing. Full-inventory match after fix: 796 of 870 noun segments; the remaining 74 are action/function segments and AutoRest hand renames, tracked separately. --- tools/WrapperGenerator.Tests/NamingTests.cs | 10 ++++++++-- tools/WrapperGenerator/README.md | 2 +- tools/WrapperGenerator/Singularizer.cs | 10 +++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tools/WrapperGenerator.Tests/NamingTests.cs b/tools/WrapperGenerator.Tests/NamingTests.cs index c466606d90..902a4568a1 100644 --- a/tools/WrapperGenerator.Tests/NamingTests.cs +++ b/tools/WrapperGenerator.Tests/NamingTests.cs @@ -29,11 +29,17 @@ public sealed class SingularizerTests [InlineData("Plans", "Plan")] [InlineData("Settings", "Setting")] [InlineData("Licenses", "License")] - // irregulars (Get-MgDriveItemChild, Get-MgUserPerson) + // irregulars (Get-MgDriveItemChild, Get-MgUserPerson, + // Get-MgSecurityThreatIntelligenceHostCookie, Get-MgSubscribedSku) [InlineData("Children", "Child")] [InlineData("People", "Person")] - // invariants (Get-MgUserSettingWindows) + [InlineData("Cookies", "Cookie")] + [InlineData("Skus", "Sku")] + // invariants (Get-MgUserSettingWindows, Get-MgDomainVerificationDnsRecord, + // Get-MgDeviceAppManagementIosManagedAppProtection) [InlineData("Windows", "Windows")] + [InlineData("Dns", "Dns")] + [InlineData("Ios", "Ios")] // acronyms are never plural forms [InlineData("OS", "OS")] public void SingularizesWords(string word, string expected) diff --git a/tools/WrapperGenerator/README.md b/tools/WrapperGenerator/README.md index aa348a69d0..185f50236f 100644 --- a/tools/WrapperGenerator/README.md +++ b/tools/WrapperGenerator/README.md @@ -157,7 +157,7 @@ dotnet run --project tools/WrapperGenerator -- ` ```powershell # 1. Naming rules pinned to published Microsoft.Graph names (69 tests) dotnet test tools/WrapperGenerator.Tests -# => Passed! - Failed: 0, Passed: 69, Total: 69 +# => Passed! - Failed: 0, Passed: 82, Total: 82 # 2. Parity gate: generate, then check every cmdlet name against Graph's own command inventory .\tools\Compare-WrapperCmdletNames.ps1 -GeneratedPath diff --git a/tools/WrapperGenerator/Singularizer.cs b/tools/WrapperGenerator/Singularizer.cs index c00957ecc8..ab67a0aa41 100644 --- a/tools/WrapperGenerator/Singularizer.cs +++ b/tools/WrapperGenerator/Singularizer.cs @@ -18,17 +18,25 @@ namespace WrapperGenerator; public static partial class Singularizer { // Irregular plurals the SDK singularizes: Get-MgDriveItemChild, Get-MgUserPerson. + // "Cookies" would hit the ies-rule ("Cooky") but ships as Get-MgSecurityThreatIntelligenceHostCookie; + // "Skus" would hit the us-guard (stay put) but ships as Get-MgSubscribedSku. private static readonly Dictionary Irregulars = new(StringComparer.Ordinal) { ["Children"] = "Child", ["People"] = "Person", + ["Cookies"] = "Cookie", + ["Skus"] = "Sku", }; // Words that end in "s" but are not plurals. The SDK keeps them as-is: - // /users/{id}/settings/windows ships as Get-MgUserSettingWindows. + // /users/{id}/settings/windows ships as Get-MgUserSettingWindows, verificationDnsRecords + // as Get-MgDomainVerificationDnsRecord, iosManagedAppProtections as + // Get-MgDeviceAppManagementIosManagedAppProtection. private static readonly HashSet Invariants = new(StringComparer.Ordinal) { "Windows", + "Dns", + "Ios", }; // Splits Pascal or camel text into words. Handles acronym runs ("OS" in "MacOSDmgApp"), From c4d854594484a759a38e104cd6064c7f1fb7bdb5 Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Tue, 4 Aug 2026 15:29:20 -0700 Subject: [PATCH 03/11] fix(wrapper-generator): correct HostWhoi name, add Statistics invariant, start edge-case catalog Only 2 of 30 shipped whois-family commands truncate "Whois" to "Whoi"; per review decision the generator emits the corrected ...HostWhois (no alias for the old name), and the parity gate reports it as [CORRECTED] instead of failing. "Statistics" joins the invariants, found via the DEVX Humanizer exception list. edge-cases/naming-edge-cases.md starts the per-class catalog of naming defects. 88 tests passing. --- tools/Compare-WrapperCmdletNames.ps1 | 35 ++++- tools/WrapperGenerator.Tests/NamingTests.cs | 30 +++- tools/WrapperGenerator/README.md | 8 +- tools/WrapperGenerator/Singularizer.cs | 8 +- .../edge-cases/naming-edge-cases.md | 138 ++++++++++++++++++ 5 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 tools/WrapperGenerator/edge-cases/naming-edge-cases.md diff --git a/tools/Compare-WrapperCmdletNames.ps1 b/tools/Compare-WrapperCmdletNames.ps1 index fcf8c7a28c..e06f24538c 100644 --- a/tools/Compare-WrapperCmdletNames.ps1 +++ b/tools/Compare-WrapperCmdletNames.ps1 @@ -12,6 +12,11 @@ Method+Uri -> Command inventory in MgCommandMetadata.json, and reports whether t emitted [Cmdlet(...)] name matches what the oracle says the published SDK calls that operation. +A small set of published names are known AutoRest defects the generator deliberately +corrects instead of reproducing (tools/WrapperGenerator/edge-cases/naming-edge-cases.md +is the catalog). Those are matched against the $deliberateCorrections table below and +reported as [CORRECTED] rather than [MISMATCH]; they do not fail the gate. + Dispatcher cmdlets (the paired-GET public cmdlet that only forwards to its internal _List/_Get siblings via InvokeCommand.InvokeScript - see CmdletEmitter.EmitGetDispatcher) contain no direct Graph call, so there is nothing to reconstruct from their source; they @@ -126,6 +131,17 @@ function Get-ModuleApiVersion { return $null } +# Published names the generator deliberately corrects instead of reproducing. Each entry maps +# the shipped (wrong) command to the corrected one the generator emits, and must have a matching +# entry in tools/WrapperGenerator/edge-cases/naming-edge-cases.md and a pinned naming test. The +# gate reports these as [CORRECTED] instead of [MISMATCH] and does not fail on them. +$deliberateCorrections = @{ + # AutoRest inflected the trailing /whois segment to "Whoi"; the other 28 whois-family + # cmdlets (whoisRecords, whoisHistoryRecords) all keep "Whois". + 'Get-MgSecurityThreatIntelligenceHostWhoi' = 'Get-MgSecurityThreatIntelligenceHostWhois' + 'Get-MgBetaSecurityThreatIntelligenceHostWhoi' = 'Get-MgBetaSecurityThreatIntelligenceHostWhois' +} + Write-Host "Loading oracle from $OraclePath ..." $oracle = Get-Content -Path $OraclePath -Raw | ConvertFrom-Json @@ -174,6 +190,7 @@ $totalMatched = 0 $totalMismatches = 0 $totalDispatchers = 0 $totalUnparseable = 0 +$totalCorrected = 0 foreach ($module in $modules | Sort-Object Name) { $files = Get-ChildItem -Path $module.Path -Filter '*.g.cs' -File | Sort-Object Name @@ -182,7 +199,9 @@ foreach ($module in $modules | Sort-Object Name) { $moduleMatched = 0 $moduleDispatchers = 0 $moduleUnparseable = 0 + $moduleCorrected = 0 $moduleSkips = @() + $moduleCorrections = @() $moduleProblems = @() foreach ($file in $files) { @@ -238,16 +257,25 @@ foreach ($module in $modules | Sort-Object Name) { $moduleMatched++ } else { - $moduleProblems += " [MISMATCH] $($file.Name): generated '$expectedCommand', oracle says '$($candidates | Select-Object -First 1)' for $method $normalizedUri." + $oracleCommand = $candidates | Select-Object -First 1 + if ($deliberateCorrections[$oracleCommand] -eq $expectedCommand) { + $moduleCorrected++ + $moduleCorrections += " [CORRECTED] $($file.Name): oracle ships '$oracleCommand'; generator deliberately emits '$expectedCommand' (see tools/WrapperGenerator/edge-cases/naming-edge-cases.md)." + } + else { + $moduleProblems += " [MISMATCH] $($file.Name): generated '$expectedCommand', oracle says '$oracleCommand' for $method $normalizedUri." + } } } $status = if ($moduleJoinable -eq 0) { 'n/a' } else { "$moduleMatched of $moduleJoinable" } $dispatcherNote = if ($moduleDispatchers -gt 0) { " (+$moduleDispatchers dispatcher cmdlet(s), no direct call to verify)" } else { '' } $castNote = if ($moduleUnparseable -gt 0) { " (+$moduleUnparseable cast cmdlet(s) skipped, not generated end to end yet)" } else { '' } + $correctedNote = if ($moduleCorrected -gt 0) { " (+$moduleCorrected deliberately corrected name(s))" } else { '' } $versionNote = if ($apiVersion) { " [$apiVersion]" } else { ' [ApiVersion unknown - searched all versions]' } - Write-Host "$($module.Name)$($versionNote): $status cmdlets match the oracle$dispatcherNote$castNote" + Write-Host "$($module.Name)$($versionNote): $status cmdlets match the oracle$dispatcherNote$castNote$correctedNote" foreach ($line in $moduleSkips) { Write-Host $line -ForegroundColor DarkYellow } + foreach ($line in $moduleCorrections) { Write-Host $line -ForegroundColor DarkCyan } foreach ($line in $moduleProblems) { Write-Host $line -ForegroundColor Yellow } $totalJoinable += $moduleJoinable @@ -255,10 +283,11 @@ foreach ($module in $modules | Sort-Object Name) { $totalMismatches += $moduleProblems.Count $totalDispatchers += $moduleDispatchers $totalUnparseable += $moduleUnparseable + $totalCorrected += $moduleCorrected } Write-Host '' -Write-Host "TOTAL: $totalMatched of $totalJoinable cmdlets match the oracle across $($modules.Count) module(s) (+$totalDispatchers dispatcher cmdlet(s) skipped, +$totalUnparseable cast cmdlet(s) skipped)." +Write-Host "TOTAL: $totalMatched of $totalJoinable cmdlets match the oracle across $($modules.Count) module(s) (+$totalDispatchers dispatcher cmdlet(s) skipped, +$totalUnparseable cast cmdlet(s) skipped, +$totalCorrected deliberately corrected)." if ($totalMismatches -gt 0) { exit 1 diff --git a/tools/WrapperGenerator.Tests/NamingTests.cs b/tools/WrapperGenerator.Tests/NamingTests.cs index 902a4568a1..66c84ca38c 100644 --- a/tools/WrapperGenerator.Tests/NamingTests.cs +++ b/tools/WrapperGenerator.Tests/NamingTests.cs @@ -24,6 +24,11 @@ public sealed class SingularizerTests [InlineData("Access", "Access")] [InlineData("Status", "Status")] [InlineData("Analysis", "Analysis")] + // "Whois" also hits the is-guard — a deliberate correction, not a parity pin: the SDK + // ships Get-MgSecurityThreatIntelligenceHostWhoi (AutoRest inflected the trailing + // "whois" segment) while its 28 whoisRecords/whoisHistoryRecords siblings keep "Whois". + // See edge-cases/naming-edge-cases.md. + [InlineData("Whois", "Whois")] // plain s [InlineData("Messages", "Message")] [InlineData("Plans", "Plan")] @@ -36,10 +41,12 @@ public sealed class SingularizerTests [InlineData("Cookies", "Cookie")] [InlineData("Skus", "Sku")] // invariants (Get-MgUserSettingWindows, Get-MgDomainVerificationDnsRecord, - // Get-MgDeviceAppManagementIosManagedAppProtection) + // Get-MgDeviceAppManagementIosManagedAppProtection, + // Get-MgSecurityCaseEdiscoveryCaseSearchLastEstimateStatisticsOperation) [InlineData("Windows", "Windows")] [InlineData("Dns", "Dns")] [InlineData("Ios", "Ios")] + [InlineData("Statistics", "Statistics")] // acronyms are never plural forms [InlineData("OS", "OS")] public void SingularizesWords(string word, string expected) @@ -60,6 +67,8 @@ public void SingularizesWords(string word, string expected) [InlineData("OnPremisesSynchronization", "OnPremiseSynchronization")] // version tag: Get-MgSecurityAlertV2 [InlineData("Alerts_v2", "AlertV2")] + // interior "Whois" survives per-word inflection (Get-MgSecurityThreatIntelligenceWhoisHistoryRecord) + [InlineData("WhoisHistoryRecords", "WhoisHistoryRecord")] public void SingularizesSegments(string segment, string expected) { Assert.Equal(expected, Singularizer.SingularizeSegment(segment)); @@ -86,6 +95,9 @@ private static CmdletNaming Resolve(string method, string path) => [InlineData("GET", "/identity/conditionalAccess/policies/{conditionalAccessPolicy-id}", "Get", "MgIdentityConditionalAccessPolicy")] [InlineData("GET", "/planner/plans", "Get", "MgPlannerPlan")] [InlineData("GET", "/security/alerts_v2", "Get", "MgSecurityAlertV2")] + [InlineData("GET", "/security/threatIntelligence/whoisRecords/{whoisRecord-id}", "Get", "MgSecurityThreatIntelligenceWhoisRecord")] + // interior "Statistics" survives per-word inflection (invariant found via the DEVX API's Humanizer exception list) + [InlineData("GET", "/security/cases/ediscoveryCases/{ediscoveryCase-id}/searches/{ediscoverySearch-id}/lastEstimateStatisticsOperation", "Get", "MgSecurityCaseEdiscoveryCaseSearchLastEstimateStatisticsOperation")] [InlineData("PATCH", "/admin/reportSettings", "Update", "MgAdminReportSetting")] [InlineData("GET", "/schemaExtensions", "Get", "MgSchemaExtension")] [InlineData("GET", "/domains/{domain-id}", "Get", "MgDomain")] @@ -109,6 +121,22 @@ public void ResolvesPublishedSdkNames(string method, string path, string expecte Assert.Equal($"{expectedVerb}{expectedNoun}Command", naming.ClassName); } + [Theory] + // Deliberate corrections: the published name is wrong (an AutoRest naming defect) and the + // generator emits the corrected name instead of reproducing it. Every entry here must have + // an edge-cases/naming-edge-cases.md entry and a matching row in + // Compare-WrapperCmdletNames.ps1's $deliberateCorrections table, so the parity gate + // reports it as [CORRECTED], not a failure. + // Shipped: Get-MgSecurityThreatIntelligenceHostWhoi — the only whois-family cmdlet (of 30) + // where "Whois" was inflected to "Whoi". + [InlineData("GET", "/security/threatIntelligence/hosts/{host-id}/whois", "Get", "MgSecurityThreatIntelligenceHostWhois")] + public void AppliesDeliberateNameCorrections(string method, string path, string expectedVerb, string expectedNoun) + { + var naming = Resolve(method, path); + Assert.Equal(expectedVerb, naming.VerbName); + Assert.Equal(expectedNoun, naming.Noun); + } + [Theory] // The builder expression is the Kiota request-builder chain the emitted cmdlet calls // (client..GetAsync()). A property per fixed segment, an indexer per path parameter. diff --git a/tools/WrapperGenerator/README.md b/tools/WrapperGenerator/README.md index 185f50236f..8943b4bb30 100644 --- a/tools/WrapperGenerator/README.md +++ b/tools/WrapperGenerator/README.md @@ -6,7 +6,7 @@ Generates the PowerShell **cmdlets** for the Microsoft Graph SDK from Graph's Op The Microsoft Graph PowerShell SDK is thousands of cmdlets, and customers have scripts that depend on their exact names — `Get-MgUserMessage`, not `Get-MgUsersMessages`. Those names follow conventions, but the conventions are fiddly (singular nouns, a `Mg` prefix, a handful of hand-tuned exceptions), and the SDK's current generator (AutoRest) has quietly dropped cmdlets when names collided. -This tool regenerates those cmdlets from the same OpenAPI description **while reproducing the published names exactly**, so a regenerated module is a drop-in replacement. Because name parity is the hard part, most of the tool is a naming engine; the rest is a straightforward C# code emitter. +This tool regenerates those cmdlets from the same OpenAPI description **while reproducing the published names exactly**, so a regenerated module is a drop-in replacement. Because name parity is the hard part, most of the tool is a naming engine; the rest is a straightforward C# code emitter. The one exception to "exactly": a handful of published names are AutoRest naming defects (e.g. `Get-MgSecurityThreatIntelligenceHostWhoi`, where "Whois" lost its `s`) that the generator deliberately corrects — each is pinned by a test, allowlisted in the parity gate, and documented in the edge-case catalog ([edge-cases/naming-edge-cases.md](edge-cases/naming-edge-cases.md), one file per class of issue). ## What it produces @@ -155,16 +155,16 @@ dotnet run --project tools/WrapperGenerator -- ` **Test** — two layers: ```powershell -# 1. Naming rules pinned to published Microsoft.Graph names (69 tests) +# 1. Naming rules pinned to published Microsoft.Graph names dotnet test tools/WrapperGenerator.Tests -# => Passed! - Failed: 0, Passed: 82, Total: 82 +# => Passed! - Failed: 0, Passed: 88, Total: 88 # 2. Parity gate: generate, then check every cmdlet name against Graph's own command inventory .\tools\Compare-WrapperCmdletNames.ps1 -GeneratedPath # => Mail [v1.0]: 4 of 4 cmdlets match the oracle ... EXIT CODE: 0 ``` -The unit tests guard the naming rules (their expected values are real published names from `src/Authentication/Authentication/custom/common/MgCommandMetadata.json`). The parity gate checks actual generated output against that same inventory. There is **no** test yet that the generated cmdlets *compile* — that needs step 1's client to compile against. +The unit tests guard the naming rules (their expected values are real published names from `src/Authentication/Authentication/custom/common/MgCommandMetadata.json`). The parity gate checks actual generated output against that same inventory; names on the deliberate-corrections list ([edge-cases/naming-edge-cases.md](edge-cases/naming-edge-cases.md)) are reported as `[CORRECTED]` instead of failing. There is **no** test yet that the generated cmdlets *compile* — that needs step 1's client to compile against. ## Gaps / not done yet diff --git a/tools/WrapperGenerator/Singularizer.cs b/tools/WrapperGenerator/Singularizer.cs index ab67a0aa41..05b0710b86 100644 --- a/tools/WrapperGenerator/Singularizer.cs +++ b/tools/WrapperGenerator/Singularizer.cs @@ -31,12 +31,15 @@ public static partial class Singularizer // Words that end in "s" but are not plurals. The SDK keeps them as-is: // /users/{id}/settings/windows ships as Get-MgUserSettingWindows, verificationDnsRecords // as Get-MgDomainVerificationDnsRecord, iosManagedAppProtections as - // Get-MgDeviceAppManagementIosManagedAppProtection. + // Get-MgDeviceAppManagementIosManagedAppProtection, lastEstimateStatisticsOperation as + // Get-MgSecurityCaseEdiscoveryCaseSearchLastEstimateStatisticsOperation ("Statistics" is + // also on the DEVX API's Humanizer exception list in PowershellFormatter.cs). private static readonly HashSet Invariants = new(StringComparer.Ordinal) { "Windows", "Dns", "Ios", + "Statistics", }; // Splits Pascal or camel text into words. Handles acronym runs ("OS" in "MacOSDmgApp"), @@ -93,7 +96,8 @@ public static string SingularizeWord(string word) if (EndsWithSibilantEs(word)) return word[..^2]; // Businesses -> Business, Mailboxes -> Mailbox if (word.EndsWith("ss", StringComparison.Ordinal) || word.EndsWith("us", StringComparison.Ordinal) || word.EndsWith("is", StringComparison.Ordinal)) - return word; // Access, Status, Analysis stay put + return word; // Access, Status, Analysis stay put; keeping "Whois" is a deliberate + // fix of shipped ...HostWhoi (edge-cases/naming-edge-cases.md) if (word.EndsWith('s')) return word[..^1]; // Messages -> Message, Plans -> Plan return word; diff --git a/tools/WrapperGenerator/edge-cases/naming-edge-cases.md b/tools/WrapperGenerator/edge-cases/naming-edge-cases.md new file mode 100644 index 0000000000..0c70d0a06e --- /dev/null +++ b/tools/WrapperGenerator/edge-cases/naming-edge-cases.md @@ -0,0 +1,138 @@ +# Naming edge cases + +This folder is the wrapper generator's edge-case catalog: one Markdown file per **class** of +issue, each entry written with the same fixed fields so the files stay cheap to maintain and +trivial to convert to JSON for automated processing. This file covers the first class: +**cmdlet-naming defects** — cases where the published Microsoft.Graph name is an artifact of +the previous generator (AutoRest) rather than the name the conventions would produce. + +Two policies govern the entries (agreed 2026-08-03/04, wrapper-generator review + sync): + +- **Obviously wrong published names are corrected, not reproduced.** The shipped SDK is the + baseline, not 100% ground truth. Each correction is a deliberate, documented break from + parity. +- **Corrected names ship without a back-compat alias for the old name.** Documenting the + change here and in the migration guide is the agreed mechanism; the generator does not emit + the wrong name in any form. + +## How to add an entry + +A correction lands as four pieces together: + +1. **Fix** — the naming rule change (or, as with Whois, confirmation that the existing rules + already produce the correct name). +2. **Pinned test** — a row in `AppliesDeliberateNameCorrections` (NamingTests.cs) so the + corrected name cannot regress silently. Parity-preserving edge cases go in the regular + pinned tests instead. +3. **Gate entry** — a row in `$deliberateCorrections` in `tools/Compare-WrapperCmdletNames.ps1` + mapping the shipped name to the corrected one, so the parity gate reports `[CORRECTED]` + instead of failing. +4. **Catalog entry** — a section below using the fixed field template. + +Entry template (keep the field names exact so the file converts cleanly): + +``` +## +- **Class:** +- **Status:** +- **Evidence:** +- **Decision:** +- **Migration impact:** +- **References:** +``` + +## Status summary + +| Case | Class | Status | +|---|---|---| +| `HostWhoi` → `HostWhois` | inflection-defect | corrected | +| operationId preposition truncation | operationid-truncation | structurally-avoided | +| `SkypeForBusiness` subject truncation | operationid-truncation | not-yet-reachable | +| `Cookies`/`Skus`/`Dns`/`Ios`/`Statistics` quirks | inflection-defect | reproduced-for-parity | + +## Whois truncated to Whoi on the host navigation + +- **Class:** inflection-defect +- **Status:** corrected +- **Evidence:** `GET /security/threatIntelligence/hosts/{host-id}/whois` shipped as + `Get-MgSecurityThreatIntelligenceHostWhoi` (v1.0 and beta): AutoRest's inflector treated the + trailing `whois` segment as a plural and stripped the `s`. The shipped SDK is inconsistent + with itself — the other 28 whois-family commands in MgCommandMetadata.json + (`.../whoisRecords`, `.../whoisHistoryRecords`, and their children) all keep **Whois** + intact, e.g. `Get-MgSecurityThreatIntelligenceWhoisRecord`. +- **Decision:** emit `Get-MgSecurityThreatIntelligenceHostWhois` / `Get-MgBetaSecurityThreatIntelligenceHostWhois`. + The singularizer's `is`-guard (the rule that keeps Access/Status/Analysis) already produces + `Whois`, so no rule change was needed — the corrected behavior is pinned rather than coded. +- **Migration impact:** scripts calling `Get-MgSecurityThreatIntelligenceHostWhoi` must add the + trailing `s`; no alias is emitted for the old name. Belongs in the migration guide when the + Security module is generated for real. +- **References:** pinned in `AppliesDeliberateNameCorrections` (NamingTests.cs); gate rows in + `$deliberateCorrections` (Compare-WrapperCmdletNames.ps1). + +## operationId preposition/linking-verb truncation + +- **Class:** operationid-truncation +- **Status:** structurally-avoided +- **Evidence:** AutoRest built cmdlet names from **operationIds** and truncated them at + prepositions and linking verbs, so ids like `...ByRef...` lost everything after the + preposition. The SDK worked around it with hand-written rename directives per affected + command. +- **Decision:** no mitigation needed for path-derived nouns — this generator never reads the + operationId; nouns come from URL path segments (CmdletNaming.cs), so the defect class cannot + occur there. Two watch items: (a) **OData actions/functions** (not yet generated) take their + names from an operationId-like segment (`microsoft.graph.assignLicense`, + `getSkypeForBusiness...`) — when that support lands, word-splitting must not treat + prepositions as truncation points; (b) path segments that legitimately contain prepositions + (`termsAndConditions`) are already pinned — the singularizer inflects per word and keeps the + `And` (`TermAndCondition`). +- **Migration impact:** none today. +- **References:** issue [microsoftgraph/msgraph-sdk-powershell#912](https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/912), + PR [#915](https://github.com/microsoftgraph/msgraph-sdk-powershell/pull/915). + +## SkypeForBusiness subject names + +- **Class:** operationid-truncation +- **Status:** not-yet-reachable +- **Evidence:** historically AutoRest truncated subjects containing `SkypeForBusiness` at the + `For`. The shipped names are correct today + (`Get-MgReportSkypeForBusinessActivityUserDetail`, etc.), so there is nothing to correct — + but every affected endpoint is an OData function + (`/reports/getSkypeForBusinessActivityCounts(period='{period}')`), a shape this generator + does not emit yet. +- **Decision:** when function support is implemented, add pinned tests for the + `SkypeForBusiness` family so the `For` survives word-splitting. +- **Migration impact:** none. +- **References:** [Azure/autorest.powershell#795](https://github.com/Azure/autorest.powershell/issues/795). + +## Inflection quirks reproduced for parity + +- **Class:** inflection-defect +- **Status:** reproduced-for-parity +- **Evidence:** auditing every v1.0 GET in MgCommandMetadata.json against the singularizer + surfaced four words where shipped names disagree with naive inflection rules: `Cookies` → + `Cookie` (not `Cooky`), `Skus` → `Sku` (despite the `us`-guard), and `Dns`/`Ios` kept as-is. + A fifth, `Statistics`, came from cross-checking the DEVX API's Humanizer exception list: + the shipped SDK keeps it intact everywhere, including as an interior word + (`Get-MgSecurityCaseEdiscoveryCaseSearchLastEstimateStatisticsOperation`, + `Get-MgBetaUserActivityStatistics`), where the plain s-drop rule would have produced + `Statistic`. +- **Decision:** these shipped names are *reasonable*, just not what naive rules produce, so the + generator reproduces them via the irregulars/invariants tables in Singularizer.cs. The + README's rule table cites the proving cmdlet for each. +- **Migration impact:** none — these are parity-preserving. +- **References:** commit `a429b5999c`; Singularizer.cs `Irregulars`/`Invariants`; the DEVX + API's Humanizer vocabulary in `OpenAPIService/PowershellFormatter.cs` (private + `microsoftgraph/microsoft-graph-devx-api` repo) — its five entries are `drives→drive`, + `data`, `delta`, `quota` (Humanizer-specific mistakes this rule engine never makes) and + `statistics` (the one that applied here). + +## Watch list + +Cases spotted but deliberately not acted on yet, so they aren't lost: + +- **`usageRights` vs `rights` (beta-only):** the shipped SDK keeps `usageRights` plural + (`Get-MgBetaDeviceUsageRights` for `/devices/{id}/usageRights`) but singularizes bare + `rights` (`Get-MgBetaGroupSiteInformationProtectionSensitivityLabelRight` for + `.../sensitivityLabels/{id}/rights`). Our rules match the bare-`rights` case and would + diverge on `usageRights`. All affected paths are beta; resolve when the beta parity audit + runs. From 695cfe74e1454598fe503662c8fea5406fce3f1e Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Thu, 6 Aug 2026 11:48:19 -0700 Subject: [PATCH 04/11] feat(wrapper-generator): add module packaging and smoke-test scripts Build-WrapperModule.ps1 turns one OpenAPI doc into an importable module (kiota client + wrappers + csproj + dll + PSD1 manifest), reading the Kiota-compatible docs by default with a hard kiota timeout and per-module doc fallback. Test-WrapperModule.ps1 imports each build in a fresh pwsh and verifies exports, worker pairing, and the sessionless NoGraphSession path. All 35 cmdlet-producing v1.0 modules build and pass. --- tools/Build-WrapperModule.ps1 | 228 ++++++++++++++++++++++++++++++++++ tools/Test-WrapperModule.ps1 | 145 +++++++++++++++++++++ 2 files changed, 373 insertions(+) create mode 100644 tools/Build-WrapperModule.ps1 create mode 100644 tools/Test-WrapperModule.ps1 diff --git a/tools/Build-WrapperModule.ps1 b/tools/Build-WrapperModule.ps1 new file mode 100644 index 0000000000..dc67dc464c --- /dev/null +++ b/tools/Build-WrapperModule.ps1 @@ -0,0 +1,228 @@ +<# +.SYNOPSIS +Builds installable wrapper modules end to end: Kiota client + generated cmdlets + compiled +dll + module manifest. + +.DESCRIPTION +For each module name, reproduces the pipeline the Mail spike proved: + + 1. kiota generate -> //src/Client (ApiClient + models) + 2. WrapperGenerator -> //src/Cmdlets (one *.g.cs per cmdlet) + 3. write csproj -> //src/ + 4. dotnet build -> //src/bin//net10.0/ + 5. New-ModuleManifest -> .psd1 next to the dll + +Both generators consume the SAME OpenAPI document, so the wrappers always match the client +they compile against. + +The module is named Microsoft.Graph.Wrapper. so it imports side by side with an +installed official Microsoft.Graph. without collision. + +The manifest exports EVERY cmdlet, including the internal *_Get/*_List workers: the public +Get-* dispatchers forward to the workers by name via InvokeCommand.InvokeScript, so a +manifest that hides the workers breaks dispatch ("term not recognized"). Worker visibility +needs its own dispatch design and is tracked in the module-wiring issue. + +Everything is written under artifacts/ (gitignored); nothing this script produces is +committed. To check cmdlet-name parity for a built module, point the parity gate at its +cmdlets folder: + .\tools\Compare-WrapperCmdletNames.ps1 -GeneratedPath artifacts\wrapper-modules\\src\Cmdlets + +.PARAMETER Module +One or more module names, each matching an OpenAPI doc at //.yml +(e.g. Mail, Calendar, Users.Actions). + +.PARAMETER ApiVersion +v1.0 (default) or beta. + +.PARAMETER SpecRoot +Root folder of the OpenAPI docs. Default: /openApiDocs_KiotaCompat — the Kiota-suitable +conversion (style=Plain, discriminators preserved). The PowerShell-profile docs under +openApiDocs flatten types like microsoft.graph.Dictionary into empty schemas, which kiota +rejects (Search, Identity.SignIns, Identity.Governance, ConfigurationManagement) or hangs on +(Sites). A module missing under SpecRoot falls back to /openApiDocs with a warning. + +.PARAMETER OutputRoot +Root folder for the built modules. Default: /artifacts/wrapper-modules. + +.PARAMETER Configuration +dotnet build configuration. Default: Debug. + +.PARAMETER SkipKiota +Reuse the previously generated client (fast inner loop when only the wrappers changed). + +.EXAMPLE +.\tools\Build-WrapperModule.ps1 -Module Mail + +.EXAMPLE +.\tools\Build-WrapperModule.ps1 -Module Mail,Calendar -ApiVersion v1.0 +#> +[CmdletBinding()] +param( + [Parameter(Mandatory)] + [string[]]$Module, + [ValidateSet('v1.0', 'beta')] + [string]$ApiVersion = 'v1.0', + [string]$SpecRoot, + [string]$OutputRoot, + [string]$Configuration = 'Debug', + [switch]$SkipKiota +) + +$ErrorActionPreference = 'Stop' + +$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path +if (-not $SpecRoot) { $SpecRoot = Join-Path $repoRoot 'openApiDocs_KiotaCompat' } +if (-not $OutputRoot) { $OutputRoot = Join-Path $repoRoot 'artifacts\wrapper-modules' } +$generatorProject = Join-Path $repoRoot 'tools\WrapperGenerator' +$authCsproj = Join-Path $repoRoot 'src\Authentication\Authentication\Microsoft.Graph.Authentication.csproj' + +if (-not (Get-Command kiota -ErrorAction SilentlyContinue)) { + Write-Error "kiota CLI not found on PATH. Install: dotnet tool install --global Microsoft.OpenApi.Kiota" + exit 1 +} + +# Same extraction the parity gate uses: the emitted [Cmdlet(VerbsX.Verb, "Noun")] attribute +# is the source of truth for what the dll will export, without having to load the assembly. +$cmdletAttrPattern = '\[Cmdlet\(Verbs\w+\.(\w+),\s*"((?:\\.|[^"\\])*)"' +function Get-EmittedCmdletNames { + param([string]$CmdletsDir) + Get-ChildItem -Path $CmdletsDir -Filter '*.g.cs' -File | ForEach-Object { + $match = [regex]::Match((Get-Content -Path $_.FullName -Raw), $cmdletAttrPattern) + if ($match.Success) { + "$($match.Groups[1].Value)-$([regex]::Unescape($match.Groups[2].Value))" + } + } +} + +function Build-OneModule { + param([string]$Name) + + $started = Get-Date + $result = [pscustomobject]@{ + Module = $Name; Status = 'FAILED'; FailedAt = ''; CmdletCount = 0; Psd1 = ''; Seconds = 0; Error = '' + } + + try { + $spec = Join-Path $SpecRoot "$ApiVersion\$Name.yml" + if (-not (Test-Path $spec)) { + $fallback = Join-Path $repoRoot "openApiDocs\$ApiVersion\$Name.yml" + if (Test-Path $fallback) { + Write-Warning "$Name has no doc under $SpecRoot; falling back to $fallback" + $spec = $fallback + } + else { $result.FailedAt = 'spec'; $result.Error = "no OpenAPI doc at $spec"; return $result } + } + + $moduleName = "Microsoft.Graph.Wrapper.$Name" + $clientNs = "Microsoft.Graph.PowerShell.$Name.Client" + $srcDir = Join-Path $OutputRoot "$Name\src" + $clientDir = Join-Path $srcDir 'Client' + $cmdletsDir = Join-Path $srcDir 'Cmdlets' + New-Item -ItemType Directory -Force -Path $srcDir | Out-Null + + if (-not $SkipKiota -or -not (Test-Path (Join-Path $clientDir 'ApiClient.cs'))) { + # Run kiota with a hard timeout: it can hang silently on some specs (v1.0 Sites sat + # idle for 35+ minutes with zero CPU), and a hung child must fail this module, not + # stall the whole fan-out. Successful runs take seconds, so 5 minutes is generous. + $kiotaErrLog = Join-Path $srcDir 'kiota-stderr.log' + $kiotaOutLog = Join-Path $srcDir 'kiota-stdout.log' + $kiotaProc = Start-Process kiota -PassThru -NoNewWindow -RedirectStandardError $kiotaErrLog -RedirectStandardOutput $kiotaOutLog -ArgumentList @( + 'generate', '-l', 'CSharp', '-d', $spec, '-c', 'ApiClient', '-n', $clientNs, + '-o', $clientDir, '--clean-output', '--log-level', 'Warning') + if (-not $kiotaProc.WaitForExit(300000)) { + $kiotaProc.Kill() + $result.FailedAt = 'kiota'; $result.Error = 'timed out after 300s (hung, killed)' + return $result + } + if ($kiotaProc.ExitCode -ne 0) { + $result.FailedAt = 'kiota' + $result.Error = (Get-Content -Path $kiotaErrLog -Tail 3 -ErrorAction SilentlyContinue) -join ' | ' + return $result + } + } + + $wrapperOut = & dotnet run --project $generatorProject -- -d $spec -o $cmdletsDir -n $clientNs 2>&1 + if ($LASTEXITCODE -ne 0) { $result.FailedAt = 'wrapper-generator'; $result.Error = ($wrapperOut | Select-Object -Last 3) -join ' | '; return $result } + + # Generated artifact, machine-local by design (absolute reference into this clone). + $csprojPath = Join-Path $srcDir "$moduleName.csproj" + @" + + + + + net10.0 + latest + enable + enable + $moduleName + + true + `$(NoWarn);CS1591 + + + + + + + + + + + + +"@ | Set-Content -Path $csprojPath -Encoding utf8 + + $buildOut = & dotnet build $csprojPath -c $Configuration --nologo -v minimal 2>&1 + if ($LASTEXITCODE -ne 0) { + $result.FailedAt = 'build' + $result.Error = ($buildOut | Where-Object { $_ -match 'error' } | Select-Object -First 3) -join ' | ' + return $result + } + + $cmdlets = @(Get-EmittedCmdletNames -CmdletsDir $cmdletsDir) + if ($cmdlets.Count -eq 0) { $result.FailedAt = 'manifest'; $result.Error = 'no cmdlets emitted'; return $result } + + $binDir = Join-Path $srcDir "bin\$Configuration\net10.0" + $psd1Path = Join-Path $binDir "$moduleName.psd1" + New-ModuleManifest -Path $psd1Path ` + -RootModule "$moduleName.dll" ` + -ModuleVersion '0.1.0' ` + -Author 'Microsoft Graph' -CompanyName 'Microsoft' ` + -Description "Generated Kiota-based wrapper module for $Name ($ApiVersion). Test build - not for release." ` + -CmdletsToExport $cmdlets ` + -FunctionsToExport @() -AliasesToExport @() -VariablesToExport @() + + $result.Status = 'OK' + $result.CmdletCount = $cmdlets.Count + $result.Psd1 = $psd1Path + return $result + } + catch { + if (-not $result.FailedAt) { $result.FailedAt = 'unexpected' } + $result.Error = $_.Exception.Message + return $result + } + finally { + $result.Seconds = [math]::Round(((Get-Date) - $started).TotalSeconds, 1) + } +} + +$results = foreach ($name in $Module) { + Write-Host "=== $name ===" -ForegroundColor Cyan + $r = Build-OneModule -Name $name + if ($r.Status -eq 'OK') { + Write-Host " OK: $($r.CmdletCount) cmdlets -> $($r.Psd1) ($($r.Seconds)s)" -ForegroundColor Green + } + else { + Write-Host " FAILED at $($r.FailedAt): $($r.Error)" -ForegroundColor Yellow + } + $r +} + +Write-Host '' +$results | Format-Table Module, Status, FailedAt, CmdletCount, Seconds -AutoSize | Out-Host + +if ($results.Status -contains 'FAILED') { exit 1 } +exit 0 diff --git a/tools/Test-WrapperModule.ps1 b/tools/Test-WrapperModule.ps1 new file mode 100644 index 0000000000..7460f4f2c6 --- /dev/null +++ b/tools/Test-WrapperModule.ps1 @@ -0,0 +1,145 @@ +<# +.SYNOPSIS +Smoke-tests built wrapper modules the way a user would: Import-Module, inventory the +cmdlets, exercise a dispatcher without a Graph session. + +.DESCRIPTION +Each module is tested in a CHILD pwsh process — a fresh process per module, because +assemblies cannot be unloaded and Import-Module silently no-ops when a same-name module is +already loaded. Checks, per module: + + 1. Import-Module succeeds - the user's first experience + 2. exported cmdlet count == manifest count - nothing silently dropped at load + 3. no orphan workers - every *_Get/*_List worker has its public + dispatcher exported alongside it + 4. one dispatcher invoked with dummy ids and no Graph session: + PASS = NoGraphSession error (the call flowed dispatcher -> worker -> auth path) + FAIL = CommandNotFound (dispatcher->worker forwarding broken: the manifest + visibility trap) or any other unexpected error id + +Modules with no paired list+item GETs have no dispatcher; check 4 reports n/a for them. + +.PARAMETER Module +One or more module names previously built by Build-WrapperModule.ps1. + +.PARAMETER OutputRoot +Root folder the modules were built into. Default: /artifacts/wrapper-modules. + +.PARAMETER Configuration +Build configuration used. Default: Debug. + +.EXAMPLE +.\tools\Test-WrapperModule.ps1 -Module Mail +#> +[CmdletBinding()] +param( + [Parameter(Mandatory)] + [string[]]$Module, + [string]$OutputRoot, + [string]$Configuration = 'Debug' +) + +$ErrorActionPreference = 'Stop' + +$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path +if (-not $OutputRoot) { $OutputRoot = Join-Path $repoRoot 'artifacts\wrapper-modules' } + +function Test-OneModule { + param([string]$Name) + + $moduleName = "Microsoft.Graph.Wrapper.$Name" + $psd1 = Join-Path $OutputRoot "$Name\src\bin\$Configuration\net10.0\$moduleName.psd1" + $result = [pscustomobject]@{ + Module = $Name; Pass = $false; Exported = 0; ManifestCount = 0 + OrphanWorkers = 0; Dispatcher = ''; ErrorId = ''; Detail = '' + } + + if (-not (Test-Path $psd1)) { + $result.Detail = "not built: $psd1 missing (run Build-WrapperModule.ps1 first)" + return $result + } + $result.ManifestCount = (Import-PowerShellDataFile -Path $psd1).CmdletsToExport.Count + + # The child prints exactly one JSON line; everything else it may write is noise. + $inner = @" +`$ErrorActionPreference = 'Stop' +Import-Module '$psd1' +`$cmds = Get-Command -Module '$moduleName' +`$workers = @(`$cmds | Where-Object Name -match '_(Get|List)$') +`$orphans = @(`$workers | Where-Object { `$cmds.Name -notcontains (`$_.Name -replace '_(Get|List)$', '') }) +`$dispatcher = `$cmds | Where-Object { `$_.Name -like 'Get-*' -and `$cmds.Name -contains "`$(`$_.Name)_List" } | Select-Object -First 1 +`$errorId = 'N/A' +if (`$dispatcher) { + `$defaultSet = `$dispatcher.ParameterSets | Where-Object IsDefault | Select-Object -First 1 + `$splat = @{} + foreach (`$p in (`$defaultSet.Parameters | Where-Object { `$_.IsMandatory -and `$_.ParameterType -eq [string] })) { + `$splat[`$p.Name] = 'smoke-test' + } + try { + & `$dispatcher @splat -ErrorAction Stop | Out-Null + `$errorId = 'NO-ERROR' + } + catch { + `$errorId = `$_.FullyQualifiedErrorId + } +} +[pscustomobject]@{ + Exported = `$cmds.Count + OrphanWorkers = `$orphans.Count + Dispatcher = if (`$dispatcher) { `$dispatcher.Name } else { '' } + ErrorId = `$errorId +} | ConvertTo-Json -Compress +"@ + + $encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($inner)) + $output = & pwsh -NoProfile -NonInteractive -EncodedCommand $encoded 2>&1 + if ($LASTEXITCODE -ne 0) { + $result.Detail = "Import-Module failed: $(($output | Select-Object -Last 2) -join ' | ')" + return $result + } + + $json = $output | Where-Object { $_ -match '^\{' } | Select-Object -Last 1 + if (-not $json) { $result.Detail = 'child produced no result'; return $result } + $r = $json | ConvertFrom-Json + + $result.Exported = $r.Exported + $result.OrphanWorkers = $r.OrphanWorkers + $result.Dispatcher = $r.Dispatcher + $result.ErrorId = $r.ErrorId + + if ($r.Exported -ne $result.ManifestCount) { + $result.Detail = "exported $($r.Exported) != manifest $($result.ManifestCount)" + } + elseif ($r.OrphanWorkers -gt 0) { + $result.Detail = "$($r.OrphanWorkers) worker(s) without their dispatcher" + } + elseif ($r.ErrorId -notin @('N/A') -and $r.ErrorId -notlike 'NoGraphSession*') { + $result.Detail = if ($r.ErrorId -like '*CommandNotFound*') { + "dispatcher->worker forwarding broken (manifest visibility trap): $($r.ErrorId)" + } else { + "unexpected error id: $($r.ErrorId)" + } + } + else { + $result.Pass = $true + } + return $result +} + +$results = foreach ($name in $Module) { + Write-Host "=== $name ===" -ForegroundColor Cyan + $r = Test-OneModule -Name $name + if ($r.Pass) { + Write-Host " PASS: $($r.Exported) cmdlets; dispatcher $($r.Dispatcher) -> $($r.ErrorId)" -ForegroundColor Green + } + else { + Write-Host " FAIL: $($r.Detail)" -ForegroundColor Yellow + } + $r +} + +Write-Host '' +$results | Format-Table Module, Pass, Exported, ManifestCount, OrphanWorkers, Dispatcher, ErrorId -AutoSize | Out-Host + +if ($results.Pass -contains $false) { exit 1 } +exit 0 From f2de362c085c41daa79126d76685f7a8a1c5ca52 Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Thu, 6 Aug 2026 11:48:28 -0700 Subject: [PATCH 05/11] fix(wrapper-generator): align emitted code with real kiota client output Compiling all v1.0 modules against freshly generated kiota clients surfaced eight alignment defects, each fixed and pinned by a test: dispatchers re-wrapped worker errors (NoGraphSession was lost); body properties colliding with path ids (published convention: -DeviceId1); bare model types colliding with namespaces and BCL types (now fully qualified, mirroring kiota's move-inside and reserved-name renames at root and in sub-namespaces); collection responses resolved from their own $ref; underscore members (riskEventTypes_v2 -> RiskEventTypesV2); $select/$expand emitted only where declared; re-fetch only where a GET exists; media/content endpoints skipped like $value. --- tools/WrapperGenerator.Tests/EmitterTests.cs | 61 ++++++- .../GenerationServiceRegressionTests.cs | 41 +++++ .../SchemaPropertiesTests.cs | 47 +++++ tools/WrapperGenerator/CmdletEmitter.cs | 115 ++++++++----- .../PowerShellWrapperGenerationService.cs | 162 +++++++++++++++--- tools/WrapperGenerator/SchemaProperties.cs | 38 +++- 6 files changed, 394 insertions(+), 70 deletions(-) diff --git a/tools/WrapperGenerator.Tests/EmitterTests.cs b/tools/WrapperGenerator.Tests/EmitterTests.cs index 12a4edf54e..24e8dc174b 100644 --- a/tools/WrapperGenerator.Tests/EmitterTests.cs +++ b/tools/WrapperGenerator.Tests/EmitterTests.cs @@ -1,10 +1,69 @@ -using WrapperGenerator; +using System.Collections.Generic; +using System.Net.Http; +using WrapperGenerator; using Xunit; namespace WrapperGenerator.Tests; public sealed class EmitterTests { + // A worker's terminating error (e.g. NoGraphSession) surfaces from InvokeScript as a + // RuntimeException; the dispatcher must rethrow the original ErrorRecord, not re-wrap it + // as its own GraphRequestFailed — otherwise every failure loses its identity and the + // "run Connect-MgGraph" guidance never reaches the user. Found by the module smoke test. + [Fact] + public void DispatcherRethrowsTheWorkersOriginalErrorRecord() + { + var list = Naming.Resolve(new OperationInfo(HttpMethod.Get, "/users/{user-id}/messages")); + var item = Naming.Resolve(new OperationInfo(HttpMethod.Get, "/users/{user-id}/messages/{message-id}")); + + var source = CmdletEmitter.EmitGetDispatcher( + list, item, Naming.WithSuffix(list, "_List"), Naming.WithSuffix(item, "_Get"), + new EmitContext("Test.Client"), "Message", "MessageCollectionResponse", + new HashSet(), new HashSet()); + + Assert.Contains("catch (RuntimeException rex) when (rex.ErrorRecord is not null)", source); + Assert.Contains("ThrowTerminatingError(rex.ErrorRecord);", source); + } + + // A collision-renamed property must emit the suffixed PARAMETER but assign the model's + // real property: -DeviceId1 binds, body.DeviceId receives (Update-MgDevice pattern). + [Fact] + public void EmitsSuffixedParameterButAssignsRealModelProperty() + { + var naming = Naming.Resolve(new OperationInfo(HttpMethod.Patch, "/devices/{device-id}")); + var properties = SchemaProperties.ResolveParameterNameCollisions( + new[] { new CmdletProperty("deviceId", "DeviceId", "string", IsArray: false) }, + naming.PathParamNames); + + var source = CmdletEmitter.EmitUpdate(naming, new EmitContext("Test.Client"), "Device", properties, hasPasswordProfile: false); + + Assert.Contains("public string? DeviceId1 { get; set; }", source); + Assert.Contains("body.DeviceId = DeviceId1;", source); + Assert.Contains("IsParameterBound(nameof(DeviceId1))", source); + } + + // PATCH-only resources (/places/{id}) have no GetAsync on their kiota builder, so the + // 204 re-fetch must be emitted only when the path has a GET (found by compiling the + // Calendar module). Without the re-fetch, a bodiless 204 writes nothing — same as the + // published SDK's Update behavior. + [Fact] + public void UpdateEmitsReFetchOnlyWhenPathHasGet() + { + var naming = Naming.Resolve(new OperationInfo(HttpMethod.Patch, "/places/{place-id}")); + var props = new[] { new CmdletProperty("displayName", "DisplayName", "string", IsArray: false) }; + var ctx = new EmitContext("Test.Client"); + + var withGet = CmdletEmitter.EmitUpdate(naming, ctx, "Place", props, hasPasswordProfile: false, reFetchAfterUpdate: true); + Assert.Contains("re-fetching the updated resource", withGet); + Assert.Contains(".GetAsync()", withGet); + + var withoutGet = CmdletEmitter.EmitUpdate(naming, ctx, "Place", props, hasPasswordProfile: false, reFetchAfterUpdate: false); + Assert.DoesNotContain("re-fetching the updated resource", withoutGet); + Assert.DoesNotContain(".GetAsync()", withoutGet); + Assert.Contains("if (result is not null)", withoutGet); + } + // A spec-derived noun or header name containing a double quote must be escaped where it is // interpolated into a generated C# string literal, or the generated source will not compile. [Fact] diff --git a/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs b/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs index fb5f07a471..7275265a81 100644 --- a/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs +++ b/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs @@ -13,6 +13,47 @@ namespace WrapperGenerator.Tests; public sealed class GenerationServiceRegressionTests { + // Kiota moves a model INTO a same-named sub-namespace when both exist: + // microsoft.graph.security (alongside microsoft.graph.security.*) generates as + // Models.Security.Security, and a bare "Security" reference resolves to the namespace + // instead — it does not compile (found by building the Security module end to end). + [Theory] + // always fully qualified: bare "Directory" resolved to System.IO.Directory under + // implicit usings (Identity.DirectoryManagement), bare "Security" to the sub-namespace. + [InlineData("microsoft.graph.user", "Test.Models.User")] + [InlineData("microsoft.graph.directory", "Test.Models.Directory")] + [InlineData("microsoft.graph.security", "Test.Models.Security.Security")] + [InlineData("microsoft.graph.security.alert", "Test.Models.Security.Alert")] + [InlineData("microsoft.graph.partners", "Test.Models.Partners.Partners")] + public void ResolvesModelTypeNamesTheWayKiotaLaysThemOut(string schemaName, string expected) + { + var subNamespaces = new HashSet { "Security", "Partners", "CallRecords" }; + Assert.Equal(expected, + PowerShellWrapperGenerationService.ResolveModelTypeName(schemaName, "Test.Models", subNamespaces)); + } + + // Kiota renames reserved class names (BCL conflicts) by appending "Object", then dedupes + // numerically: microsoft.graph.directory -> DirectoryObject1, because directoryObject + // already exists (verified against the Identity.DirectoryManagement client). + [Fact] + public void AppliesKiotaReservedNameRenames() + { + var renames = new Dictionary + { + ["Directory"] = "DirectoryObject1", + ["IdentityGovernance.Task"] = "TaskObject", + }; + Assert.Equal("Test.Models.DirectoryObject1", + PowerShellWrapperGenerationService.ResolveModelTypeName( + "microsoft.graph.directory", "Test.Models", new HashSet(), renames)); + // Reserved renames apply inside sub-namespaces too: identityGovernance.task + // generates as Models.IdentityGovernance.TaskObject (verified against the + // Identity.Governance client). + Assert.Equal("Test.Models.IdentityGovernance.TaskObject", + PowerShellWrapperGenerationService.ResolveModelTypeName( + "microsoft.graph.identityGovernance.task", "Test.Models", new HashSet { "IdentityGovernance" }, renames)); + } + [Fact] public async Task GenerateAsync_SkipsGetWithoutJsonSuccessSchema_DoesNotThrow() { diff --git a/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs b/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs index 7ac2b68961..9d70471981 100644 --- a/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs +++ b/tools/WrapperGenerator.Tests/SchemaPropertiesTests.cs @@ -8,6 +8,53 @@ namespace WrapperGenerator.Tests; public sealed class SchemaPropertiesTests { + // Kiota strips underscores when naming model members: signIn's "riskEventTypes_v2" + // becomes RiskEventTypesV2 (verified against a generated SignIn model). The body + // assignment targets that member, so extraction must produce the same name. + [Fact] + public void MapsUnderscorePropertyNamesTheWayKiotaDoes() + { + var schema = new OpenApiSchema + { + Type = JsonSchemaType.Object, + Properties = new Dictionary + { + ["riskEventTypes_v2"] = new OpenApiSchema + { + Type = JsonSchemaType.Array, + Items = new OpenApiSchema { Type = JsonSchemaType.String }, + }, + }, + }; + + var property = Assert.Single(SchemaProperties.ExtractPrimitiveProperties(schema)); + Assert.Equal("RiskEventTypesV2", property.PascalName); + Assert.Equal("riskEventTypes_v2", property.OpenApiName); + } + + // PATCH /devices/{device-id} carries a body property "deviceId" (Entra's device + // identifier — a different value from the path's object id). The published SDK ships + // both as -DeviceId and -DeviceId1; the resolver reproduces that "1" suffix. The body + // assignment target (PascalName) must stay untouched — only the parameter renames. + [Fact] + public void SuffixesBodyPropertyThatCollidesWithPathParameter() + { + var properties = new[] + { + new CmdletProperty("deviceId", "DeviceId", "string", IsArray: false), + new CmdletProperty("displayName", "DisplayName", "string", IsArray: false), + }; + + var resolved = SchemaProperties.ResolveParameterNameCollisions(properties, new[] { "DeviceId" }); + + var renamed = Assert.Single(resolved, p => p.OpenApiName == "deviceId"); + Assert.Equal("DeviceId1", renamed.ParameterName); + Assert.Equal("DeviceId", renamed.PascalName); + + var untouched = Assert.Single(resolved, p => p.OpenApiName == "displayName"); + Assert.Equal("DisplayName", untouched.ParameterName); + } + private static OpenApiSchema Scalar(JsonSchemaType type, bool readOnly = false, string? format = null) => new() { Type = type, ReadOnly = readOnly, Format = format }; diff --git a/tools/WrapperGenerator/CmdletEmitter.cs b/tools/WrapperGenerator/CmdletEmitter.cs index 79914e69b1..f88ae8742b 100644 --- a/tools/WrapperGenerator/CmdletEmitter.cs +++ b/tools/WrapperGenerator/CmdletEmitter.cs @@ -154,10 +154,21 @@ private static string EmitCallWithOptionalHeaders(CmdletNaming naming, string me return $"{call}{args}requestConfiguration =>\n {{{bindings}\n }})"; } - public static string EmitItemGet(CmdletNaming naming, EmitContext ctx, string entityType) + public static string EmitItemGet(CmdletNaming naming, EmitContext ctx, string entityType, IReadOnlySet queryParamNames) { ArgumentNullException.ThrowIfNull(naming); ArgumentNullException.ThrowIfNull(ctx); + ArgumentNullException.ThrowIfNull(queryParamNames); + + // Only what the operation declares: kiota omits query-parameter properties the doc + // doesn't declare (subscribedSkus/{id} has $select but no $expand), so an + // unconditional binding would not compile against the builder. + var applicable = CollectionQueryOptions + .Where(o => o.ODataName is "$select" or "$expand" && queryParamNames.Contains(o.ODataName)) + .ToList(); + var queryParamDecls = string.Join("\n", applicable.Select(o => o.ParamDecl(null))); + var queryBindings = string.Join("\n\n", applicable.Select(o => o.Binding)); + return $$""" #nullable enable @@ -181,13 +192,7 @@ public class {{naming.ClassName}} : PSCmdlet {{AccessTokenParamDecl()}} - [Parameter(Mandatory = false)] - [Alias("Select")] - public string[]? Property { get; set; } - - [Parameter(Mandatory = false)] - [Alias("Expand")] - public string[]? ExpandProperty { get; set; } +{{queryParamDecls}} {{HeaderParamDecls(naming)}} {{GenericHeadersParamDecl()}} @@ -200,11 +205,7 @@ protected override void ProcessRecord() { result = client.{{naming.BuilderExpression}}.GetAsync(requestConfiguration => { - if (this.IsParameterBound(nameof(Property))) - requestConfiguration.QueryParameters.Select = Property; - - if (this.IsParameterBound(nameof(ExpandProperty))) - requestConfiguration.QueryParameters.Expand = ExpandProperty; +{{queryBindings}} {{HeaderBindings(naming)}} {{GenericHeadersBinding()}} }).GetAwaiter().GetResult(); @@ -315,7 +316,7 @@ protected override void ProcessRecord() } // The dispatcher's list-only parameter declarations: CollectionQueryOptions minus - // $select/$expand, which are shared with the "Get" set and declared once at class level. + // $select/$expand, which are declared separately per the sets that support them. // Declarations only; binding happens in the internal list cmdlet the dispatcher calls. private static IEnumerable<(string ODataName, string ParamDecl)> ListOnlyQueryOptionsForMerge() => CollectionQueryOptions @@ -353,21 +354,38 @@ private static string PairedPathParams(IReadOnlyList sharedNames, IReadO // call shares the caller's session, including an active Connect-MgGraph. public static string EmitGetDispatcher(CmdletNaming listNaming, CmdletNaming itemNaming, CmdletNaming internalListNaming, CmdletNaming internalItemNaming, EmitContext ctx, - string entityType, string collectionResponseType, IReadOnlySet queryParamNames) + string entityType, string collectionResponseType, IReadOnlySet listQueryParamNames, IReadOnlySet itemQueryParamNames) { ArgumentNullException.ThrowIfNull(listNaming); ArgumentNullException.ThrowIfNull(itemNaming); ArgumentNullException.ThrowIfNull(internalListNaming); ArgumentNullException.ThrowIfNull(internalItemNaming); ArgumentNullException.ThrowIfNull(ctx); - ArgumentNullException.ThrowIfNull(queryParamNames); + ArgumentNullException.ThrowIfNull(listQueryParamNames); + ArgumentNullException.ThrowIfNull(itemQueryParamNames); var sharedPathParams = listNaming.PathParamNames; var getOnlyPathParams = itemNaming.PathParamNames.Skip(sharedPathParams.Count).ToList(); - var applicable = ListOnlyQueryOptionsForMerge().Where(o => queryParamNames.Contains(o.ODataName)).ToList(); + var applicable = ListOnlyQueryOptionsForMerge().Where(o => listQueryParamNames.Contains(o.ODataName)).ToList(); var listOnlyParamDecls = string.Join("\n\n", applicable.Select(o => o.ParamDecl)); + // $select/$expand support can differ between the two operations (subscribedSkus + // declares $expand on the list but not the item), so each declaration is scoped to + // the parameter set(s) whose worker actually binds it. + var selectExpandDecls = string.Join("\n\n", new[] { "$select", "$expand" } + .Select(od => + { + var row = CollectionQueryOptions.First(o => o.ODataName == od); + var inList = listQueryParamNames.Contains(od); + var inItem = itemQueryParamNames.Contains(od); + return inList && inItem ? row.ParamDecl(null) + : inList ? row.ParamDecl("List") + : inItem ? row.ParamDecl("Get") + : null; + }) + .Where(static d => d is not null)); + var (sharedHeaders, listOnlyHeaders, getOnlyHeaders) = PartitionHeaderParams(listNaming, itemNaming); var internalListCmdletName = $"{internalListNaming.VerbName}-{internalListNaming.Noun}"; @@ -392,13 +410,7 @@ public class {{listNaming.ClassName}} : PSCmdlet {{AccessTokenParamDecl()}} - [Parameter(Mandatory = false)] - [Alias("Select")] - public string[]? Property { get; set; } - - [Parameter(Mandatory = false)] - [Alias("Expand")] - public string[]? ExpandProperty { get; set; } +{{selectExpandDecls}} {{listOnlyParamDecls}} {{HeaderParamDeclsFor(sharedHeaders, parameterSetName: null)}} @@ -420,6 +432,16 @@ protected override void ProcessRecord() null, MyInvocation.BoundParameters, internalCmdletName); } + // The workers signal failure via ThrowTerminatingError, which InvokeScript surfaces + // as a RuntimeException carrying the worker's ErrorRecord. Rethrow that record + // unchanged so the caller sees the worker's error identity (NoGraphSession, + // GraphRequestFailed, ...) instead of every failure collapsing into a generic + // dispatcher error. + catch (RuntimeException rex) when (rex.ErrorRecord is not null) + { + ThrowTerminatingError(rex.ErrorRecord); + return; + } {{CatchBlock($"ParameterSetName == \"Get\" ? {TargetId(itemNaming)} : {TargetId(listNaming)}")}} } } @@ -485,7 +507,7 @@ protected override void ProcessRecord() """; } - public static string EmitUpdate(CmdletNaming naming, EmitContext ctx, string entityType, IReadOnlyList properties, bool hasPasswordProfile) + public static string EmitUpdate(CmdletNaming naming, EmitContext ctx, string entityType, IReadOnlyList properties, bool hasPasswordProfile, bool reFetchAfterUpdate = true) { ArgumentNullException.ThrowIfNull(naming); ArgumentNullException.ThrowIfNull(ctx); @@ -534,20 +556,9 @@ protected override void ProcessRecord() } {{CatchBlock(TargetId(naming))}} - // Graph often answers a successful PATCH with 204 and no body (seen live on - // schemaExtension update). Re-fetch so the cmdlet returns the updated resource - // instead of nothing. - if (result is null) - { - WriteVerbose("[MgPoC] PATCH succeeded with no response body, re-fetching the updated resource."); - try - { - result = client.{{naming.BuilderExpression}}.GetAsync().GetAwaiter().GetResult(); - } -{{CatchBlock(TargetId(naming), " ")}} - } - - WriteObject(result); +{{(reFetchAfterUpdate ? ReFetchBlock(naming) : "")}} + if (result is not null) + WriteObject(result); } } } @@ -648,18 +659,38 @@ public Task AuthenticateRequestAsync(RequestInformation request, Dictionary $$""" + + if (result is null) + { + WriteVerbose("[MgPoC] PATCH succeeded with no response body, re-fetching the updated resource."); + try + { + result = client.{{naming.BuilderExpression}}.GetAsync().GetAwaiter().GetResult(); + } +{{CatchBlock(TargetId(naming), " ")}} + } +"""; + + // ParameterName (not PascalName) names the parameter: it carries the "1" suffix when a + // body property collides with a path id. The body assignment keeps PascalName — the + // Kiota model property is unaffected by the parameter rename. private static string EmitPropertyParameters(IReadOnlyList properties) => string.Join("\n", properties.Select(p => $$""" [Parameter(Mandatory = false)] - public {{p.PsTypeName}}? {{p.PascalName}} { get; set; } + public {{p.PsTypeName}}? {{p.ParameterName}} { get; set; } """)); private static string EmitPropertyAssignments(IReadOnlyList properties) => string.Join("\n", properties.Select(p => $$""" - if (this.IsParameterBound(nameof({{p.PascalName}}))) - body.{{p.PascalName}} = {{(p.IsArray ? $"{p.PascalName}!.ToList()" : p.PascalName)}}; + if (this.IsParameterBound(nameof({{p.ParameterName}}))) + body.{{p.PascalName}} = {{(p.IsArray ? $"{p.ParameterName}!.ToList()" : p.ParameterName)}}; """)); private static string EmitPasswordProfileParameters() => """ diff --git a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs index 279470cd9a..f339190253 100644 --- a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs +++ b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs @@ -19,6 +19,8 @@ public sealed partial class PowerShellWrapperGenerationService private readonly OpenApiDocument document; private readonly GeneratorConfig config; private readonly ILogger logger; + private readonly HashSet modelSubNamespaces; + private readonly Dictionary kiotaReservedRenames; public PowerShellWrapperGenerationService(OpenApiDocument document, GeneratorConfig configuration, ILogger logger) { @@ -28,8 +30,57 @@ public PowerShellWrapperGenerationService(OpenApiDocument document, GeneratorCon this.document = document; config = configuration; this.logger = logger; + + // Kiota nests each dotted schema-name segment as a sub-namespace under Models + // ("security.alert" -> Models.Security.Alert), and when a model's own name matches + // such a namespace ("microsoft.graph.security" alongside "microsoft.graph.security.*") + // it moves the class INSIDE it: Models.Security.Security. Collect those namespace + // roots so ResolveModelTypeName can mirror the move — a bare "Security" would + // otherwise resolve to the namespace, not the type, and fail to compile. + // Model names grouped by the sub-namespace kiota puts them in ("" = Models root): + // needed both for the namespace-move rule and to dedupe reserved-name renames the + // way kiota does (against siblings in the same namespace). + modelSubNamespaces = new HashSet(StringComparer.Ordinal); + var namesByNamespace = new Dictionary>(StringComparer.Ordinal) { [""] = new(StringComparer.Ordinal) }; + foreach (var key in document.Components?.Schemas?.Keys ?? Enumerable.Empty()) + { + var segments = StripGraphPrefix(key).Split('.') + .Select(static s => char.ToUpperInvariant(s[0]) + s[1..]).ToArray(); + if (segments.Length > 1) + modelSubNamespaces.Add(segments[0]); + var ns = string.Join('.', segments[..^1]); + if (!namesByNamespace.TryGetValue(ns, out var names)) + namesByNamespace[ns] = names = new HashSet(StringComparer.Ordinal); + names.Add(segments[^1]); + } + + // Kiota renames model classes whose name is on its C# reserved list (BCL conflicts: + // Directory, File, Task, ...) by appending "Object", then dedupes numerically against + // sibling models. Observed and verified: microsoft.graph.directory generates as + // DirectoryObject1 (directoryObject already exists at the root) and + // microsoft.graph.identityGovernance.task as IdentityGovernance.TaskObject. This + // mirrors observed kiota 1.32.2 behavior — a wrong prediction fails the module + // compile, it cannot fail silently. Keyed by the full Pascal segment path. + kiotaReservedRenames = new Dictionary(StringComparer.Ordinal); + foreach (var (ns, names) in namesByNamespace) + { + foreach (var reserved in KiotaReservedModelNames) + { + if (!names.Contains(reserved)) + continue; + var renamed = reserved + "Object"; + while (names.Contains(renamed)) + renamed += "1"; + kiotaReservedRenames[ns.Length == 0 ? reserved : $"{ns}.{reserved}"] = renamed; + } + } } + // Kiota's C# refiner reserves type names that collide with common BCL types (see + // CSharpReservedClassNamesProvider in microsoft/kiota). Only names observed in Graph + // docs are listed; a new one surfaces as a compile failure in the affected module. + private static readonly string[] KiotaReservedModelNames = ["Directory", "File", "Task", "Type", "Environment"]; + // One GET operation from the first pass, held until we know whether it pairs with a // list/item partner. CollectionValueSchema is the response's "value" array property when // the response is a collection, null for a single entity. It is resolved once here so @@ -92,6 +143,17 @@ public async Task GenerateAsync(CancellationToken cancellationToken) // checks "2XX" first and falls back across 200/201/default and "+json" content // types for the few operations that deviate, rather than doing general content // negotiation the way a generic OpenAPI reader would have to. + // A success response that also declares non-JSON content (octet-stream, + // image/*) is a media download — kiota generates GetAsync returning Stream + // there regardless of any JSON schema the doc also lists (the styled docs + // attach an entity schema to /content endpoints; found by compiling Teams). + // Stream downloads are not generated yet; see the README gap list. + if (httpMethod == HttpMethod.Get && HasNonJsonSuccessContent(operation)) + { + LogSkippedUnsupportedOperation(httpMethod.Method, pathTemplate, "media/stream content endpoint, not generated yet"); + continue; + } + var responseSchema = httpMethod == HttpMethod.Get ? TryGetSuccessJsonSchema(operation) : null; @@ -116,7 +178,8 @@ public async Task GenerateAsync(CancellationToken cancellationToken) { _ when httpMethod == HttpMethod.Delete => CmdletEmitter.EmitRemove(cmdletNaming, ctx), _ when httpMethod == HttpMethod.Post => EmitNewFor(cmdletNaming, ctx, operation), - _ when httpMethod == HttpMethod.Patch => EmitUpdateFor(cmdletNaming, ctx, operation), + _ when httpMethod == HttpMethod.Patch => EmitUpdateFor(cmdletNaming, ctx, operation, + canReFetch: pathItem.Operations?.ContainsKey(HttpMethod.Get) == true), _ => null, }; @@ -177,18 +240,19 @@ private async Task EmitGetOperationsAsync(List getOpera LogSkippedUnsupportedOperation("GET", listOp.Naming.BuilderExpression, "response schema is not a resolvable $ref entity type"); continue; } - var collectionResponseType = listEntityType + "CollectionResponse"; + var collectionResponseType = ResolveCollectionResponseType(listOp.ResponseSchema, ctx.ModelsNamespace, listEntityType); // The two real implementations: separate, independently documented cmdlets, unchanged // from (and reusing) the standalone shapes used for unpaired GETs. var internalListNaming = Naming.WithSuffix(listOp.Naming, "_List"); var internalItemNaming = Naming.WithSuffix(itemOp.Naming, "_Get"); var internalListSource = CmdletEmitter.EmitListGet(internalListNaming, ctx, listEntityType, collectionResponseType, listOp.QueryParams.ToHashSet()); - var internalItemSource = CmdletEmitter.EmitItemGet(internalItemNaming, ctx, entityType); + var internalItemSource = CmdletEmitter.EmitItemGet(internalItemNaming, ctx, entityType, itemOp.QueryParams.ToHashSet()); // The thin public dispatcher on top, presenting the merged Get-MgX surface. var dispatcherSource = CmdletEmitter.EmitGetDispatcher(listOp.Naming, itemOp.Naming, - internalListNaming, internalItemNaming, ctx, entityType, collectionResponseType, listOp.QueryParams.ToHashSet()); + internalListNaming, internalItemNaming, ctx, entityType, collectionResponseType, + listOp.QueryParams.ToHashSet(), itemOp.QueryParams.ToHashSet()); written += await WriteCmdletFileAsync(internalListNaming, internalListSource, cancellationToken).ConfigureAwait(false); written += await WriteCmdletFileAsync(internalItemNaming, internalItemSource, cancellationToken).ConfigureAwait(false); @@ -211,7 +275,8 @@ private async Task EmitGetOperationsAsync(List getOpera continue; } - source = CmdletEmitter.EmitListGet(op.Naming, ctx, listEntityType, listEntityType + "CollectionResponse", op.QueryParams.ToHashSet()); + source = CmdletEmitter.EmitListGet(op.Naming, ctx, listEntityType, + ResolveCollectionResponseType(op.ResponseSchema, ctx.ModelsNamespace, listEntityType), op.QueryParams.ToHashSet()); } else { @@ -221,7 +286,7 @@ private async Task EmitGetOperationsAsync(List getOpera continue; } - source = CmdletEmitter.EmitItemGet(op.Naming, ctx, entityType); + source = CmdletEmitter.EmitItemGet(op.Naming, ctx, entityType, op.QueryParams.ToHashSet()); } written += await WriteCmdletFileAsync(op.Naming, source, cancellationToken).ConfigureAwait(false); @@ -260,7 +325,7 @@ private static bool HasUnsupportedPathSegment(string pathTemplate) => // collectionValueSchema is the already-resolved "value" array property from // GetOperationRecord, so nothing is re-walked here. - private static bool TryResolveListEntityTypeName(IOpenApiSchema collectionValueSchema, string modelsNamespace, out string entityTypeName) + private bool TryResolveListEntityTypeName(IOpenApiSchema collectionValueSchema, string modelsNamespace, out string entityTypeName) { entityTypeName = string.Empty; var itemSchema = collectionValueSchema.Items; @@ -285,7 +350,7 @@ private static bool TryResolveListEntityTypeName(IOpenApiSchema collectionValueS return null; } - private static string? EmitNewFor(CmdletNaming naming, EmitContext ctx, OpenApiOperation operation) + private string? EmitNewFor(CmdletNaming naming, EmitContext ctx, OpenApiOperation operation) { // "application/json" is an intentional, Graph-scoped assumption: Graph request bodies are // JSON, so the content type is indexed directly rather than negotiated. See the matching @@ -295,11 +360,12 @@ private static bool TryResolveListEntityTypeName(IOpenApiSchema collectionValueS return null; if (!TryResolveEntityTypeName(bodySchema, ctx.ModelsNamespace, out var entityType)) return null; - return CmdletEmitter.EmitNew(naming, ctx, entityType, - SchemaProperties.ExtractPrimitiveProperties(bodySchema), SchemaProperties.HasPasswordProfile(bodySchema)); + var properties = SchemaProperties.ResolveParameterNameCollisions( + SchemaProperties.ExtractPrimitiveProperties(bodySchema), naming.PathParamNames); + return CmdletEmitter.EmitNew(naming, ctx, entityType, properties, SchemaProperties.HasPasswordProfile(bodySchema)); } - private static string? EmitUpdateFor(CmdletNaming naming, EmitContext ctx, OpenApiOperation operation) + private string? EmitUpdateFor(CmdletNaming naming, EmitContext ctx, OpenApiOperation operation, bool canReFetch) { // "application/json" is an intentional, Graph-scoped assumption (see EmitNewFor). var bodySchema = TryGetRequestJsonSchema(operation); @@ -307,8 +373,27 @@ private static bool TryResolveListEntityTypeName(IOpenApiSchema collectionValueS return null; if (!TryResolveEntityTypeName(bodySchema, ctx.ModelsNamespace, out var entityType)) return null; - return CmdletEmitter.EmitUpdate(naming, ctx, entityType, - SchemaProperties.ExtractPrimitiveProperties(bodySchema), SchemaProperties.HasPasswordProfile(bodySchema)); + var properties = SchemaProperties.ResolveParameterNameCollisions( + SchemaProperties.ExtractPrimitiveProperties(bodySchema), naming.PathParamNames); + return CmdletEmitter.EmitUpdate(naming, ctx, entityType, properties, SchemaProperties.HasPasswordProfile(bodySchema), canReFetch); + } + + private static bool HasNonJsonSuccessContent(OpenApiOperation operation) + { + if (operation.Responses is null) + return false; + foreach (var key in new[] { "2XX", "200", "201" }) + { + if (!operation.Responses.TryGetValue(key, out var response) || response?.Content is null) + continue; + foreach (var contentType in response.Content.Keys) + { + if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) + && !contentType.EndsWith("+json", StringComparison.OrdinalIgnoreCase)) + return true; + } + } + return false; } private static IOpenApiSchema? TryGetSuccessJsonSchema(OpenApiOperation operation) @@ -355,27 +440,56 @@ private static bool TryResolveListEntityTypeName(IOpenApiSchema collectionValueS return null; } - private static bool TryResolveEntityTypeName(IOpenApiSchema schema, string modelsNamespace, out string entityTypeName) + private bool TryResolveEntityTypeName(IOpenApiSchema schema, string modelsNamespace, out string entityTypeName) { entityTypeName = string.Empty; var id = schema.GetReferenceId(); if (string.IsNullOrEmpty(id)) return false; - entityTypeName = SchemaNameToTypeName(id, modelsNamespace); + entityTypeName = ResolveModelTypeName(id, modelsNamespace, modelSubNamespaces, kiotaReservedRenames); return true; } - private static string SchemaNameToTypeName(string schemaName, string modelsNamespace) - { - var name = schemaName.StartsWith("microsoft.graph.", StringComparison.Ordinal) + // The collection response type is resolved from the list response's own $ref, not by + // appending "CollectionResponse" to the entity type: kiota's reserved-name rename hits + // the entity but not its collection response (identityGovernance.task -> + // Models.IdentityGovernance.TaskObject, but taskCollectionResponse -> TaskCollectionResponse + // unchanged — found by compiling Identity.Governance). Falls back to the append for + // inline response schemas without a $ref. + private string ResolveCollectionResponseType(IOpenApiSchema listResponseSchema, string modelsNamespace, string listEntityType) => + TryResolveEntityTypeName(listResponseSchema, modelsNamespace, out var fromRef) + ? fromRef + : listEntityType + "CollectionResponse"; + + private static string StripGraphPrefix(string schemaName) => + schemaName.StartsWith("microsoft.graph.", StringComparison.Ordinal) ? schemaName["microsoft.graph.".Length..] : schemaName; - // Kiota nests each dot segment as a sub-namespace under Models ("security.alert" - // becomes Models.Security.Alert). A using directive does not reach into nested - // namespaces, so multi-segment names are fully qualified; single-segment names, - // the common case, stay bare. - var segments = name.Split('.').Select(static segment => char.ToUpperInvariant(segment[0]) + segment[1..]).ToArray(); - return segments.Length == 1 ? segments[0] : $"{modelsNamespace}.{string.Join('.', segments)}"; + // Maps a schema reference id to the C# type name kiota generates for it. Public and pure + // so the mapping rules are directly testable. + // + // Every reference is fully qualified. Bare names break two ways, both found by compiling + // real modules: a name that matches a kiota sub-namespace resolves to the namespace + // instead of the type ("Security"), and a name that matches a BCL type in scope resolves + // to that ("Directory" vs System.IO.Directory under implicit usings). Kiota itself nests + // dotted segments as sub-namespaces ("security.alert" -> Models.Security.Alert), and when + // a model's own name matches such a namespace it moves the class inside it + // (microsoft.graph.security -> Models.Security.Security, verified against a real client). + public static string ResolveModelTypeName(string schemaName, string modelsNamespace, IReadOnlySet modelSubNamespaces, + IReadOnlyDictionary? kiotaReservedRenames = null) + { + ArgumentNullException.ThrowIfNull(schemaName); + ArgumentNullException.ThrowIfNull(modelsNamespace); + ArgumentNullException.ThrowIfNull(modelSubNamespaces); + + var segments = StripGraphPrefix(schemaName).Split('.') + .Select(static segment => char.ToUpperInvariant(segment[0]) + segment[1..]).ToArray(); + if (kiotaReservedRenames is not null && kiotaReservedRenames.TryGetValue(string.Join('.', segments), out var renamed)) + segments[^1] = renamed; + var qualified = $"{modelsNamespace}.{string.Join('.', segments)}"; + return segments.Length == 1 && modelSubNamespaces.Contains(segments[0]) + ? $"{qualified}.{segments[0]}" + : qualified; } } diff --git a/tools/WrapperGenerator/SchemaProperties.cs b/tools/WrapperGenerator/SchemaProperties.cs index 08fe5d4b3e..30d3ac2302 100644 --- a/tools/WrapperGenerator/SchemaProperties.cs +++ b/tools/WrapperGenerator/SchemaProperties.cs @@ -5,7 +5,12 @@ namespace WrapperGenerator; -public sealed record CmdletProperty(string OpenApiName, string PascalName, string PsTypeName, bool IsArray); +public sealed record CmdletProperty(string OpenApiName, string PascalName, string PsTypeName, bool IsArray) +{ + // The emitted -Parameter name. Differs from PascalName only when the body property + // collides with a path parameter; see ResolveParameterNameCollisions. + public string ParameterName { get; init; } = PascalName; +} // Maps a body schema's top-level primitive properties onto cmdlet parameters. Deliberately // shallow, per team decision: nested complex properties (assignedLicenses, employeeOrgData, @@ -32,11 +37,11 @@ void Walk(IOpenApiSchema s) if (IsPlainScalar(propSchema)) { - result.Add(new CmdletProperty(name, name.ToFirstCharacterUpperCase(), MapPsType(propSchema), IsArray: false)); + result.Add(new CmdletProperty(name, ToKiotaPropertyName(name), MapPsType(propSchema), IsArray: false)); } else if (propSchema.Type == JsonSchemaType.Array && propSchema.Items is { } items && IsPlainScalar(items)) { - result.Add(new CmdletProperty(name, name.ToFirstCharacterUpperCase(), MapPsType(items) + "[]", IsArray: true)); + result.Add(new CmdletProperty(name, ToKiotaPropertyName(name), MapPsType(items) + "[]", IsArray: true)); } } } @@ -45,6 +50,23 @@ void Walk(IOpenApiSchema s) return result; } + // A body property whose Pascal name matches a path parameter would emit a duplicate C# + // property (PATCH /devices/{device-id} has a path id AND a body property "deviceId" — + // different values: the URL takes the object id, the body carries Entra's deviceId). + // The published SDK keeps both reachable by suffixing the body one with "1" + // (Update-MgDevice ships -DeviceId and -DeviceId1); reproduce that convention rather + // than dropping a settable property. + public static IReadOnlyList ResolveParameterNameCollisions( + IReadOnlyList properties, IReadOnlyList pathParamNames) + { + ArgumentNullException.ThrowIfNull(properties); + ArgumentNullException.ThrowIfNull(pathParamNames); + var taken = new HashSet(pathParamNames, StringComparer.Ordinal); + return properties + .Select(p => taken.Contains(p.PascalName) ? p with { ParameterName = p.PascalName + "1" } : p) + .ToList(); + } + // passwordProfile is a nested complex type, so ExtractPrimitiveProperties skips it, but // Graph requires it to create a user. This flag lets the emitter add the two flattened // parameters (-Password, -ForceChangePasswordNextSignIn) that make New-MgUser usable. @@ -88,6 +110,16 @@ public static bool HasPasswordProfile(IOpenApiSchema schema) _ => "string", }; + // Kiota cleans property symbols when generating model members: underscores are dropped + // and the following character upper-cased ("riskEventTypes_v2" -> RiskEventTypesV2, + // verified against a generated SignIn model). The body assignment targets that member, + // so this mapping must match kiota's or the emitted code does not compile. + private static string ToKiotaPropertyName(string openApiName) + { + var parts = openApiName.Split('_', StringSplitOptions.RemoveEmptyEntries); + return string.Concat(parts.Select(static p => char.ToUpperInvariant(p[0]) + p[1..])); + } + // Excludes properties a caller cannot or should not set. "id" is server-assigned. // "@"-prefixed names like "@odata.type" are OData control data that Kiota's serializer // fills in from the model type, and they are not legal C# identifiers anyway. ReadOnly is From 26948e82dedbaab9f7454dc9d5d5d62fb820020d Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Thu, 6 Aug 2026 11:48:55 -0700 Subject: [PATCH 06/11] fix(wrapper-generator): correct PlaceCheckIn names, add Rights invariant, catalog kiota edge cases The full-module parity sweep found two shipped-name issues: AutoRest truncated /places/{id}/checkIns at the preposition (8 commands ship as *-MgPlaceCheck while Get-MgPlaceCheckInCount keeps "In") - corrected per policy with gate rows and pinned tests; and "Rights" needs to be an inflection invariant (Get-MgPrivacySubjectRightsRequest, 42 cmdlets) - Compliance now matches 23 of 23. New edge-cases/kiota-alignment file catalogs the compile-found defect classes; README refreshed. 103 tests. --- tools/Compare-WrapperCmdletNames.ps1 | 10 ++ tools/WrapperGenerator.Tests/NamingTests.cs | 7 ++ tools/WrapperGenerator/README.md | 6 +- tools/WrapperGenerator/Singularizer.cs | 3 + .../edge-cases/kiota-alignment-edge-cases.md | 119 ++++++++++++++++++ .../edge-cases/naming-edge-cases.md | 28 ++++- 6 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 tools/WrapperGenerator/edge-cases/kiota-alignment-edge-cases.md diff --git a/tools/Compare-WrapperCmdletNames.ps1 b/tools/Compare-WrapperCmdletNames.ps1 index e06f24538c..d1a6b0a5c2 100644 --- a/tools/Compare-WrapperCmdletNames.ps1 +++ b/tools/Compare-WrapperCmdletNames.ps1 @@ -140,6 +140,16 @@ $deliberateCorrections = @{ # cmdlets (whoisRecords, whoisHistoryRecords) all keep "Whois". 'Get-MgSecurityThreatIntelligenceHostWhoi' = 'Get-MgSecurityThreatIntelligenceHostWhois' 'Get-MgBetaSecurityThreatIntelligenceHostWhoi' = 'Get-MgBetaSecurityThreatIntelligenceHostWhois' + # AutoRest truncated /places/{id}/checkIns at the preposition (the #912 defect class): + # shipped ...PlaceCheck, while Get-MgPlaceCheckInCount keeps "In" intact. + 'Get-MgPlaceCheck' = 'Get-MgPlaceCheckIn' + 'New-MgPlaceCheck' = 'New-MgPlaceCheckIn' + 'Update-MgPlaceCheck' = 'Update-MgPlaceCheckIn' + 'Remove-MgPlaceCheck' = 'Remove-MgPlaceCheckIn' + 'Get-MgBetaPlaceCheck' = 'Get-MgBetaPlaceCheckIn' + 'New-MgBetaPlaceCheck' = 'New-MgBetaPlaceCheckIn' + 'Update-MgBetaPlaceCheck' = 'Update-MgBetaPlaceCheckIn' + 'Remove-MgBetaPlaceCheck' = 'Remove-MgBetaPlaceCheckIn' } Write-Host "Loading oracle from $OraclePath ..." diff --git a/tools/WrapperGenerator.Tests/NamingTests.cs b/tools/WrapperGenerator.Tests/NamingTests.cs index 66c84ca38c..3f101ae752 100644 --- a/tools/WrapperGenerator.Tests/NamingTests.cs +++ b/tools/WrapperGenerator.Tests/NamingTests.cs @@ -47,6 +47,7 @@ public sealed class SingularizerTests [InlineData("Dns", "Dns")] [InlineData("Ios", "Ios")] [InlineData("Statistics", "Statistics")] + [InlineData("Rights", "Rights")] // acronyms are never plural forms [InlineData("OS", "OS")] public void SingularizesWords(string word, string expected) @@ -98,6 +99,8 @@ private static CmdletNaming Resolve(string method, string path) => [InlineData("GET", "/security/threatIntelligence/whoisRecords/{whoisRecord-id}", "Get", "MgSecurityThreatIntelligenceWhoisRecord")] // interior "Statistics" survives per-word inflection (invariant found via the DEVX API's Humanizer exception list) [InlineData("GET", "/security/cases/ediscoveryCases/{ediscoveryCase-id}/searches/{ediscoverySearch-id}/lastEstimateStatisticsOperation", "Get", "MgSecurityCaseEdiscoveryCaseSearchLastEstimateStatisticsOperation")] + // interior "Rights" survives per-word inflection (Get-MgPrivacySubjectRightsRequest, found by the full-module parity sweep) + [InlineData("GET", "/privacy/subjectRightsRequests/{subjectRightsRequest-id}", "Get", "MgPrivacySubjectRightsRequest")] [InlineData("PATCH", "/admin/reportSettings", "Update", "MgAdminReportSetting")] [InlineData("GET", "/schemaExtensions", "Get", "MgSchemaExtension")] [InlineData("GET", "/domains/{domain-id}", "Get", "MgDomain")] @@ -130,6 +133,10 @@ public void ResolvesPublishedSdkNames(string method, string path, string expecte // Shipped: Get-MgSecurityThreatIntelligenceHostWhoi — the only whois-family cmdlet (of 30) // where "Whois" was inflected to "Whoi". [InlineData("GET", "/security/threatIntelligence/hosts/{host-id}/whois", "Get", "MgSecurityThreatIntelligenceHostWhois")] + // Shipped: New-MgPlaceCheck — AutoRest truncated "CheckIns" at the preposition (#912 + // class) while Get-MgPlaceCheckInCount keeps "In" intact. + [InlineData("GET", "/places/{place-id}/checkIns", "Get", "MgPlaceCheckIn")] + [InlineData("POST", "/places/{place-id}/checkIns", "New", "MgPlaceCheckIn")] public void AppliesDeliberateNameCorrections(string method, string path, string expectedVerb, string expectedNoun) { var naming = Resolve(method, path); diff --git a/tools/WrapperGenerator/README.md b/tools/WrapperGenerator/README.md index 8943b4bb30..caab1d5e93 100644 --- a/tools/WrapperGenerator/README.md +++ b/tools/WrapperGenerator/README.md @@ -143,7 +143,7 @@ The wrappers compile and run only alongside step 1's output. Wiring the two into ```powershell dotnet run --project tools/WrapperGenerator -- ` - -d openApiDocs/v1.0/Mail.yml ` + -d openApiDocs_KiotaCompat/v1.0/Mail.yml ` -o ` -n Microsoft.Graph.PowerShell.Mail.Client ` --include-path '/users/{user-id}/message[s]#GET,POST' ` @@ -157,7 +157,7 @@ dotnet run --project tools/WrapperGenerator -- ` ```powershell # 1. Naming rules pinned to published Microsoft.Graph names dotnet test tools/WrapperGenerator.Tests -# => Passed! - Failed: 0, Passed: 88, Total: 88 +# => Passed! - Failed: 0, Passed: 103, Total: 103 # 2. Parity gate: generate, then check every cmdlet name against Graph's own command inventory .\tools\Compare-WrapperCmdletNames.ps1 -GeneratedPath @@ -168,7 +168,7 @@ The unit tests guard the naming rules (their expected values are real published ## Gaps / not done yet -- **Output isn't wired into a module.** Files go to whatever `-o` folder you pass, in a fixed `MgPoC` namespace. The target design commits wrappers into `src/{Module}/` with a per-module namespace; that alignment (and a namespace override) isn't built. +- **Output isn't committed into `src/{Module}/`.** `tools/Build-WrapperModule.ps1` now turns a module into an importable build under `artifacts/` (kiota client + wrappers + csproj + PSD1; `tools/Test-WrapperModule.ps1` smoke-tests it), with generation reading the Kiota-compatible docs (`openApiDocs_KiotaCompat`) by default. The target design — wrappers committed into `src/{Module}/` with a per-module namespace instead of `MgPoC` — is still open. - **No runtime base classes or real auth flow.** Shared paging, a proper `Connect-MgGraph`/session integration, and base cmdlet classes are a later phase. - **Body binding is shallow** — top-level primitive properties only; no nested/complex types beyond the `passwordProfile` special case. - **Some operation shapes aren't generated** — `$count`/`$ref`/`$value`, delta, OData actions/functions, and cast endpoints. diff --git a/tools/WrapperGenerator/Singularizer.cs b/tools/WrapperGenerator/Singularizer.cs index 05b0710b86..098a7ff687 100644 --- a/tools/WrapperGenerator/Singularizer.cs +++ b/tools/WrapperGenerator/Singularizer.cs @@ -40,6 +40,9 @@ public static partial class Singularizer "Dns", "Ios", "Statistics", + // subjectRightsRequests ships keeping "Rights" (Get-MgPrivacySubjectRightsRequest, + // 42 cmdlets across Compliance/Security); usageRights likewise in beta. + "Rights", }; // Splits Pascal or camel text into words. Handles acronym runs ("OS" in "MacOSDmgApp"), diff --git a/tools/WrapperGenerator/edge-cases/kiota-alignment-edge-cases.md b/tools/WrapperGenerator/edge-cases/kiota-alignment-edge-cases.md new file mode 100644 index 0000000000..f7c2775c9c --- /dev/null +++ b/tools/WrapperGenerator/edge-cases/kiota-alignment-edge-cases.md @@ -0,0 +1,119 @@ +# Kiota alignment edge cases + +Second class file in the edge-case catalog (see `naming-edge-cases.md` for the catalog +conventions). These cases are places where the wrapper generator's *prediction* of what +kiota generates — type names, builder members, query parameters — met kiota's actual +output and lost. Every entry was found the same way: compiling generated wrappers against +a real kiota client, module by module. That is the point of the packaging pipeline: a wrong +prediction fails a build loudly instead of shipping. + +The systemic backstop for this whole class is the compile gate (tracked with the pipeline +work): these entries document the specific rules learned so far, not a promise that no +others exist. + +## Doc flavor: kiota requires the KiotaCompat conversion + +- **Class:** doc-flavor +- **Status:** handled (Build-WrapperModule.ps1 defaults to openApiDocs_KiotaCompat) +- **Evidence:** the PowerShell-profile docs under `openApiDocs` flatten open types + (`microsoft.graph.Dictionary`, `customExtensionData`, `onAttributeCollectionHandler`) + into empty schemas; kiota rejects them ("the type does not contain any information") in + Search, Identity.SignIns, Identity.Governance, and ConfigurationManagement, and hangs + >35 min on Sites. The `openApiDocs_KiotaCompat` conversion (DEVX API, `style=Plain`, + discriminators preserved) generates all five in seconds. +- **Decision:** KiotaCompat docs are the generator's canonical input. Open question raised + with the team: make them canonical for the whole v3 pipeline. +- **Migration impact:** none — input selection, not output change. +- **References:** tools/DownloadOpenApiDocKiotaCompat.ps1 (provenance); + Build-WrapperModule.ps1 `-SpecRoot`. + +## kiota hangs on specific docs (both flavors) + +- **Class:** doc-flavor +- **Status:** workaround (hard timeout + per-module doc-flavor fallback) +- **Evidence:** kiota 1.32.2 hangs silently (zero CPU, no output) on the *styled* Sites doc + and on the *KiotaCompat* Teams doc — while generating each module fine from the other + flavor. Content-dependent, not size-dependent (larger docs complete in seconds). +- **Decision:** Build-WrapperModule.ps1 kills kiota after 300s and fails the module rather + than stalling a fan-out; Teams builds from the styled doc via `-SpecRoot`. Candidate for + an upstream kiota report once a minimal repro is extracted. +- **Migration impact:** none. + +## Reserved model names: Directory → DirectoryObject1 + +- **Class:** kiota-symbol-prediction +- **Status:** handled (observed rule encoded, pinned test) +- **Evidence:** kiota renames model classes on its C# reserved list (BCL conflicts) by + appending `Object`, then dedupes numerically: `microsoft.graph.directory` generates as + `DirectoryObject1` because `directoryObject` already exists (Identity.DirectoryManagement). + A bare `Directory` reference had first resolved to `System.IO.Directory` under implicit + usings. +- **Decision:** encode the observed rule for reserved names present in Graph docs + (Directory/File/Task/Type/Environment), computed against the document's schema set. This + mirrors observed kiota 1.32.2 behavior — a wrong prediction fails the module compile, it + cannot fail silently. +- **Migration impact:** none — internal type references only. +- **References:** kiota's CSharpReservedClassNamesProvider; + PowerShellWrapperGenerationService.KiotaReservedModelNames. + +## A model that shares its name with a kiota sub-namespace moves inside it + +- **Class:** kiota-symbol-prediction +- **Status:** handled (all model references fully qualified; pinned tests) +- **Evidence:** `microsoft.graph.security` generates as `Models.Security.Security` because + the `microsoft.graph.security.*` family creates a `Models.Security` namespace; bare + `Security` resolved to the namespace and did not compile (Security module; same for + `partners`/`Models.Partners.Partners` in Reports). +- **Decision:** fully qualify every model type reference and mirror the move-inside rule + when a single-segment name matches a sub-namespace derived from the document. +- **Migration impact:** none. + +## kiota strips underscores from member names + +- **Class:** kiota-symbol-prediction +- **Status:** handled (pinned test) +- **Evidence:** signIn's `riskEventTypes_v2` property generates as `RiskEventTypesV2`; the + wrapper's naive Pascal-casing produced `RiskEventTypes_v2` and the body assignment did + not compile (Reports). +- **Decision:** mirror the cleanup (drop `_`, upper-case the following character) when + naming the model member a body parameter assigns to. +- **Migration impact:** none. + +## Query options exist only where the doc declares them + +- **Class:** kiota-builder-shape +- **Status:** handled (pinned by the option-table mechanism) +- **Evidence:** kiota omits query-parameter properties the operation doesn't declare: + content/stream endpoints get a bare `DefaultQueryParameters` (Files, Notes, Users, +4 on + the styled docs), and `subscribedSkus/{id}` declares `$select` but not `$expand` + (Identity.DirectoryManagement, KiotaCompat). Unconditional `-Property`/`-ExpandProperty` + bindings did not compile. +- **Decision:** item GETs and dispatchers now emit `$select`/`$expand` parameters only when + the operation declares them, per parameter set — the same declared-options mechanism list + GETs already used. +- **Migration impact:** cmdlets for endpoints without `$select`/`$expand` no longer expose + dead `-Property`/`-ExpandProperty` parameters (they never worked server-side). + +## Media/content endpoints return Stream regardless of declared JSON schema + +- **Class:** kiota-builder-shape +- **Status:** handled (skipped with a logged reason; pinned by regression test) +- **Evidence:** the styled docs attach an entity JSON schema to media endpoints + (`.../filesFolder/content`), but kiota generates `GetAsync` returning `System.IO.Stream` + for them — assigning that to an entity type does not compile (Teams, built from the + styled doc because kiota hangs on its KiotaCompat variant). The KiotaCompat docs declare + these endpoints without a JSON schema, so they were already skipped there. +- **Decision:** a GET whose success response also declares non-JSON content is a media + download and is skipped until stream support exists (same treatment as `$value`). +- **Migration impact:** content-download cmdlets (`Get-...Content`) are not generated yet; + tracked with the operation-shapes work. + +## PATCH-only resources have no GetAsync to re-fetch + +- **Class:** kiota-builder-shape +- **Status:** handled (pinned test) +- **Evidence:** Update cmdlets re-fetch after a bodiless 204; `/places/{place-id}` has no + GET, so the builder has no `GetAsync` and `Update-MgPlace` did not compile (Calendar). +- **Decision:** emit the re-fetch only when the path declares a GET; otherwise a bodiless + 204 returns nothing — matching the published SDK's Update behavior. +- **Migration impact:** none vs the published SDK. diff --git a/tools/WrapperGenerator/edge-cases/naming-edge-cases.md b/tools/WrapperGenerator/edge-cases/naming-edge-cases.md index 0c70d0a06e..e5d541e562 100644 --- a/tools/WrapperGenerator/edge-cases/naming-edge-cases.md +++ b/tools/WrapperGenerator/edge-cases/naming-edge-cases.md @@ -46,6 +46,7 @@ Entry template (keep the field names exact so the file converts cleanly): | Case | Class | Status | |---|---|---| | `HostWhoi` → `HostWhois` | inflection-defect | corrected | +| `PlaceCheck` → `PlaceCheckIn` | operationid-truncation | corrected | | operationId preposition truncation | operationid-truncation | structurally-avoided | | `SkypeForBusiness` subject truncation | operationid-truncation | not-yet-reachable | | `Cookies`/`Skus`/`Dns`/`Ios`/`Statistics` quirks | inflection-defect | reproduced-for-parity | @@ -69,6 +70,22 @@ Entry template (keep the field names exact so the file converts cleanly): - **References:** pinned in `AppliesDeliberateNameCorrections` (NamingTests.cs); gate rows in `$deliberateCorrections` (Compare-WrapperCmdletNames.ps1). +## CheckIns truncated to Check on the places API + +- **Class:** operationid-truncation +- **Status:** corrected +- **Evidence:** `/places/{place-id}/checkIns` shipped as `{Get,New,Update,Remove}-Mg(Beta)PlaceCheck` + (8 commands) — AutoRest truncated "CheckIns" at the preposition "In", the #912 defect + class. The SDK is inconsistent with itself: `Get-MgPlaceCheckInCount` (the `$count` path) + keeps "In" intact. Found by the parity gate during the full-inventory module fan-out. +- **Decision:** emit `...PlaceCheckIn` for all four verbs, v1.0 and beta; no alias for the + old names. Pinned in `AppliesDeliberateNameCorrections`; gate rows in + `$deliberateCorrections`. +- **Migration impact:** scripts using `*-MgPlaceCheck` must switch to `*-MgPlaceCheckIn`. + Belongs in the migration guide when the Calendar module ships for real. +- **References:** issue [#912](https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/912) + (the AutoRest defect class). + ## operationId preposition/linking-verb truncation - **Class:** operationid-truncation @@ -130,9 +147,8 @@ Entry template (keep the field names exact so the file converts cleanly): Cases spotted but deliberately not acted on yet, so they aren't lost: -- **`usageRights` vs `rights` (beta-only):** the shipped SDK keeps `usageRights` plural - (`Get-MgBetaDeviceUsageRights` for `/devices/{id}/usageRights`) but singularizes bare - `rights` (`Get-MgBetaGroupSiteInformationProtectionSensitivityLabelRight` for - `.../sensitivityLabels/{id}/rights`). Our rules match the bare-`rights` case and would - diverge on `usageRights`. All affected paths are beta; resolve when the beta parity audit - runs. +- **bare `rights` (beta-only):** "Rights" is now an invariant — v1.0 evidence arrived via + `subjectRightsRequests` (42 cmdlets ship keeping "Rights"; `usageRights` in beta agrees). + The one holdout is beta's bare `.../sensitivityLabels/{id}/rights`, which ships + singularized (`...SensitivityLabelRight`) and now diverges from our invariant. Beta-only, + 4 cmdlets; resolve at the beta parity audit (likely a correction or a path override). From 668a28d03358c6fade2c2017570ea1eaa6272877 Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Tue, 11 Aug 2026 10:25:40 -0700 Subject: [PATCH 07/11] fix(wrapper-generator): fail loudly on cmdlet file collisions A second operation resolving to an already-written cmdlet file now fails generation with the full collision list instead of silently overwriting it, which is the silent-drop failure mode AutoRest had. OData cast list/item pairs (owners/graph.user) now merge like plain pairs, and the sweep's collisions land as cited NamingOverrides entries: termStore and agreement-file stitches, default-singleton renames (SubSite, DefaultDrive, DefaultCalendarEvent), and nested navs the SDK never shipped. Remaining families are tracked on #3704. --- tools/Build-WrapperModule.ps1 | 14 +- .../GenerationServiceRegressionTests.cs | 77 ++++++++ tools/WrapperGenerator.Tests/NamingTests.cs | 66 ++++++- tools/WrapperGenerator/CmdletNaming.cs | 52 ++++- tools/WrapperGenerator/NamingOverrides.cs | 182 ++++++++++++++++-- .../PowerShellWrapperGenerationService.cs | 33 +++- tools/WrapperGenerator/README.md | 6 +- .../edge-cases/naming-edge-cases.md | 43 ++++- 8 files changed, 440 insertions(+), 33 deletions(-) diff --git a/tools/Build-WrapperModule.ps1 b/tools/Build-WrapperModule.ps1 index dc67dc464c..3a5a392c1d 100644 --- a/tools/Build-WrapperModule.ps1 +++ b/tools/Build-WrapperModule.ps1 @@ -143,7 +143,19 @@ function Build-OneModule { } $wrapperOut = & dotnet run --project $generatorProject -- -d $spec -o $cmdletsDir -n $clientNs 2>&1 - if ($LASTEXITCODE -ne 0) { $result.FailedAt = 'wrapper-generator'; $result.Error = ($wrapperOut | Select-Object -Last 3) -join ' | '; return $result } + if ($LASTEXITCODE -ne 0) { + # Skip warnings precede the failure; the exception message is what identifies it. + $result.FailedAt = 'wrapper-generator' + $lines = @($wrapperOut | ForEach-Object { "$_" }) + $exception = $lines | Where-Object { $_ -match 'Unhandled exception|Exception:' } | Select-Object -First 1 + $exceptionIndex = if ($exception) { $lines.IndexOf($exception) } else { -1 } + $result.Error = if ($exceptionIndex -ge 0) { + ($lines[$exceptionIndex..([Math]::Min($exceptionIndex + 5, $lines.Count - 1))] | Where-Object { $_ -notmatch '^\s+at ' }) -join ' | ' + } else { + ($lines | Where-Object { $_ -notmatch '^\s+at ' } | Select-Object -First 6) -join ' | ' + } + return $result + } # Generated artifact, machine-local by design (absolute reference into this clone). $csprojPath = Join-Path $srcDir "$moduleName.csproj" diff --git a/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs b/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs index 7275265a81..b63d68d244 100644 --- a/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs +++ b/tools/WrapperGenerator.Tests/GenerationServiceRegressionTests.cs @@ -181,6 +181,83 @@ public async Task GenerateAsync_SkipsUnsupportedODataPathSegments_DoesNotEmitMal Assert.DoesNotContain(files, f => f != "Shared.g.cs"); } + // Two operations resolving to the same cmdlet file must fail generation loudly, + // identifying both operations — never silently overwrite. The real shipped collision + // (/sites/{id}/sites) is renamed via NamingOverrides, so a synthetic self-referential + // path keeps the guard itself exercised. + [Fact] + public async Task GenerateAsync_FailsLoudlyWhenTwoCmdletsResolveToTheSameFile() + { + var document = new OpenApiDocument + { + Paths = new OpenApiPaths(), + Components = new OpenApiComponents + { + Schemas = new Dictionary + { + ["microsoft.graph.widget"] = new OpenApiSchema + { + Type = JsonSchemaType.Object, + Properties = new Dictionary + { + ["displayName"] = new OpenApiSchema { Type = JsonSchemaType.String }, + }, + }, + }, + }, + }; + + static OpenApiOperation ItemGet(OpenApiDocument doc) => new() + { + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponse + { + Content = new Dictionary + { + ["application/json"] = new OpenApiMediaType + { + Schema = new OpenApiSchemaReference("microsoft.graph.widget", doc), + }, + }, + }, + }, + }; + + // /widgets/{id} and /widgets/{id}/widgets/{id2} both singularize to the noun Widget; + // with two same-noun item GETs nothing merges, and both emit GetMgWidget.g.cs. + document.Paths["/widgets/{widget-id}"] = new OpenApiPathItem + { + Operations = new Dictionary { [HttpMethod.Get] = ItemGet(document) }, + }; + document.Paths["/widgets/{widget-id}/widgets/{widget-id1}"] = new OpenApiPathItem + { + Operations = new Dictionary { [HttpMethod.Get] = ItemGet(document) }, + }; + + var outputDir = Path.Combine(Path.GetTempPath(), "wrapper-generator-tests", Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(outputDir); + try + { + var config = new GeneratorConfig("Microsoft.Graph.PowerShell.Test.Client", outputDir); + var service = new PowerShellWrapperGenerationService(document, config, NullLogger.Instance); + + var ex = await Assert.ThrowsAsync(() => service.GenerateAsync(CancellationToken.None)); + + Assert.Contains("GetMgWidget.g.cs", ex.Message); + Assert.Contains("collision", ex.Message); + // Both colliding cmdlets are named Get-MgWidget, so only their builder expressions + // prove the message identifies both operations. + Assert.Contains("[Widgets[WidgetId]]", ex.Message); + Assert.Contains("Widgets[WidgetId].Widgets[WidgetId1]", ex.Message); + } + finally + { + if (Directory.Exists(outputDir)) + Directory.Delete(outputDir, recursive: true); + } + } + private static OpenApiDocument BuildDocument(HttpMethod method, string path, OpenApiOperation operation) { return new OpenApiDocument diff --git a/tools/WrapperGenerator.Tests/NamingTests.cs b/tools/WrapperGenerator.Tests/NamingTests.cs index 3f101ae752..3e8c8ebca6 100644 --- a/tools/WrapperGenerator.Tests/NamingTests.cs +++ b/tools/WrapperGenerator.Tests/NamingTests.cs @@ -110,6 +110,19 @@ private static CmdletNaming Resolve(string method, string path) => [InlineData("GET", "/solutions/bookingBusinesses/{bookingBusiness-id}", "Get", "MgBookingBusiness")] [InlineData("PATCH", "/solutions/bookingBusinesses/{bookingBusiness-id}", "Update", "MgBookingBusiness")] [InlineData("GET", "/users/{user-id}/calendar", "Get", "MgUserDefaultCalendar")] + // self-referential sites rename to SubSite instead of colliding with the parent noun + [InlineData("GET", "/sites/{site-id}/sites", "Get", "MgSubSite")] + [InlineData("GET", "/sites/{site-id}/sites/{site-id1}", "Get", "MgSubSite")] + [InlineData("GET", "/groups/{group-id}/sites/{site-id}/sites", "Get", "MgGroupSubSite")] + [InlineData("GET", "/groups/{group-id}/sites/{site-id}/sites/{site-id1}", "Get", "MgGroupSubSite")] + // default-singleton renames (issue #3704 oracle sweep) + [InlineData("GET", "/users/{user-id}/drive", "Get", "MgUserDefaultDrive")] + [InlineData("GET", "/groups/{group-id}/drive", "Get", "MgGroupDefaultDrive")] + [InlineData("GET", "/sites/{site-id}/drive", "Get", "MgSiteDefaultDrive")] + [InlineData("GET", "/groups/{group-id}/sites/{site-id}/drive", "Get", "MgGroupSiteDefaultDrive")] + [InlineData("GET", "/users/{user-id}/calendar/events", "Get", "MgUserDefaultCalendarEvent")] + // nested-collection GET renamed by the Groups.md directive (subject $1ByGroup) + [InlineData("GET", "/groups/{group-id}/groupLifecyclePolicies", "Get", "MgGroupLifecyclePolicyByGroup")] // boundary word-overlap collapse (Get-MgDomainNameReference) [InlineData("GET", "/domains/{domain-id}/domainNameReferences", "Get", "MgDomainNameReference")] // adjacent-duplicate collapse (Get-MgUserOnenoteSectionGroup... family) @@ -177,6 +190,34 @@ public void SuppressesOperationsThePublishedSdkOmits() Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/solutions")); Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Patch, "/solutions")); Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/solutions/bookingBusinesses/{bookingBusiness-id}")); + + // The /photos collection ships no distinct cmdlet; only the /photo singleton does. + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/users/{user-id}/photos")); + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/users/{user-id}/photos/{userProfilePhoto-id}")); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/users/{user-id}/photo")); + + // Suffix-matched suppressions apply under any root; siblings stay generated + // (issue #3704: Info-wrapper navs ship nothing, their siblings ship). + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/chats/{chat-id}/pinnedMessages/{pinnedChatMessageInfo-id}/message")); + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/teams/{team-id}/channels/{channel-id}/sharedWithTeams/{id}/team")); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/teams/{team-id}/channels/{channel-id}/sharedWithTeams/{id}/allowedMembers")); + + // Exact-matched suppressions cover only the named node; descendants with no entry of + // their own stay generated (Security nested navs, issue #3704). + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/security/threatIntelligence/hosts/{host-id}/components")); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/security/threatIntelligence/hosts/{host-id}/components/$count")); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/security/threatIntelligence/hosts/{host-id}/passiveDns")); + + // termStore trees are stitched: /termStores/{id} descendants ship nothing (the 402 + // descendant command rows come from the /termStore singleton trees), and the singleton + // root GET ships no distinct cmdlet (Get-MgSiteTermStore serves both /termStore and + // /termStores; GET generates from the collection side only). + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/sites/{site-id}/termStores/{store-id}")); + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/sites/{site-id}/termStores/{store-id}/sets/{set-id}")); + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/sites/{site-id}/termStore")); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Patch, "/sites/{site-id}/termStore")); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/sites/{site-id}/termStores")); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/sites/{site-id}/termStore/sets/{set-id}")); } [Theory] @@ -228,14 +269,29 @@ public void GetWithNoStructuralPartnerStaysStandalone() } [Fact] - public void AmbiguousSameNounDoesNotMerge() + public void CastListItemPairMergesLikeAPlainPair() + { + // The published SDK ships one Get-MgGroupOwnerAsUser covering both the cast on the + // collection and the cast on the item; without pairing, both emit the same file. + var list = Resolve("GET", "/groups/{group-id}/owners/graph.user"); + var item = Resolve("GET", "/groups/{group-id}/owners/{directoryObject-id}/graph.user"); + Assert.Equal(list.Noun, item.Noun); + Assert.True(Naming.IsListItemPair(list, item)); + + // Different cast types never pair. + var otherCast = Resolve("GET", "/groups/{group-id}/owners/{directoryObject-id}/graph.servicePrincipal"); + Assert.False(Naming.IsListItemPair(list, otherCast)); + } + + [Fact] + public void SelfReferentialSitesRenameInsteadOfCollidingWithParent() { - // Self-referential /sites: the collection /sites/{id}/sites and the single /sites/{id} - // both resolve to MgSite, but the "item" is the parent, not a child one id deeper, so - // the structural check rejects the merge and both stay standalone. + // Without the SubSite rename, /sites/{id}/sites singularizes to the parent's own noun + // and its cmdlet file would collide with Get-MgSite's. The renamed nouns are pinned in + // ResolvesPublishedSdkNames; this pins that the pair no longer merges or collides. var list = Resolve("GET", "/sites/{site-id}/sites"); var item = Resolve("GET", "/sites/{site-id}"); - Assert.Equal(list.Noun, item.Noun); + Assert.NotEqual(list.Noun, item.Noun); Assert.False(Naming.IsListItemPair(list, item)); } } diff --git a/tools/WrapperGenerator/CmdletNaming.cs b/tools/WrapperGenerator/CmdletNaming.cs index 6cf4339687..a9836723e2 100644 --- a/tools/WrapperGenerator/CmdletNaming.cs +++ b/tools/WrapperGenerator/CmdletNaming.cs @@ -197,16 +197,54 @@ private static string ToCastAwareBuilderMemberName(string segment) => : segment.ToFirstCharacterUpperCase(); // Whether a list GET and an item GET form a mergeable pair for the public Get-MgX - // dispatcher: the item's path must be the list's path plus exactly one trailing id - // (Users[UserId].Messages -> Users[UserId].Messages[MessageId]). Callers group by noun - // first, so this only decides the structural fit; a same-noun item that does not extend the - // list (for example the self-referential /sites/{id} vs /sites/{id}/sites) is rejected. + // dispatcher: the item's path must extend the list's path by exactly one id, either + // trailing (Users[UserId].Messages -> Users[UserId].Messages[MessageId]) or inserted + // before a shared trailing OData cast (Owners.GraphUser -> Owners[Id].GraphUser). Callers + // group by noun first, so this only decides the structural fit; a same-noun item that does + // not extend the list is rejected. public static bool IsListItemPair(CmdletNaming list, CmdletNaming item) { ArgumentNullException.ThrowIfNull(list); ArgumentNullException.ThrowIfNull(item); - return item.PathParamNames.Count == list.PathParamNames.Count + 1 - && item.PathParamNames.Take(list.PathParamNames.Count).SequenceEqual(list.PathParamNames) - && item.BuilderExpression.StartsWith(list.BuilderExpression + "[", StringComparison.Ordinal); + if (item.PathParamNames.Count != list.PathParamNames.Count + 1 + || !item.PathParamNames.Take(list.PathParamNames.Count).SequenceEqual(list.PathParamNames)) + return false; + + if (item.BuilderExpression.StartsWith(list.BuilderExpression + "[", StringComparison.Ordinal)) + return true; + + // OData cast pair: the id inserts BEFORE the trailing cast member, not at the end + // (owners/graph.user vs owners/{id}/graph.user builds Owners.GraphUser vs + // Owners[Id].GraphUser). The published SDK ships these as one cmdlet, same as a + // plain list/item pair; without this the two emit identical file names and collide. + var listCast = TrailingCastMember(list.BuilderExpression); + var itemCast = TrailingCastMember(item.BuilderExpression); + if (listCast is null || !string.Equals(listCast, itemCast, StringComparison.Ordinal)) + return false; + + var listStem = list.BuilderExpression[..^(listCast.Length + 1)]; + var itemStem = item.BuilderExpression[..^(itemCast.Length + 1)]; + if (!itemStem.StartsWith(listStem + "[", StringComparison.Ordinal) || !itemStem.EndsWith("]", StringComparison.Ordinal)) + return false; + var indexer = itemStem[(listStem.Length + 1)..^1]; + return indexer.Length > 0 && !indexer.Contains('[') && !indexer.Contains('.'); + } + + // The kiota builder member for a trailing OData cast segment (GraphUser from + // "graph.user", MicrosoftGraphUser from "microsoft.graph.user"); null when the + // expression does not end in a cast. + private static string? TrailingCastMember(string builderExpression) + { + var lastDot = builderExpression.LastIndexOf('.'); + if (lastDot < 0) + return null; + var member = builderExpression[(lastDot + 1)..]; + if (member.Contains('[')) + return null; + if (member.StartsWith("MicrosoftGraph", StringComparison.Ordinal) && member.Length > 14 && char.IsUpper(member[14])) + return member; + if (member.StartsWith("Graph", StringComparison.Ordinal) && member.Length > 5 && char.IsUpper(member[5])) + return member; + return null; } } diff --git a/tools/WrapperGenerator/NamingOverrides.cs b/tools/WrapperGenerator/NamingOverrides.cs index db36576a21..3aae42bfc8 100644 --- a/tools/WrapperGenerator/NamingOverrides.cs +++ b/tools/WrapperGenerator/NamingOverrides.cs @@ -7,12 +7,13 @@ namespace WrapperGenerator; // Hand-tuned naming exceptions, kept as data with a cited source on every entry. // -// The published Microsoft.Graph names are mostly algorithmic, but a few come from -// hand-written AutoRest directives in the msgraph-sdk-powershell module configs. Matching -// the published names 100% means mirroring those directives here. +// The published Microsoft.Graph names are mostly algorithmic. Entries here cover the rest: +// renames from hand-written AutoRest directives in the msgraph-sdk-powershell module +// configs, and suppressions for spec routes the published SDK ships nothing for. // -// Keep this list short. Add an entry only when the published name cannot come out of the -// naming rules, and cite the directive that created it. +// Add an entry only when the published surface cannot come out of the naming rules, and +// cite the evidence: the directive when one exists, otherwise the shipped-command +// inventory (the oracle, MgCommandMetadata.json). public static partial class NamingOverrides { private enum OverrideKind @@ -22,33 +23,185 @@ private enum OverrideKind StripNounPrefix, } - private sealed record Entry(OverrideKind Kind, HttpMethod? Method, string PathPrefix, bool ExactPath, string? Value, string Reason); + // How Pattern is matched against the normalized path: the full path (Exact), its start + // (Prefix), or its end (Suffix — for navs that recur under many roots, like + // .../resourceRoleScopes/{}/scope appearing under several parents). + private enum PathMatch + { + Exact, + Prefix, + Suffix, + } + + private sealed record Entry(OverrideKind Kind, HttpMethod? Method, string Pattern, PathMatch Match, string? Value, string Reason); private static readonly List Entries = [ // The SDK ships no Update cmdlet for /users/{id}/calendar. Its pipeline removes the // operation outright, in src/Calendar/Calendar.md: remove-path-by-operation // user_UpdateCalendar. The wrapper must not invent a cmdlet the SDK chose to drop. - new(OverrideKind.SuppressOperation, HttpMethod.Patch, "/users/{}/calendar", ExactPath: true, Value: null, + new(OverrideKind.SuppressOperation, HttpMethod.Patch, "/users/{}/calendar", Match: PathMatch.Exact, Value: null, Reason: "Calendar.md remove-path-by-operation user_UpdateCalendar"), // GET /users/{id}/calendar ships as Get-MgUserDefaultCalendar, renamed in // src/Calendar/Calendar.md: "^(User)(Calendar)$" -> "$1Default$2". - new(OverrideKind.ReplaceNoun, HttpMethod.Get, "/users/{}/calendar", ExactPath: true, Value: "UserDefaultCalendar", + new(OverrideKind.ReplaceNoun, HttpMethod.Get, "/users/{}/calendar", Match: PathMatch.Exact, Value: "UserDefaultCalendar", Reason: "Calendar.md directive renames UserCalendar to UserDefaultCalendar"), // The SDK ships no cmdlets for the /solutions root singleton itself (Get-MgSolution / // Update-MgSolution do not exist): src/Bookings/Bookings.md removes every solutionsRoot // operation with remove-path-by-operation ^solution\.solutionsRoot.*$. Exact-path, all // methods, so operations on children like /solutions/bookingBusinesses are unaffected. - new(OverrideKind.SuppressOperation, Method: null, "/solutions", ExactPath: true, Value: null, + new(OverrideKind.SuppressOperation, Method: null, "/solutions", Match: PathMatch.Exact, Value: null, Reason: "Bookings.md remove-path-by-operation ^solution\\.solutionsRoot.*$"), // Most nouns under /solutions/ drop the "Solution" prefix (for example // Get-MgBookingBusiness, Get-MgVirtualEventWebinar). BackupRestore is a known // exception where published cmdlets keep the Solution prefix. - new(OverrideKind.StripNounPrefix, Method: null, "/solutions/", ExactPath: false, Value: "Solution", + new(OverrideKind.StripNounPrefix, Method: null, "/solutions/", Match: PathMatch.Prefix, Value: "Solution", Reason: "Bookings/VirtualEvents naming pattern under /solutions/*; BackupRestore is explicitly excluded in ApplyNounOverrides"), + + // The spec carries two parallel termStore trees; the shipped surface stitches them: + // GET/POST come from the /termStores collection (Get-MgSiteTermStore, New-...), while + // PATCH/DELETE and all 402 descendant command rows come from the /termStore singleton. + // Nothing ships under /termStores/{id}, and the singleton root GET has no distinct + // cmdlet — generating either would collide with its shipped twin. + new(OverrideKind.SuppressOperation, Method: null, "/sites/{}/termstores/{}", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: zero commands under /termStores/{id}; descendants ship from the /termStore singleton tree"), + new(OverrideKind.SuppressOperation, HttpMethod.Get, "/sites/{}/termstore", Match: PathMatch.Exact, Value: null, + Reason: "oracle: Get-MgSiteTermStore serves GET /termStore and /termStores; GET generates from the collection side only"), + new(OverrideKind.SuppressOperation, Method: null, "/groups/{}/sites/{}/termstores/{}", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: zero commands under /termStores/{id}; descendants ship from the /termStore singleton tree"), + new(OverrideKind.SuppressOperation, HttpMethod.Get, "/groups/{}/sites/{}/termstore", Match: PathMatch.Exact, Value: null, + Reason: "oracle: Get-MgGroupSiteTermStore serves GET /termStore and /termStores; GET generates from the collection side only"), + + // Get-MgUserPhoto serves both /photo and /photos; the /photos routes ship no distinct + // cmdlet, and generating them would collide with the singleton's noun. + new(OverrideKind.SuppressOperation, Method: null, "/users/{}/photos", Match: PathMatch.Exact, Value: null, + Reason: "oracle: Get-MgUserPhoto serves /photo and /photos; the collection ships no distinct cmdlet"), + new(OverrideKind.SuppressOperation, Method: null, "/users/{}/photos/{}", Match: PathMatch.Exact, Value: null, + Reason: "oracle: /photos/{} ships nothing; the photo surface is the /photo singleton"), + + // Self-referential /sites: singularizing sites/{id}/sites collapses to the parent's + // noun, so the sub-sites cmdlets would overwrite Get-MgSite. The SDK ships them + // renamed: Get-MgSubSite and Get-MgGroupSubSite (v1.0 and beta, incl. $count). + new(OverrideKind.ReplaceNoun, Method: null, "/sites/{}/sites", Match: PathMatch.Exact, Value: "SubSite", + Reason: "Sites.md directive; oracle ships Get-MgSubSite for /sites/{site-id}/sites"), + new(OverrideKind.ReplaceNoun, Method: null, "/sites/{}/sites/{}", Match: PathMatch.Exact, Value: "SubSite", + Reason: "Sites.md directive; oracle ships Get-MgSubSite for /sites/{site-id}/sites/{site-id1}"), + new(OverrideKind.ReplaceNoun, Method: null, "/groups/{}/sites/{}/sites", Match: PathMatch.Exact, Value: "GroupSubSite", + Reason: "Sites.md directive; oracle ships Get-MgGroupSubSite"), + new(OverrideKind.ReplaceNoun, Method: null, "/groups/{}/sites/{}/sites/{}", Match: PathMatch.Exact, Value: "GroupSubSite", + Reason: "Sites.md directive; oracle ships Get-MgGroupSubSite"), + + // ---- Collision resolutions from the full-inventory oracle sweep (issue #3704). ---- + + // Identity.Governance: agreement file item ops ship only from the /file singleton + // (Update/Remove-MgAgreementFile); /files/{} items ship nothing, /files/{}/versions does. + new(OverrideKind.SuppressOperation, Method: null, "/agreements/{}/files/{}", Match: PathMatch.Exact, Value: null, + Reason: "oracle: /files/{} item ops ship nothing; file surface is the /file singleton (Update/Remove-MgAgreementFile)"), + new(OverrideKind.SuppressOperation, Method: null, "/identitygovernance/termsofuse/agreements/{}/files/{}", Match: PathMatch.Exact, Value: null, + Reason: "oracle: ships nothing; mirrors /agreements/{}/files/{} suppression"), + // GET of the file/files pair ships from the collection (same command on both URIs), + // like the termStore root stitch; Update/Remove stay on the singleton. + new(OverrideKind.SuppressOperation, HttpMethod.Get, "/agreements/{}/file", Match: PathMatch.Exact, Value: null, + Reason: "oracle: Get-MgAgreementFile serves /file and /files; GET generated from the collection side only"), + new(OverrideKind.SuppressOperation, HttpMethod.Get, "/identitygovernance/termsofuse/agreements/{}/file", Match: PathMatch.Exact, Value: null, + Reason: "oracle: Get-MgIdentityGovernanceTermsOfUseAgreementFile serves /file and /files; GET from the collection side only"), + // The /scope node duplicates its parent's noun and ships nothing anywhere; its + // children ship with the Scope segment elided (…ResourceRoleScopeResource). + new(OverrideKind.SuppressOperation, Method: null, "/resourcerolescopes/{}/scope", Match: PathMatch.Suffix, Value: null, + Reason: "oracle: the /scope node ships nothing under any parent; children ship with Scope elided"), + new(OverrideKind.SuppressOperation, Method: null, "/identitygovernance/entitlementmanagement/assignments/{}/assignmentpolicy", Match: PathMatch.Exact, Value: null, + Reason: "nav duplicate of /assignmentPolicies (Get-MgEntitlementManagementAssignmentPolicy); ships nothing"), + new(OverrideKind.SuppressOperation, Method: null, "/identitygovernance/entitlementmanagement/resources/{}/environment", Match: PathMatch.Exact, Value: null, + Reason: "nav duplicate of /resourceEnvironments (Get-MgEntitlementManagementResourceEnvironment); ships nothing"), + new(OverrideKind.SuppressOperation, Method: null, "/identitygovernance/lifecycleworkflows", Match: PathMatch.Exact, Value: null, + Reason: "the container node's own operations ship nothing; its children ship"), + new(OverrideKind.SuppressOperation, Method: null, "/identitygovernance/termsofuse/agreements/{}/acceptances", Match: PathMatch.Prefix, Value: null, + Reason: "ships nothing; acceptances ship from /termsOfUse/agreementAcceptances (Get-MgIdentityGovernanceTermsOfUseAgreementAcceptance)"), + + // Security threatIntelligence: nested navs under articles/{} and hosts/{} duplicate + // the shipped top-level sets (articleIndicators, hostComponents, hostCookies, + // hostPairs, hostPorts, hostSslCertificates, hostTrackers) and ship nothing + // themselves. Exact-only: two of these navs have shipped $count children + // (Get-MgSecurityThreatIntelligenceHost{SslCertificate,Tracker}Count); the other five + // ship no children at all. + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/articles/{}/indicators", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level articleIndicators ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/articles/{}/indicators/{}", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level articleIndicators ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/components", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostComponents ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/components/{}", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostComponents ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/cookies", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostCookies ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/cookies/{}", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostCookies ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/hostpairs", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostPairs ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/hostpairs/{}", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostPairs ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/ports", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostPorts ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/ports/{}", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostPorts ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/sslcertificates", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostSslCertificates ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/sslcertificates/{}", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostSslCertificates ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/trackers", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostTrackers ships"), + new(OverrideKind.SuppressOperation, Method: null, "/security/threatintelligence/hosts/{}/trackers/{}", Match: PathMatch.Exact, Value: null, Reason: "oracle: ships nothing; top-level hostTrackers ships"), + // The attackSimulation container node itself ships nothing; children under a + // simulation item ship nothing either (the list/item pair then merges normally). + new(OverrideKind.SuppressOperation, Method: null, "/security/attacksimulation", Match: PathMatch.Exact, Value: null, + Reason: "oracle: the container node ships nothing; its child collections ship"), + new(OverrideKind.SuppressOperation, Method: null, "/security/attacksimulation/simulations/{}/", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: nothing under a simulation item ships in v1.0"), + + // Calendar: the shipped default-calendar surface. Events under a NAMED calendar and + // the default-calendar event item tree ship nothing; event items ship from + // /users/{}/events (Get-MgUserEvent family). + new(OverrideKind.ReplaceNoun, Method: null, "/users/{}/calendar/events", Match: PathMatch.Exact, Value: "UserDefaultCalendarEvent", + Reason: "oracle: list/create ship as Get/New-MgUserDefaultCalendarEvent"), + new(OverrideKind.SuppressOperation, Method: null, "/users/{}/calendar/events/{}", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: default-calendar event items ship nothing; items ship from /users/{}/events/{}"), + new(OverrideKind.SuppressOperation, Method: null, "/users/{}/calendars/{}/events/{}", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: named-calendar event items ship nothing; items ship from /users/{}/events/{}"), + new(OverrideKind.SuppressOperation, Method: null, "/users/{}/calendars/{}/calendarpermissions", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: permissions ship only from the default calendar (Get-MgUserCalendarPermission on /users/{}/calendar/calendarPermissions)"), + + // Teams Info-wrapper navs: the wrapped single-entity navigation ships nothing under + // any root. The suffix matches just the nav node, so shipped siblings + // (…SharedWithTeamAllowedMember) are unaffected. + new(OverrideKind.SuppressOperation, Method: null, "/pinnedmessages/{}/message", Match: PathMatch.Suffix, Value: null, + Reason: "oracle: ships nothing under any root; list side ships (Get-MgChatPinnedMessage)"), + new(OverrideKind.SuppressOperation, Method: null, "/sharedwithteams/{}/team", Match: PathMatch.Suffix, Value: null, + Reason: "oracle: ships nothing; sibling /allowedMembers ships, so node-only"), + new(OverrideKind.SuppressOperation, Method: null, "/associatedteams/{}/team", Match: PathMatch.Suffix, Value: null, + Reason: "oracle: ships nothing; list side ships (Get-MgUserTeamworkAssociatedTeam)"), + + // Groups: the nested lifecycle-policies GET ships renamed; everything else on that + // route ships from the top-level set. Photos items ship nothing (singleton /photo). + new(OverrideKind.ReplaceNoun, HttpMethod.Get, "/groups/{}/grouplifecyclepolicies", Match: PathMatch.Exact, Value: "GroupLifecyclePolicyByGroup", + Reason: "Groups.md directive (subject $1ByGroup); oracle ships Get-MgGroupLifecyclePolicyByGroup"), + new(OverrideKind.SuppressOperation, Method: null, "/groups/{}/grouplifecyclepolicies/", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: item/children under the nested route ship nothing; the set ships top-level"), + new(OverrideKind.SuppressOperation, Method: null, "/groups/{}/photos/{}", Match: PathMatch.Exact, Value: null, + Reason: "oracle: photos items ship nothing; shipped surface is the /photo singleton (Get-MgGroupPhoto)"), + + // Small-module resolutions. + new(OverrideKind.SuppressOperation, Method: null, "/solutions/virtualevents", Match: PathMatch.Exact, Value: null, + Reason: "oracle: the virtualEvents root node ships nothing; children ship (Get-MgVirtualEventWebinar)"), + new(OverrideKind.SuppressOperation, Method: null, "/replies/{}/replyto", Match: PathMatch.Suffix, Value: null, + Reason: "oracle: the replyTo nav ships nothing under any root"), + new(OverrideKind.SuppressOperation, Method: null, "/deviceappmanagement/mobileapps/{}/categories", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: nested app categories ship nothing; the set ships top-level (mobileAppCategories)"), + new(OverrideKind.SuppressOperation, Method: null, "/education/classes/{}/assignments/{}/categories", Match: PathMatch.Exact, Value: null, + Reason: "oracle: the plain path ships nothing; the shipped surface is the $ref route"), + new(OverrideKind.SuppressOperation, Method: null, "/education/users/{}/user", Match: PathMatch.Exact, Value: null, + Reason: "oracle: the user self-nav node ships nothing; its children (mailboxSettings) ship"), + new(OverrideKind.ReplaceNoun, HttpMethod.Get, "/groups/{}/drive", Match: PathMatch.Exact, Value: "GroupDefaultDrive", + Reason: "Files.md directive (subject $1Default$2); oracle ships Get-MgGroupDefaultDrive"), + new(OverrideKind.ReplaceNoun, HttpMethod.Get, "/users/{}/drive", Match: PathMatch.Exact, Value: "UserDefaultDrive", + Reason: "Files.md directive (subject $1Default$2); oracle ships Get-MgUserDefaultDrive"), + new(OverrideKind.ReplaceNoun, HttpMethod.Get, "/sites/{}/drive", Match: PathMatch.Exact, Value: "SiteDefaultDrive", + Reason: "oracle ships Get-MgSiteDefaultDrive for the site default-drive singleton"), + new(OverrideKind.ReplaceNoun, HttpMethod.Get, "/groups/{}/sites/{}/drive", Match: PathMatch.Exact, Value: "GroupSiteDefaultDrive", + Reason: "oracle ships Get-MgGroupSiteDefaultDrive"), + new(OverrideKind.SuppressOperation, HttpMethod.Get, "/shares/{}/list/items/{}", Match: PathMatch.Exact, Value: null, + Reason: "oracle: the bare shared-list item GET ships nothing; its descendants ship"), + new(OverrideKind.SuppressOperation, Method: null, "/identityproviders", Match: PathMatch.Prefix, Value: null, + Reason: "oracle: the deprecated top-level /identityProviders set ships nothing in v1.0; shipped surface is /identity/identityProviders (Get-MgIdentityProvider)"), ]; [GeneratedRegex(@"\{[^}]*\}")] @@ -107,8 +260,11 @@ private static bool Matches(Entry entry, HttpMethod httpMethod, string normalize // HttpMethod's own equality is case-insensitive, so no string comparison is needed. if (entry.Method is not null && entry.Method != httpMethod) return false; - return entry.ExactPath - ? string.Equals(normalizedPath, entry.PathPrefix, StringComparison.Ordinal) - : normalizedPath.StartsWith(entry.PathPrefix, StringComparison.Ordinal); + return entry.Match switch + { + PathMatch.Exact => string.Equals(normalizedPath, entry.Pattern, StringComparison.Ordinal), + PathMatch.Prefix => normalizedPath.StartsWith(entry.Pattern, StringComparison.Ordinal), + _ => normalizedPath.EndsWith(entry.Pattern, StringComparison.Ordinal), + }; } } diff --git a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs index f339190253..b0b1edd923 100644 --- a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs +++ b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs @@ -20,6 +20,12 @@ public sealed partial class PowerShellWrapperGenerationService private readonly GeneratorConfig config; private readonly ILogger logger; private readonly HashSet modelSubNamespaces; + + // Every file written this run, keyed case-insensitively (Windows file systems are), so a + // second cmdlet resolving to an existing file is a detected collision instead of a silent + // overwrite. + private readonly Dictionary writtenCmdletFiles = new(StringComparer.OrdinalIgnoreCase); + private readonly List fileCollisions = []; private readonly Dictionary kiotaReservedRenames; public PowerShellWrapperGenerationService(OpenApiDocument document, GeneratorConfig configuration, ILogger logger) @@ -96,6 +102,9 @@ public async Task GenerateAsync(CancellationToken cancellationToken) var ctx = new EmitContext(ClientNamespace: config.ClientNamespaceName); + writtenCmdletFiles.Clear(); + fileCollisions.Clear(); + Directory.CreateDirectory(config.OutputPath); foreach (var stale in Directory.GetFiles(config.OutputPath, "*.g.cs")) File.Delete(stale); @@ -198,6 +207,15 @@ public async Task GenerateAsync(CancellationToken cancellationToken) written += await EmitGetOperationsAsync(getOperations, ctx, cancellationToken).ConfigureAwait(false); + // All collisions for the run are reported together so one generation surfaces the + // complete list; see edge-cases/naming-edge-cases.md for how each kind is resolved. + if (fileCollisions.Count > 0) + { + throw new InvalidOperationException( + $"{fileCollisions.Count} cmdlet name collision(s): a later operation would overwrite an already-written cmdlet file. " + + $"Resolve each with a NamingOverrides rename or suppression.\n " + string.Join("\n ", fileCollisions)); + } + LogWroteFiles(written + 1, config.OutputPath); } @@ -208,9 +226,9 @@ public async Task GenerateAsync(CancellationToken cancellationToken) // which one to invoke. // // A pairing is only trusted when it is structurally unambiguous: exactly one collection GET - // and one single-entity GET share the noun, and the item's path is the list's path plus one - // trailing id (Users[UserId].Messages -> Users[UserId].Messages[MessageId]). Everything - // else keeps the standalone shape: singleton navs with no list (GET /users/{id}/calendar), + // and one single-entity GET share the noun, and the item's path extends the list's path by + // exactly one id, in either of the shapes Naming.IsListItemPair accepts. Everything else + // keeps the standalone shape: singleton navs with no list (GET /users/{id}/calendar), // list-only endpoints such as delta queries, or an unexpected same-noun collision. private async Task EmitGetOperationsAsync(List getOperations, EmitContext ctx, CancellationToken cancellationToken) { @@ -298,6 +316,15 @@ private async Task EmitGetOperationsAsync(List getOpera private async Task WriteCmdletFileAsync(CmdletNaming naming, string source, CancellationToken cancellationToken) { var fileName = naming.ClassName.Replace("Command", "", StringComparison.Ordinal) + ".g.cs"; + // Both colliding cmdlets usually share the same name, so the builder expression (the + // request path) is what actually identifies which two operations collided. + var cmdletName = $"{naming.VerbName}-{naming.Noun} [{naming.BuilderExpression}]"; + if (writtenCmdletFiles.TryGetValue(fileName, out var existing)) + { + fileCollisions.Add($"{fileName}: '{cmdletName}' collides with already-written '{existing}'"); + return 0; + } + writtenCmdletFiles[fileName] = cmdletName; await File.WriteAllTextAsync(Path.Combine(config.OutputPath, fileName), source, cancellationToken).ConfigureAwait(false); LogWroteCmdletFile(fileName, naming.VerbName, naming.Noun); return 1; diff --git a/tools/WrapperGenerator/README.md b/tools/WrapperGenerator/README.md index caab1d5e93..eaf37248be 100644 --- a/tools/WrapperGenerator/README.md +++ b/tools/WrapperGenerator/README.md @@ -52,7 +52,7 @@ Singularization runs per camel-case word (so `termsAndConditions` → `TermAndCo | ends in `ss`/`us`/`is` stays | `Access`, `Status`, `Analysis` | | trailing `s` drops | `Messages` → `Message` | -A few published names aren't algorithmic — they come from hand-written directives in the SDK's module configs. Those live as data in `NamingOverrides.cs`, each with a cited source, rather than as special cases in the naming code. There are three today: suppress `PATCH /users/{id}/calendar` (the SDK ships no such cmdlet), rename `GET /users/{id}/calendar` to `…UserDefaultCalendar`, and strip the `Solution` prefix for most `/solutions/*` nouns (for example, `Get-MgBookingBusiness`, not `Get-MgSolutionBookingBusiness`) while preserving it for known exceptions such as BackupRestore (`Get-MgSolutionBackupRestore`). +A few published names aren't algorithmic, and the spec publishes some routes the SDK never shipped. Both live as data in `NamingOverrides.cs` — renames mirroring the SDK's hand-written AutoRest directives, and suppressions for routes that ship nothing — each entry citing its evidence: the directive when one exists, otherwise the shipped-command inventory. Examples: the `GET /users/{id}/calendar` rename to `…UserDefaultCalendar` (Calendar.md), the `Solution` prefix strip under `/solutions/*` with the BackupRestore exception (Bookings.md), and the self-referential `sites/{id}/sites` rename to `SubSite`/`GroupSubSite` (Sites.md) — without which the sub-sites cmdlets would collide with `Get-MgSite` itself. The generator fails loudly on any such file collision rather than silently overwriting. ## The one subtle part: list + item GET become one cmdlet @@ -126,7 +126,7 @@ The wrappers compile and run only alongside step 1's output. Wiring the two into | `PowerShellWrapperGenerationService.cs` | The orchestrator: walks the paths, pairs list/item GETs, writes the files | | `CmdletNaming.cs` | Verb + noun + the `client.X[Y].Z` request chain | | `Singularizer.cs` | The per-word singularization rules | -| `NamingOverrides.cs` | The three hand-cited name exceptions | +| `NamingOverrides.cs` | Cited rename/suppression data mirroring the shipped SDK surface | | `CmdletEmitter.cs` | The C# templates for each cmdlet shape (the actual code text) | | `SchemaProperties.cs` | Which body properties become `New`/`Update` parameters | | `OperationInfo.cs`, `EmitContext.cs`, `GeneratorConfig.cs` | Small data/config carriers | @@ -157,7 +157,7 @@ dotnet run --project tools/WrapperGenerator -- ` ```powershell # 1. Naming rules pinned to published Microsoft.Graph names dotnet test tools/WrapperGenerator.Tests -# => Passed! - Failed: 0, Passed: 103, Total: 103 +# => Passed! - Failed: 0, Passed: 115, Total: 115 # 2. Parity gate: generate, then check every cmdlet name against Graph's own command inventory .\tools\Compare-WrapperCmdletNames.ps1 -GeneratedPath diff --git a/tools/WrapperGenerator/edge-cases/naming-edge-cases.md b/tools/WrapperGenerator/edge-cases/naming-edge-cases.md index e5d541e562..309c64f5e8 100644 --- a/tools/WrapperGenerator/edge-cases/naming-edge-cases.md +++ b/tools/WrapperGenerator/edge-cases/naming-edge-cases.md @@ -34,7 +34,7 @@ Entry template (keep the field names exact so the file converts cleanly): ``` ## - **Class:** -- **Status:** +- **Status:** — optionally followed by a short parenthetical qualifier - **Evidence:** - **Decision:** - **Migration impact:** @@ -50,6 +50,8 @@ Entry template (keep the field names exact so the file converts cleanly): | operationId preposition truncation | operationid-truncation | structurally-avoided | | `SkypeForBusiness` subject truncation | operationid-truncation | not-yet-reachable | | `Cookies`/`Skus`/`Dns`/`Ios`/`Statistics` quirks | inflection-defect | reproduced-for-parity | +| Self-referential `sites/{id}/sites` → `SubSite` | adjacent-duplicate-segments | handled | +| Route duplicates (spec paths the SDK never shipped) | duplicate-routes | partially-handled | ## Whois truncated to Whoi on the host navigation @@ -143,6 +145,45 @@ Entry template (keep the field names exact so the file converts cleanly): `data`, `delta`, `quota` (Humanizer-specific mistakes this rule engine never makes) and `statistics` (the one that applied here). +## Self-referential paths collide with their parent's cmdlet + +- **Class:** adjacent-duplicate-segments +- **Status:** handled (loud failure + directive-cited renames) +- **Evidence:** singularizing a self-referencing path collapses it onto its parent's noun: + `/sites/{id}/sites` produced `GetMgSite.g.cs`, silently overwriting the get-site-by-id + cmdlet — the same silent-drop failure AutoRest had. Nothing could detect it: writes are + not logged at console level, the summary counts surviving files, and the parity gate only + inspects files that exist. +- **Decision:** the generator now fails generation loudly on any cmdlet file collision, + listing every colliding pair. Shipped cases are renamed via NamingOverrides with their + directive cited (`sites/{id}/sites` → `SubSite`/`GroupSubSite`, per Sites.md + `subject: SubSite` directives); paths the SDK ships nothing for are suppressed as they + surface. +- **Migration impact:** none — renames match the published names exactly. +- **References:** issue #3704; `NamingOverrides.cs` SubSite entries; Sites.md lines 32–61. + +## Route duplicates: the spec publishes paths the SDK never shipped + +- **Class:** duplicate-routes +- **Status:** partially-handled (oracle-cited suppressions/renames) +- **Evidence:** the collision guard's first full-inventory sweep found 966 silent collisions + (per-module counts on issue #3704). Beyond self-references, the dominant cause is the spec + publishing the same data + under two routes while the SDK ships exactly one: nested navs duplicating top-level sets + (`hosts/{id}/components` vs `hostComponents` — 14 Security paths, ships nothing nested), + default-singleton vs collection (`/users/{id}/drive` ships renamed `UserDefaultDrive`; + `/users/{id}/calendar/events` ships `UserDefaultCalendarEvent`), Info-wrapper navs that + never shipped (`pinnedMessages/{id}/message`), and stitched pairs where GET ships from one + route and PATCH/DELETE from the other (termStore, agreement file/files). +- **Decision:** each resolved family is a `NamingOverrides` entry citing the shipped + command or the oracle's absence. Two families remain open on #3704 with full evidence: + the Identity.Governance mirrored navigations (the shipped survivor alternates by nesting + level, needing a dedupe design decision) and the Sites termStore `children` recursion + (resolver and direct oracle probes disagree; needs reconciliation before encoding). +- **Migration impact:** none — suppressed routes never shipped; renames match shipped names. +- **References:** issue #3704 (remainder inventory + resolver evidence); `NamingOverrides.cs` + "Collision resolutions" section. + ## Watch list Cases spotted but deliberately not acted on yet, so they aren't lost: From e6c98e4a78156aa91a3f22fee514aa5c24deb73a Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Wed, 12 Aug 2026 10:12:12 -0700 Subject: [PATCH 08/11] feat(wrapper-generator): resolve cmdlet collisions via oracle-derived data Derive-CollisionResolutions.ps1 replays the checked-in collision inventory (212 lines, 365 contested routes) against MgCommandMetadata and emits exact-match resolution data: 191 suppressions (routes the published SDK prunes) and 64 renames (published nouns), each entry carrying its oracle evidence. The files embed into the generator and apply only when UseCollisionData is set; -Validate fails on drift, and a new xunit test runs it on every `dotnet test` so staleness fails the suite instead of depending on someone remembering to run the script by hand. Derivation itself fails on any unclassified or ambiguous route. Only 2 cross-path variant merges exist in all of v1.0 (GroupPhoto, ShareListItem) - deferred with the singleton side kept, cataloged in crosspath-merge-edge-cases.md. Full 39-module v1.0 generation now produces zero collisions; 20 published commands that lost filename races are recovered; exact-name matches rise 5,042 -> 5,098. Also: cmdlets emit into a per-module namespace derived from the client namespace instead of the leftover MgPoC placeholder; Build-WrapperModule's generated csproj references Authentication by a relative path instead of an absolute one; its -Configuration parameter now actually reaches the wrapper generator's own build, not just the final module build; and a pre-existing nullable warning in the list/item pairing check is fixed. 121 tests pass. --- tools/Build-WrapperModule.ps1 | 10 +- tools/Derive-CollisionResolutions.ps1 | 239 ++ .../CollisionDataDriftTests.cs | 49 + .../DerivedCollisionResolutionsTests.cs | 60 + tools/WrapperGenerator/CmdletEmitter.cs | 4 +- tools/WrapperGenerator/CmdletNaming.cs | 6 +- .../DerivedCollisionResolutions.cs | 75 + tools/WrapperGenerator/EmitContext.cs | 14 +- tools/WrapperGenerator/GeneratorConfig.cs | 14 +- tools/WrapperGenerator/NamingOverrides.cs | 13 +- .../PowerShellWrapperGenerationService.cs | 4 +- tools/WrapperGenerator/Program.cs | 15 +- tools/WrapperGenerator/README.md | 8 +- .../WrapperGenerator/WrapperGenerator.csproj | 6 + .../data/collision-inventory.v1.0.txt | 212 + .../data/collision-renames.v1.0.json | 1254 ++++++ .../data/collision-resolution-ledger.v1.0.csv | 366 ++ .../data/collision-suppressions.v1.0.json | 3792 +++++++++++++++++ .../edge-cases/crosspath-merge-edge-cases.md | 49 + 19 files changed, 6167 insertions(+), 23 deletions(-) create mode 100644 tools/Derive-CollisionResolutions.ps1 create mode 100644 tools/WrapperGenerator.Tests/CollisionDataDriftTests.cs create mode 100644 tools/WrapperGenerator.Tests/DerivedCollisionResolutionsTests.cs create mode 100644 tools/WrapperGenerator/DerivedCollisionResolutions.cs create mode 100644 tools/WrapperGenerator/data/collision-inventory.v1.0.txt create mode 100644 tools/WrapperGenerator/data/collision-renames.v1.0.json create mode 100644 tools/WrapperGenerator/data/collision-resolution-ledger.v1.0.csv create mode 100644 tools/WrapperGenerator/data/collision-suppressions.v1.0.json create mode 100644 tools/WrapperGenerator/edge-cases/crosspath-merge-edge-cases.md diff --git a/tools/Build-WrapperModule.ps1 b/tools/Build-WrapperModule.ps1 index 3a5a392c1d..7630a2563e 100644 --- a/tools/Build-WrapperModule.ps1 +++ b/tools/Build-WrapperModule.ps1 @@ -142,7 +142,7 @@ function Build-OneModule { } } - $wrapperOut = & dotnet run --project $generatorProject -- -d $spec -o $cmdletsDir -n $clientNs 2>&1 + $wrapperOut = & dotnet run --project $generatorProject -c $Configuration -- -d $spec -o $cmdletsDir -n $clientNs --api-version $ApiVersion 2>&1 if ($LASTEXITCODE -ne 0) { # Skip warnings precede the failure; the exception message is what identifies it. $result.FailedAt = 'wrapper-generator' @@ -157,8 +157,12 @@ function Build-OneModule { return $result } - # Generated artifact, machine-local by design (absolute reference into this clone). + # Relative to $srcDir rather than the absolute $authCsproj, so the csproj is portable + # across clones and stays correct if a module's output folder ever moves (the eventual + # src/// commit target sits at a different depth than + # artifacts/wrapper-modules//src/). $csprojPath = Join-Path $srcDir "$moduleName.csproj" + $authCsprojRelative = [System.IO.Path]::GetRelativePath($srcDir, $authCsproj) -replace '/', '\' @" @@ -180,7 +184,7 @@ function Build-OneModule { - + diff --git a/tools/Derive-CollisionResolutions.ps1 b/tools/Derive-CollisionResolutions.ps1 new file mode 100644 index 0000000000..6171f01fbb --- /dev/null +++ b/tools/Derive-CollisionResolutions.ps1 @@ -0,0 +1,239 @@ +<# +.SYNOPSIS +Derives the wrapper generator's collision-resolution data files from the published-command +oracle, and validates the checked-in files against a fresh derivation. + +.DESCRIPTION +Input is a collision inventory: the exact lines the generator prints when it fails loudly on +cmdlet file collisions (one "Module :: File: 'Verb-Noun [Builder]' collides with +already-written 'Verb-Noun [Builder]'" per line), captured from a generation run with no +collision resolutions applied. + +For every route that appears in the inventory, the script asks the oracle +(MgCommandMetadata.json, filtered to -ApiVersion) what the published SDK ships for that +method + URI, and derives exactly one action: + + keep the route ships under the same name the generator produces - no entry emitted + suppress the route ships nothing - the published SDK pruned it + rename the route ships under a different noun - entry carries the published noun + +Anything else is a hard failure: + - an inventory line that does not parse, + - the same route deriving two different actions from different lines, + - a cross-path merge (both routes ship the SAME command from DIFFERENT URIs - the + generator cannot represent that yet) that no curated NamingOverrides entry resolves. + +Output is two deterministic JSON files (sorted, no timestamps) so renames review separately +from suppressions: + + tools/WrapperGenerator/data/collision-suppressions..json + tools/WrapperGenerator/data/collision-renames..json + +plus an operation-level ledger of every inventory route -> action -> evidence: + + /collision-resolution-ledger..csv + +.PARAMETER Validate +Re-derive and byte-compare against the checked-in data files instead of writing them. +Exits 1 on any difference, so drift between oracle, inventory, and data cannot land silently. + +.EXAMPLE +.\tools\Derive-CollisionResolutions.ps1 +.EXAMPLE +.\tools\Derive-CollisionResolutions.ps1 -Validate +#> +[CmdletBinding()] +param( + # The checked-in inventory snapshot: every collision line from a full-module generation + # run with the derived data disabled (WrapperGenerator --no-collision-data). Re-capture it + # with that flag whenever specs or naming rules change, then re-derive. + [string]$InventoryPath, + [string]$OraclePath = "$PSScriptRoot\..\src\Authentication\Authentication\custom\common\MgCommandMetadata.json", + [string]$OutDir = "$PSScriptRoot\WrapperGenerator\data", + [string]$LedgerPath, + [ValidateSet('v1.0', 'beta')] + [string]$ApiVersion = 'v1.0', + [switch]$Validate +) +if (-not $InventoryPath) { $InventoryPath = "$PSScriptRoot\WrapperGenerator\data\collision-inventory.$ApiVersion.txt" } +# Checked in alongside the inventory (NOT artifacts/, which is gitignored) so it ships as +# reviewable evidence in the PR diff. It is regenerated on every run but NOT compared by +# -Validate — only the two collision-*.json files are the enforced contract; this CSV is the +# human-readable "why" behind them, kept in sync by convention, not by the drift gate. +if (-not $LedgerPath) { $LedgerPath = "$PSScriptRoot\WrapperGenerator\data\collision-resolution-ledger.$ApiVersion.csv" } + +$ErrorActionPreference = 'Stop' + +# ---- parse the inventory ------------------------------------------------------------------- +$lineRx = "^(?[^:]+?) :: (?\S+): '(?[A-Za-z]+)-(?[A-Za-z0-9]+) \[(?[^\]]*(?:\[[^\]]*\][^\]]*)*)\]' collides with already-written '(?[A-Za-z]+)-(?[A-Za-z0-9]+) \[(?[^\]]*(?:\[[^\]]*\][^\]]*)*)\]'$" +$verbToMethod = @{ Get = 'GET'; New = 'POST'; Update = 'PATCH'; Set = 'PUT'; Remove = 'DELETE' } + +# Builder expression -> the same normalized URI skeleton NamingOverrides.NormalizePath +# produces from a path template: lowercase fixed segments, every parameter erased to {}. +function ConvertTo-UriSkeleton([string]$builder) { + $parts = @() + foreach ($seg in ($builder -split '\.')) { + if ($seg -notmatch '^(?[A-Za-z0-9]+)(\[(?[^\]]+)\])?$') { return $null } + $parts += $Matches.n.ToLowerInvariant() + if ($Matches.i) { $parts += '{}' } + } + '/' + ($parts -join '/') +} + +$lines = @(Get-Content $InventoryPath | Where-Object { $_.Trim() }) +$parsed = @() +$unparsed = @() +foreach ($l in $lines) { + if ($l -match $lineRx) { + $lost = ConvertTo-UriSkeleton $Matches.lost + $kept = ConvertTo-UriSkeleton $Matches.kept + if (-not $lost -or -not $kept) { $unparsed += $l; continue } + $parsed += [pscustomobject]@{ + Module = $Matches.mod.Trim(); Method = $verbToMethod[$Matches.verb] + OurName = "$($Matches.verb)-$($Matches.noun)"; Lost = $lost; Kept = $kept + } + } + else { $unparsed += $l } +} +if ($unparsed) { + $unparsed | ForEach-Object { Write-Error -ErrorAction Continue "unparsed inventory line: $_" } + throw "$($unparsed.Count) inventory line(s) did not parse; refusing to derive from a partial inventory." +} +Write-Host "inventory: $($parsed.Count) collision lines" + +# ---- oracle lookup: METHOD + skeleton -> published commands -------------------------------- +$oracle = @{} +foreach ($e in (Get-Content $OraclePath -Raw | ConvertFrom-Json)) { + if ($e.ApiVersion -ne $ApiVersion) { continue } + $skel = (($e.Uri -split '/') | ForEach-Object { if ($_ -match '^\{') { '{}' } else { $_.ToLowerInvariant() } }) -join '/' + $k = "$($e.Method) $skel" + if (-not $oracle.ContainsKey($k)) { $oracle[$k] = [System.Collections.Generic.SortedSet[string]]::new() } + [void]$oracle[$k].Add($e.Command) +} + +# ---- derive one action per route ------------------------------------------------------------ +# Route identity is (method, skeleton). Every inventory line contributes both of its routes. +$routes = @{} +function Add-Route($module, $method, $skel, $ourName, $counterpartSkel) { + $key = "$method $skel" + if (-not $routes.ContainsKey($key)) { + $routes[$key] = [pscustomobject]@{ + Method = $method; Uri = $skel; OurName = $ourName + Modules = [System.Collections.Generic.SortedSet[string]]::new() + Counterparts = [System.Collections.Generic.SortedSet[string]]::new() + } + } + $r = $routes[$key] + if ($r.OurName -cne $ourName) { + throw "ambiguous: route '$key' produces both '$($r.OurName)' and '$ourName' in the inventory." + } + [void]$r.Modules.Add($module) + [void]$r.Counterparts.Add($counterpartSkel) +} +foreach ($p in $parsed) { + Add-Route $p.Module $p.Method $p.Lost $p.OurName $p.Kept + Add-Route $p.Module $p.Method $p.Kept $p.OurName $p.Lost +} +Write-Host "routes contested: $($routes.Count)" + +# Pass 1 - tentative action per route, straight from the oracle: +# ships nothing -> suppress +# ships under our name -> keep (subject to the cross-path pass below) +# ships renamed -> rename to the published noun +$failures = @() +foreach ($key in ($routes.Keys | Sort-Object)) { + $r = $routes[$key] + $ships = if ($oracle.ContainsKey($key)) { @($oracle[$key]) } else { @() } + # The comma operator keeps a single-element array an array through Add-Member's binder. + $r | Add-Member ShipsAs (, $ships) + $action = + if ($ships.Count -eq 0) { 'suppress' } + elseif ($ships -ccontains $r.OurName) { 'keep' } + else { + $shippedNouns = @($ships | ForEach-Object { ($_ -split '-', 2)[1] -replace '^Mg', '' } | Sort-Object -Unique) + if ($shippedNouns.Count -ne 1) { + $failures += "ambiguous rename: $key ships as [$($ships -join ', ')] - more than one target noun." + } + 'rename' + } + $r | Add-Member Action $action +} + +# Pass 2 - cross-path merges. The published SDK serves ONE command from several URIs as +# parameter-set variants (Get-MgSiteTermStoreSetChild covers /children, /children/{}, +# /children/{}/children, /children/{}/children/{}). The wrapper cannot express that yet, so +# among same-command keep-routes only the shallowest list/item pair survives: the route with +# the fewest path parameters (tie: shortest, then ordinal - fully deterministic) plus its +# trailing-id partner. Deeper twins are suppressed and marked deferred; they come back when +# cross-path parameter sets land (tracked in the operation-shapes issue). +foreach ($group in ($routes.Values | Where-Object { $_.Action -eq 'keep' } | + Group-Object { "$($_.Method) $($_.OurName)" } | Where-Object Count -gt 1)) { + $anchor = $group.Group | Sort-Object ` + @{e = { ([regex]::Matches($_.Uri, '\{\}')).Count } }, @{e = { $_.Uri.Length } }, @{e = { $_.Uri } } | + Select-Object -First 1 + foreach ($r in $group.Group) { + if ($r.Uri -cne $anchor.Uri -and $r.Uri -cne "$($anchor.Uri)/{}") { $r.Action = 'suppress-deferred' } + } +} + +if ($failures) { + $failures | ForEach-Object { Write-Error -ErrorAction Continue $_ } + throw "$($failures.Count) route(s) unclassified or ambiguous; refusing to emit a partial derivation." +} + +$suppressions = @(); $renames = @(); $ledger = @() +foreach ($key in ($routes.Keys | Sort-Object)) { + $r = $routes[$key] + $counterpartShips = @($r.Counterparts | ForEach-Object { $ck = "$($r.Method) $_" + if ($oracle.ContainsKey($ck)) { @($oracle[$ck]) } else { @() } } | Sort-Object -Unique) + $entry = [ordered]@{ + apiVersion = $ApiVersion; modules = @($r.Modules); method = $r.Method; uri = $r.Uri + action = if ($r.Action -eq 'suppress-deferred') { 'suppress' } else { $r.Action } + evidence = [ordered]@{ + shipsAs = @($r.ShipsAs); counterpartUris = @($r.Counterparts); counterpartShipsAs = $counterpartShips + } + } + if ($r.Action -eq 'suppress-deferred') { $entry.deferredCrossPathMerge = $true } + if ($r.Action -eq 'rename') { $entry.replacementNoun = (@($r.ShipsAs)[0] -split '-', 2)[1] -replace '^Mg', '' } + switch ($entry.action) { + 'suppress' { $suppressions += [pscustomobject]$entry } + 'rename' { $renames += [pscustomobject]$entry } + } + $ledger += [pscustomobject]@{ + Method = $r.Method; Uri = $r.Uri; Modules = ($r.Modules -join ';'); OurName = $r.OurName + Action = $r.Action; ShipsAs = ($r.ShipsAs -join ';'); CounterpartUris = ($r.Counterparts -join ';') + CounterpartShipsAs = ($counterpartShips -join ';') + } +} + +# ---- write or validate ---------------------------------------------------------------------- +$jsonOpts = [System.Text.Json.JsonSerializerOptions]::new() +$jsonOpts.WriteIndented = $true +function ToJson($obj) { + # ConvertTo-Json reorders nothing, but normalize newlines so the byte-compare is stable. + (($obj | ConvertTo-Json -Depth 6) -replace "`r`n", "`n") + "`n" +} +$targets = @( + @{ Path = Join-Path $OutDir "collision-suppressions.$ApiVersion.json"; Content = ToJson $suppressions }, + @{ Path = Join-Path $OutDir "collision-renames.$ApiVersion.json"; Content = ToJson $renames } +) +if ($Validate) { + $drift = @() + foreach ($t in $targets) { + if (-not (Test-Path $t.Path)) { $drift += "missing: $($t.Path)"; continue } + $existing = (Get-Content $t.Path -Raw) -replace "`r`n", "`n" + if ($existing -cne $t.Content) { $drift += "differs from fresh derivation: $($t.Path)" } + } + if ($drift) { + $drift | ForEach-Object { Write-Error -ErrorAction Continue $_ } + exit 1 + } + Write-Host "validation OK: $($suppressions.Count) suppressions + $($renames.Count) renames match the checked-in files." + exit 0 +} + +New-Item -ItemType Directory -Force $OutDir | Out-Null +foreach ($t in $targets) { [System.IO.File]::WriteAllText($t.Path, $t.Content) } +New-Item -ItemType Directory -Force (Split-Path $LedgerPath) | Out-Null +$ledger | Sort-Object Method, Uri | Export-Csv $LedgerPath -NoTypeInformation +Write-Host "wrote $($suppressions.Count) suppressions, $($renames.Count) renames, ledger of $($ledger.Count) routes -> $LedgerPath" diff --git a/tools/WrapperGenerator.Tests/CollisionDataDriftTests.cs b/tools/WrapperGenerator.Tests/CollisionDataDriftTests.cs new file mode 100644 index 0000000000..b539877d3d --- /dev/null +++ b/tools/WrapperGenerator.Tests/CollisionDataDriftTests.cs @@ -0,0 +1,49 @@ +using System; +using System.Diagnostics; +using System.IO; +using Xunit; + +namespace WrapperGenerator.Tests; + +// The checked-in collision-resolution data (tools/WrapperGenerator/data/collision-*.json) is +// derived FROM tools/WrapperGenerator/data/collision-inventory.v1.0.txt and the oracle +// (MgCommandMetadata.json) by tools/Derive-CollisionResolutions.ps1. Nothing else enforces +// that the checked-in files still match a fresh derivation — there is no CI pipeline for this +// project yet (tracked separately) — so this test is the drift gate: it shells out to the +// script's -Validate mode as part of the normal `dotnet test` run, the same command a human +// would run by hand, so staleness fails the suite instead of depending on someone remembering +// to run it. +public sealed class CollisionDataDriftTests +{ + [Fact] + public void DerivedCollisionDataMatchesAFreshDerivation() + { + var scriptPath = Path.Combine(FindRepoRoot(), "tools", "Derive-CollisionResolutions.ps1"); + Assert.True(File.Exists(scriptPath), $"Derivation script not found at '{scriptPath}'."); + + var psi = new ProcessStartInfo("pwsh") + { + ArgumentList = { "-NoProfile", "-NonInteractive", "-File", scriptPath, "-Validate" }, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + }; + using var process = Process.Start(psi) ?? throw new InvalidOperationException("Failed to start pwsh."); + var stdout = process.StandardOutput.ReadToEnd(); + var stderr = process.StandardError.ReadToEnd(); + process.WaitForExit(); + + Assert.True(process.ExitCode == 0, + "Checked-in collision-suppressions/renames JSON no longer matches a fresh derivation from " + + "collision-inventory.v1.0.txt and the oracle. Re-run tools/Derive-CollisionResolutions.ps1 " + + $"(without -Validate) and commit the result.\n--- stdout ---\n{stdout}\n--- stderr ---\n{stderr}"); + } + + private static string FindRepoRoot() + { + var dir = new DirectoryInfo(AppContext.BaseDirectory); + while (dir is not null && !Directory.Exists(Path.Combine(dir.FullName, ".git"))) + dir = dir.Parent; + return dir?.FullName ?? throw new InvalidOperationException("Could not locate repo root (.git) from " + AppContext.BaseDirectory); + } +} diff --git a/tools/WrapperGenerator.Tests/DerivedCollisionResolutionsTests.cs b/tools/WrapperGenerator.Tests/DerivedCollisionResolutionsTests.cs new file mode 100644 index 0000000000..da3a254119 --- /dev/null +++ b/tools/WrapperGenerator.Tests/DerivedCollisionResolutionsTests.cs @@ -0,0 +1,60 @@ +using System.Net.Http; +using WrapperGenerator; +using Xunit; + +namespace WrapperGenerator.Tests; + +// The derived collision data (tools/WrapperGenerator/data/collision-*.json, embedded at +// build time) must only act when a run opts in via GeneratorConfig: the curated-only paths +// the naming tests pin are exercised with config null, so a data-file regeneration can never +// silently shift those expectations. Entries asserted here are oracle-cited in the data +// files' evidence fields. +public sealed class DerivedCollisionResolutionsTests +{ + private static readonly GeneratorConfig DataOn = new("Test.Client", "unused"); + private static readonly GeneratorConfig DataOff = new("Test.Client", "unused", UseCollisionData: false); + + // Oracle: /groupSettings ships nothing in v1.0; Get/New/Update/Remove-MgGroupSetting all + // ship from the nested /groups/{id}/settings routes. + [Fact] + public void DerivedSuppressionAppliesOnlyWithDataEnabled() + { + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, "/groupSettings", DataOn)); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/groupSettings", DataOff)); + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/groupSettings")); + } + + // Oracle: the nested catalog resourceRoles route ships as + // Get-MgEntitlementManagementCatalogResourceRole - the published noun drops the + // IdentityGovernance prefix our path rules produce. + [Fact] + public void DerivedRenameReplacesTheNounVerbatim() + { + var path = "/identityGovernance/entitlementManagement/catalogs/{accessPackageCatalog-id}/resourceRoles"; + + var renamed = Naming.Resolve(new OperationInfo(HttpMethod.Get, path), DataOn); + Assert.Equal("MgEntitlementManagementCatalogResourceRole", renamed.Noun); + + var untouched = Naming.Resolve(new OperationInfo(HttpMethod.Get, path)); + Assert.Equal("MgIdentityGovernanceEntitlementManagementCatalogResourceRole", untouched.Noun); + } + + // A derived rename is keyed by method: the GET rename of the resourceRoles route must not + // leak onto a POST of a DIFFERENT route that only shares the prefix. + [Fact] + public void DerivedEntriesAreExactMatchOnly() + { + Assert.False(NamingOverrides.IsSuppressed(HttpMethod.Get, "/groupSettings/extra/segment", DataOn)); + } + + // The two deferred cross-path merges (the only ones in all of v1.0): the published SDK + // serves one command from two unrelated routes; the singleton side is kept, the + // collection side is suppressed until cross-path parameter sets land. + [Theory] + [InlineData("/groups/{group-id}/photos")] + [InlineData("/shares/{sharedDriveItem-id}/list/items")] + public void DeferredCrossPathRoutesAreSuppressed(string pathTemplate) + { + Assert.True(NamingOverrides.IsSuppressed(HttpMethod.Get, pathTemplate, DataOn)); + } +} diff --git a/tools/WrapperGenerator/CmdletEmitter.cs b/tools/WrapperGenerator/CmdletEmitter.cs index f88ae8742b..985309edfe 100644 --- a/tools/WrapperGenerator/CmdletEmitter.cs +++ b/tools/WrapperGenerator/CmdletEmitter.cs @@ -25,7 +25,7 @@ public static class CmdletEmitter } else { - WriteVerbose("[MgPoC] No -AccessToken supplied, using the active Connect-MgGraph session."); + WriteVerbose("No -AccessToken supplied, using the active Connect-MgGraph session."); try { httpClient = HttpHelpers.GetGraphHttpClient(); @@ -667,7 +667,7 @@ private static string ReFetchBlock(CmdletNaming naming) => $$""" if (result is null) { - WriteVerbose("[MgPoC] PATCH succeeded with no response body, re-fetching the updated resource."); + WriteVerbose("PATCH succeeded with no response body, re-fetching the updated resource."); try { result = client.{{naming.BuilderExpression}}.GetAsync().GetAwaiter().GetResult(); diff --git a/tools/WrapperGenerator/CmdletNaming.cs b/tools/WrapperGenerator/CmdletNaming.cs index a9836723e2..0ee3046c5a 100644 --- a/tools/WrapperGenerator/CmdletNaming.cs +++ b/tools/WrapperGenerator/CmdletNaming.cs @@ -41,7 +41,7 @@ public static class Naming [HttpMethod.Delete] = PsVerb.Remove, }; - public static CmdletNaming Resolve(OperationInfo operation) + public static CmdletNaming Resolve(OperationInfo operation, GeneratorConfig? config = null) { ArgumentNullException.ThrowIfNull(operation); if (!VerbMap.TryGetValue(operation.HttpMethod, out var verb)) @@ -51,7 +51,7 @@ public static CmdletNaming Resolve(OperationInfo operation) // plurality the spec author chose, while the published SDK names follow the path: // GET /users/{id}/messages is Get-MgUserMessage. The few hand-tuned exceptions the // published SDK carries are mirrored as data in NamingOverrides, never as code here. - var noun = GeneratorConstants.NounPrefix + NamingOverrides.ApplyNounOverrides(operation.HttpMethod, operation.Path, BuildNounFromPath(operation.Path)); + var noun = GeneratorConstants.NounPrefix + NamingOverrides.ApplyNounOverrides(operation.HttpMethod, operation.Path, BuildNounFromPath(operation.Path), config); // A list GET (/users/{id}/messages) and its item GET (/users/{id}/messages/{message-id}) // get the same noun on purpose. PowerShellWrapperGenerationService pairs them into one @@ -219,7 +219,7 @@ public static bool IsListItemPair(CmdletNaming list, CmdletNaming item) // plain list/item pair; without this the two emit identical file names and collide. var listCast = TrailingCastMember(list.BuilderExpression); var itemCast = TrailingCastMember(item.BuilderExpression); - if (listCast is null || !string.Equals(listCast, itemCast, StringComparison.Ordinal)) + if (listCast is null || itemCast is null || !string.Equals(listCast, itemCast, StringComparison.Ordinal)) return false; var listStem = list.BuilderExpression[..^(listCast.Length + 1)]; diff --git a/tools/WrapperGenerator/DerivedCollisionResolutions.cs b/tools/WrapperGenerator/DerivedCollisionResolutions.cs new file mode 100644 index 0000000000..793377e8c6 --- /dev/null +++ b/tools/WrapperGenerator/DerivedCollisionResolutions.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Reflection; +using System.Text.Json; + +namespace WrapperGenerator; + +// Collision resolutions DERIVED from the published-command oracle, as opposed to the curated +// judgment entries in NamingOverrides. tools/Derive-CollisionResolutions.ps1 writes the +// data/collision-*.json files from (collision inventory x MgCommandMetadata.json) and its +// -Validate mode fails when the checked-in files drift from a fresh derivation; the files are +// embedded at build time so a generation run never reads the 22 MB oracle itself. +// +// Entries are exact-match only, keyed by API version + HTTP method + normalized URI, and +// exist solely for operations that appeared in the collision inventory. Anything broader +// (subtree prunes, cross-path merge picks) is curated in NamingOverrides with a citation. +internal static class DerivedCollisionResolutions +{ + private sealed record DataEntry(string ApiVersion, string Method, string Uri, string Action, string? ReplacementNoun); + + private sealed record Tables(HashSet Suppressions, Dictionary Renames); + + private static readonly Lazy> ByApiVersion = new(Load); + + private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true }; + + public static bool IsSuppressed(string apiVersion, HttpMethod method, string normalizedPath) => + ByApiVersion.Value.TryGetValue(apiVersion, out var tables) + && tables.Suppressions.Contains(Key(method, normalizedPath)); + + public static bool TryReplaceNoun(string apiVersion, HttpMethod method, string normalizedPath, out string noun) + { + noun = string.Empty; + return ByApiVersion.Value.TryGetValue(apiVersion, out var tables) + && tables.Renames.TryGetValue(Key(method, normalizedPath), out noun!); + } + + private static string Key(HttpMethod method, string normalizedPath) => $"{method.Method.ToUpperInvariant()} {normalizedPath}"; + + private static Dictionary Load() + { + var result = new Dictionary(StringComparer.Ordinal); + var assembly = typeof(DerivedCollisionResolutions).Assembly; + foreach (var resource in assembly.GetManifestResourceNames()) + { + if (!resource.Contains(".data.collision-", StringComparison.Ordinal) || !resource.EndsWith(".json", StringComparison.Ordinal)) + continue; + using var stream = assembly.GetManifestResourceStream(resource)!; + var entries = JsonSerializer.Deserialize>(stream, JsonOptions) ?? []; + foreach (var entry in entries) + { + if (!result.TryGetValue(entry.ApiVersion, out var tables)) + result[entry.ApiVersion] = tables = new Tables(new HashSet(StringComparer.Ordinal), new Dictionary(StringComparer.Ordinal)); + var key = $"{entry.Method.ToUpperInvariant()} {entry.Uri}"; + switch (entry.Action) + { + case "suppress": + tables.Suppressions.Add(key); + break; + case "rename" when !string.IsNullOrEmpty(entry.ReplacementNoun): + tables.Renames[key] = entry.ReplacementNoun; + break; + default: + // A malformed data file must fail the run, not silently generate the + // very collision the entry was derived to resolve. + throw new InvalidDataException($"{resource}: entry '{key}' has unsupported action '{entry.Action}'."); + } + } + } + return result; + } +} diff --git a/tools/WrapperGenerator/EmitContext.cs b/tools/WrapperGenerator/EmitContext.cs index 9a738aa7f9..f2db739ffa 100644 --- a/tools/WrapperGenerator/EmitContext.cs +++ b/tools/WrapperGenerator/EmitContext.cs @@ -1,9 +1,19 @@ -namespace WrapperGenerator; +using System; + +namespace WrapperGenerator; // The per-module values CmdletEmitter's templates need, so the emitter stays module-agnostic. // ClientNamespace is whatever --namespace-name the module was generated with, for example // "Microsoft.Graph.PowerShell.Mail.Client". -public sealed record EmitContext(string ClientNamespace, string CmdletNamespace = "MgPoC") +public sealed record EmitContext(string ClientNamespace) { public string ModelsNamespace => $"{ClientNamespace}.Models"; + + // The emitted cmdlets' own namespace: the client namespace with its trailing ".Client" + // dropped ("Microsoft.Graph.PowerShell.Mail.Client" -> "Microsoft.Graph.PowerShell.Mail"), + // so it is per-module like everything else the client generates rather than a shared + // placeholder every module's cmdlets would otherwise collide into. + public string CmdletNamespace => ClientNamespace.EndsWith(".Client", StringComparison.Ordinal) + ? ClientNamespace[..^".Client".Length] + : ClientNamespace; } diff --git a/tools/WrapperGenerator/GeneratorConfig.cs b/tools/WrapperGenerator/GeneratorConfig.cs index 0b8f90c796..dc4d64f57f 100644 --- a/tools/WrapperGenerator/GeneratorConfig.cs +++ b/tools/WrapperGenerator/GeneratorConfig.cs @@ -1,5 +1,11 @@ -namespace WrapperGenerator; +namespace WrapperGenerator; -// Configuration for a generation run. The generation service reads exactly two values: the -// client namespace the module is generated with, and the output folder for the .g.cs files. -public sealed record GeneratorConfig(string ClientNamespaceName, string OutputPath); +// Configuration for a generation run: the client namespace the module is generated with, the +// output folder for the .g.cs files, the API version the derived collision-resolution data is +// keyed by, and whether that data is applied at all (derivation runs disable it to reproduce +// the raw collision inventory the data is derived FROM). +public sealed record GeneratorConfig( + string ClientNamespaceName, + string OutputPath, + string ApiVersion = "v1.0", + bool UseCollisionData = true); diff --git a/tools/WrapperGenerator/NamingOverrides.cs b/tools/WrapperGenerator/NamingOverrides.cs index 3aae42bfc8..f7972a4364 100644 --- a/tools/WrapperGenerator/NamingOverrides.cs +++ b/tools/WrapperGenerator/NamingOverrides.cs @@ -213,11 +213,16 @@ private sealed record Entry(OverrideKind Kind, HttpMethod? Method, string Patter private static string NormalizePath(string pathTemplate) => PathParamRegex().Replace(pathTemplate, "{}").TrimEnd('/').ToLowerInvariant(); - public static bool IsSuppressed(HttpMethod httpMethod, string pathTemplate) + // config carries the API version the derived collision data is keyed by; null (the unit + // tests' default) applies only the curated entries below, so a data-file change can never + // silently shift a pinned naming expectation. + public static bool IsSuppressed(HttpMethod httpMethod, string pathTemplate, GeneratorConfig? config = null) { ArgumentNullException.ThrowIfNull(httpMethod); ArgumentNullException.ThrowIfNull(pathTemplate); var path = NormalizePath(pathTemplate); + if (config is { UseCollisionData: true } && DerivedCollisionResolutions.IsSuppressed(config.ApiVersion, httpMethod, path)) + return true; foreach (var entry in Entries) { if (entry.Kind == OverrideKind.SuppressOperation && Matches(entry, httpMethod, path)) @@ -226,13 +231,17 @@ public static bool IsSuppressed(HttpMethod httpMethod, string pathTemplate) return false; } - public static string ApplyNounOverrides(HttpMethod httpMethod, string pathTemplate, string noun) + public static string ApplyNounOverrides(HttpMethod httpMethod, string pathTemplate, string noun, GeneratorConfig? config = null) { ArgumentNullException.ThrowIfNull(httpMethod); ArgumentNullException.ThrowIfNull(pathTemplate); ArgumentNullException.ThrowIfNull(noun); var path = NormalizePath(pathTemplate); + // A derived rename is the published noun verbatim; nothing curated may rewrite it. + if (config is { UseCollisionData: true } && DerivedCollisionResolutions.TryReplaceNoun(config.ApiVersion, httpMethod, path, out var derivedNoun)) + return derivedNoun; + // Published BackupRestore cmdlets retain the Solution prefix (for example, // Get-MgSolutionBackupRestore). Do not apply /solutions/* strip rules here. var skipSolutionStrip = path.StartsWith("/solutions/backuprestore", StringComparison.Ordinal); diff --git a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs index b0b1edd923..82974e0db3 100644 --- a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs +++ b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs @@ -135,7 +135,7 @@ public async Task GenerateAsync(CancellationToken cancellationToken) // Skip operations the published SDK deliberately does not ship. NamingOverrides // holds the citation for each one. - if (NamingOverrides.IsSuppressed(httpMethod, pathTemplate)) + if (NamingOverrides.IsSuppressed(httpMethod, pathTemplate, config)) { LogSuppressedOperation(httpMethod.Method, pathTemplate); continue; @@ -168,7 +168,7 @@ public async Task GenerateAsync(CancellationToken cancellationToken) : null; var collectionValueSchema = responseSchema is not null ? FindProperty(responseSchema, "value") : null; - var cmdletNaming = Naming.Resolve(new OperationInfo(httpMethod, pathTemplate, headerParams)); + var cmdletNaming = Naming.Resolve(new OperationInfo(httpMethod, pathTemplate, headerParams), config); if (httpMethod == HttpMethod.Get && responseSchema is null) { diff --git a/tools/WrapperGenerator/Program.cs b/tools/WrapperGenerator/Program.cs index dfe08a5a09..15d43b5dff 100644 --- a/tools/WrapperGenerator/Program.cs +++ b/tools/WrapperGenerator/Program.cs @@ -20,6 +20,8 @@ private static async Task Main(string[] args) string? specPath = null; string? outputPath = null; string? clientNamespace = null; + var apiVersion = "v1.0"; + var useCollisionData = true; var includePaths = new List(); for (var i = 0; i < args.Length; i++) @@ -35,6 +37,14 @@ private static async Task Main(string[] args) case "-n" or "--namespace" or "--namespace-name": clientNamespace = ArgValue(args, ref i); break; + case "--api-version": + apiVersion = ArgValue(args, ref i); + break; + case "--no-collision-data": + // Derivation mode: tools/Derive-CollisionResolutions.ps1 needs the raw + // collision inventory, so the derived resolutions must not mask it. + useCollisionData = false; + break; case "--include-path": includePaths.Add(ArgValue(args, ref i)); break; @@ -52,7 +62,7 @@ private static async Task Main(string[] args) if (specPath is null || outputPath is null || clientNamespace is null) { Console.Error.WriteLine( - "Usage: WrapperGenerator -d -o -n [--include-path '#GET,POST' ...]"); + "Usage: WrapperGenerator -d -o -n [--api-version v1.0|beta] [--no-collision-data] [--include-path '#GET,POST' ...]"); return 2; } @@ -66,7 +76,8 @@ private static async Task Main(string[] args) IncludePathFilter.Apply(document, includePaths); - var config = new GeneratorConfig(ClientNamespaceName: clientNamespace, OutputPath: outputPath); + var config = new GeneratorConfig(ClientNamespaceName: clientNamespace, OutputPath: outputPath, + ApiVersion: apiVersion, UseCollisionData: useCollisionData); var service = new PowerShellWrapperGenerationService(document, config, new StderrLogger()); await service.GenerateAsync(CancellationToken.None).ConfigureAwait(false); diff --git a/tools/WrapperGenerator/README.md b/tools/WrapperGenerator/README.md index eaf37248be..60e4aa796a 100644 --- a/tools/WrapperGenerator/README.md +++ b/tools/WrapperGenerator/README.md @@ -54,6 +54,8 @@ Singularization runs per camel-case word (so `termsAndConditions` → `TermAndCo A few published names aren't algorithmic, and the spec publishes some routes the SDK never shipped. Both live as data in `NamingOverrides.cs` — renames mirroring the SDK's hand-written AutoRest directives, and suppressions for routes that ship nothing — each entry citing its evidence: the directive when one exists, otherwise the shipped-command inventory. Examples: the `GET /users/{id}/calendar` rename to `…UserDefaultCalendar` (Calendar.md), the `Solution` prefix strip under `/solutions/*` with the BackupRestore exception (Bookings.md), and the self-referential `sites/{id}/sites` rename to `SubSite`/`GroupSubSite` (Sites.md) — without which the sub-sites cmdlets would collide with `Get-MgSite` itself. The generator fails loudly on any such file collision rather than silently overwriting. +On top of the curated entries sits a **derived** layer: `tools/Derive-CollisionResolutions.ps1` replays every route from the checked-in collision inventory (`data/collision-inventory.v1.0.txt`, captured with `--no-collision-data`) against the shipped-command inventory and emits `data/collision-suppressions.v1.0.json` and `data/collision-renames.v1.0.json` — one exact-match entry per contested method+route, each carrying its oracle evidence. The files are embedded into the generator at build time (generation never reads the 22 MB oracle), applied only when `GeneratorConfig.UseCollisionData` is set, and the script's `-Validate` mode fails if the checked-in files drift from a fresh derivation. Two routes in all of v1.0 are **deferred cross-path merges** — the published SDK serves `Get-MgGroupPhoto` from both `/photo` and `/photos`, and `Get-MgShareListItem` from both `/listItem` and `/list/items`, as parameter-set variants of one cmdlet; the generator keeps the singleton side and suppresses the collection side until cross-path parameter sets land (see [edge-cases/crosspath-merge-edge-cases.md](edge-cases/crosspath-merge-edge-cases.md)). With the derived data applied, a full v1.0 generation across all 39 modules produces zero collisions. + ## The one subtle part: list + item GET become one cmdlet Graph has two GETs for a resource — the collection (`GET …/messages`) and a single item (`GET …/messages/{message-id}`) — but the published SDK exposes **one** cmdlet, `Get-MgUserMessage`, that does both: no `-MessageId` lists them, a `-MessageId` fetches one. @@ -150,14 +152,14 @@ dotnet run --project tools/WrapperGenerator -- ` --include-path '/users/{user-id}/messages/{message-id}*#GET,DELETE' ``` -`-d` is the spec, `-o` the output folder, `-n` the namespace of the step-1 client the wrappers call. Each `--include-path` is a glob with an optional `#METHOD,METHOD` filter; omit them to generate every operation in the document. Output: `Shared.g.cs`, one `*.g.cs` per cmdlet (in namespace `MgPoC`), and a small `kiota-lock.json` noting the source spec. +`-d` is the spec, `-o` the output folder, `-n` the namespace of the step-1 client the wrappers call. Each `--include-path` is a glob with an optional `#METHOD,METHOD` filter; omit them to generate every operation in the document. Output: `Shared.g.cs`, one `*.g.cs` per cmdlet (in a namespace derived from `-n` by dropping its trailing `.Client`, e.g. `-n Microsoft.Graph.PowerShell.Mail.Client` emits into `Microsoft.Graph.PowerShell.Mail`), and a small `kiota-lock.json` noting the source spec. **Test** — two layers: ```powershell # 1. Naming rules pinned to published Microsoft.Graph names dotnet test tools/WrapperGenerator.Tests -# => Passed! - Failed: 0, Passed: 115, Total: 115 +# => Passed! - Failed: 0, Passed: 120, Total: 120 # 2. Parity gate: generate, then check every cmdlet name against Graph's own command inventory .\tools\Compare-WrapperCmdletNames.ps1 -GeneratedPath @@ -168,7 +170,7 @@ The unit tests guard the naming rules (their expected values are real published ## Gaps / not done yet -- **Output isn't committed into `src/{Module}/`.** `tools/Build-WrapperModule.ps1` now turns a module into an importable build under `artifacts/` (kiota client + wrappers + csproj + PSD1; `tools/Test-WrapperModule.ps1` smoke-tests it), with generation reading the Kiota-compatible docs (`openApiDocs_KiotaCompat`) by default. The target design — wrappers committed into `src/{Module}/` with a per-module namespace instead of `MgPoC` — is still open. +- **Output isn't committed into `src/{Module}/`.** `tools/Build-WrapperModule.ps1` now turns a module into an importable build under `artifacts/` (kiota client + wrappers + csproj + PSD1; `tools/Test-WrapperModule.ps1` smoke-tests it), with generation reading the Kiota-compatible docs (`openApiDocs_KiotaCompat`) by default. Cmdlets now emit into a per-module namespace (not `MgPoC`) and the generated csproj references Authentication by a relative path, so both are ready to move; the exact target folder under `src/{Module}/{v1.0|beta}/` is still open — the existing AutoRest modules' `.gitignore` there excludes a folder literally named `generated`, so the wrapper output needs a different folder name or that pattern needs updating, or a commit there would silently produce an empty diff. - **No runtime base classes or real auth flow.** Shared paging, a proper `Connect-MgGraph`/session integration, and base cmdlet classes are a later phase. - **Body binding is shallow** — top-level primitive properties only; no nested/complex types beyond the `passwordProfile` special case. - **Some operation shapes aren't generated** — `$count`/`$ref`/`$value`, delta, OData actions/functions, and cast endpoints. diff --git a/tools/WrapperGenerator/WrapperGenerator.csproj b/tools/WrapperGenerator/WrapperGenerator.csproj index ee22043de8..b6c3d744bd 100644 --- a/tools/WrapperGenerator/WrapperGenerator.csproj +++ b/tools/WrapperGenerator/WrapperGenerator.csproj @@ -20,4 +20,10 @@ + + + + + diff --git a/tools/WrapperGenerator/data/collision-inventory.v1.0.txt b/tools/WrapperGenerator/data/collision-inventory.v1.0.txt new file mode 100644 index 0000000000..a39893d2c0 --- /dev/null +++ b/tools/WrapperGenerator/data/collision-inventory.v1.0.txt @@ -0,0 +1,212 @@ +Calendar :: GetMgGroupCalendarView.g.cs: 'Get-MgGroupCalendarView [Groups[GroupId].CalendarView]' collides with already-written 'Get-MgGroupCalendarView [Groups[GroupId].Calendar.CalendarView]' +Calendar :: GetMgUserCalendarView.g.cs: 'Get-MgUserCalendarView [Users[UserId].Calendars[CalendarId].CalendarView]' collides with already-written 'Get-MgUserCalendarView [Users[UserId].Calendar.CalendarView]' +Calendar :: GetMgUserCalendarView.g.cs: 'Get-MgUserCalendarView [Users[UserId].CalendarView]' collides with already-written 'Get-MgUserCalendarView [Users[UserId].Calendar.CalendarView]' +Files :: GetMgShareListItem.g.cs: 'Get-MgShareListItem [Shares[SharedDriveItemId].ListItem]' collides with already-written 'Get-MgShareListItem [Shares[SharedDriveItemId].List.Items]' +Groups :: NewMgGroupLifecyclePolicy.g.cs: 'New-MgGroupLifecyclePolicy [Groups[GroupId].GroupLifecyclePolicies]' collides with already-written 'New-MgGroupLifecyclePolicy [GroupLifecyclePolicies]' +Groups :: NewMgGroupSetting.g.cs: 'New-MgGroupSetting [GroupSettings]' collides with already-written 'New-MgGroupSetting [Groups[GroupId].Settings]' +Groups :: UpdateMgGroupSetting.g.cs: 'Update-MgGroupSetting [GroupSettings[GroupSettingId]]' collides with already-written 'Update-MgGroupSetting [Groups[GroupId].Settings[GroupSettingId]]' +Groups :: RemoveMgGroupSetting.g.cs: 'Remove-MgGroupSetting [GroupSettings[GroupSettingId]]' collides with already-written 'Remove-MgGroupSetting [Groups[GroupId].Settings[GroupSettingId]]' +Groups :: GetMgGroupPhoto.g.cs: 'Get-MgGroupPhoto [Groups[GroupId].Photos]' collides with already-written 'Get-MgGroupPhoto [Groups[GroupId].Photo]' +Groups :: GetMgGroupSetting.g.cs: 'Get-MgGroupSetting [Groups[GroupId].Settings[GroupSettingId]]' collides with already-written 'Get-MgGroupSetting [Groups[GroupId].Settings]' +Groups :: GetMgGroupSetting.g.cs: 'Get-MgGroupSetting [GroupSettings]' collides with already-written 'Get-MgGroupSetting [Groups[GroupId].Settings]' +Groups :: GetMgGroupSetting.g.cs: 'Get-MgGroupSetting [GroupSettings[GroupSettingId]]' collides with already-written 'Get-MgGroupSetting [Groups[GroupId].Settings]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementCatalogResourceRole.g.cs: 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceRole.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceRole.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope.g.cs: 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementCatalogResourceScope.g.cs: 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceScope.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceScope.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole.g.cs: 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole.g.cs: 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope.g.cs: 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope.g.cs: 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: NewMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole.g.cs: 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles]' collides with already-written 'New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' +Identity.Governance :: UpdateMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource.g.cs: 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: RemoveMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource.g.cs: 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Environment]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource.Environment]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Environment]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.Catalogs[AccessPackageCatalogId].Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource.Environment]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Environment]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Roles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceRoles[AccessPackageResourceRoleId].Resource.Scopes[AccessPackageResourceScopeId].Resource.Environment]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Environment]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId]]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource]' +Identity.Governance :: GetMgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment.g.cs: 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.ResourceScopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource.Environment]' collides with already-written 'Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment [IdentityGovernance.EntitlementManagement.ResourceRequests[AccessPackageResourceRequestId].Catalog.Resources[AccessPackageResourceId].Scopes[AccessPackageResourceScopeId].Resource.Roles[AccessPackageResourceRoleId].Resource.Environment]' +Notes :: GetMgGroupOnenoteNotebookSectionGroup.g.cs: 'Get-MgGroupOnenoteNotebookSectionGroup [Groups[GroupId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgGroupOnenoteNotebookSectionGroup [Groups[GroupId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgGroupOnenoteNotebookSectionGroup.g.cs: 'Get-MgGroupOnenoteNotebookSectionGroup [Groups[GroupId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgGroupOnenoteNotebookSectionGroup [Groups[GroupId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgGroupOnenoteNotebookSectionGroup.g.cs: 'Get-MgGroupOnenoteNotebookSectionGroup [Groups[GroupId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgGroupOnenoteNotebookSectionGroup [Groups[GroupId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgGroupOnenoteSectionGroup.g.cs: 'Get-MgGroupOnenoteSectionGroup [Groups[GroupId].Onenote.SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgGroupOnenoteSectionGroup [Groups[GroupId].Onenote.SectionGroups]' +Notes :: GetMgGroupOnenoteSectionGroup.g.cs: 'Get-MgGroupOnenoteSectionGroup [Groups[GroupId].Onenote.SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgGroupOnenoteSectionGroup [Groups[GroupId].Onenote.SectionGroups]' +Notes :: GetMgGroupOnenoteSectionGroup.g.cs: 'Get-MgGroupOnenoteSectionGroup [Groups[GroupId].Onenote.SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgGroupOnenoteSectionGroup [Groups[GroupId].Onenote.SectionGroups]' +Notes :: GetMgSiteOnenoteNotebookSectionGroup.g.cs: 'Get-MgSiteOnenoteNotebookSectionGroup [Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgSiteOnenoteNotebookSectionGroup [Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgSiteOnenoteNotebookSectionGroup.g.cs: 'Get-MgSiteOnenoteNotebookSectionGroup [Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgSiteOnenoteNotebookSectionGroup [Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgSiteOnenoteNotebookSectionGroup.g.cs: 'Get-MgSiteOnenoteNotebookSectionGroup [Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgSiteOnenoteNotebookSectionGroup [Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgSiteOnenoteSectionGroup.g.cs: 'Get-MgSiteOnenoteSectionGroup [Sites[SiteId].Onenote.SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgSiteOnenoteSectionGroup [Sites[SiteId].Onenote.SectionGroups]' +Notes :: GetMgSiteOnenoteSectionGroup.g.cs: 'Get-MgSiteOnenoteSectionGroup [Sites[SiteId].Onenote.SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgSiteOnenoteSectionGroup [Sites[SiteId].Onenote.SectionGroups]' +Notes :: GetMgSiteOnenoteSectionGroup.g.cs: 'Get-MgSiteOnenoteSectionGroup [Sites[SiteId].Onenote.SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgSiteOnenoteSectionGroup [Sites[SiteId].Onenote.SectionGroups]' +Notes :: GetMgUserOnenoteNotebookSectionGroup.g.cs: 'Get-MgUserOnenoteNotebookSectionGroup [Users[UserId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgUserOnenoteNotebookSectionGroup [Users[UserId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgUserOnenoteNotebookSectionGroup.g.cs: 'Get-MgUserOnenoteNotebookSectionGroup [Users[UserId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgUserOnenoteNotebookSectionGroup [Users[UserId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgUserOnenoteNotebookSectionGroup.g.cs: 'Get-MgUserOnenoteNotebookSectionGroup [Users[UserId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgUserOnenoteNotebookSectionGroup [Users[UserId].Onenote.Notebooks[NotebookId].SectionGroups]' +Notes :: GetMgUserOnenoteSectionGroup.g.cs: 'Get-MgUserOnenoteSectionGroup [Users[UserId].Onenote.SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgUserOnenoteSectionGroup [Users[UserId].Onenote.SectionGroups]' +Notes :: GetMgUserOnenoteSectionGroup.g.cs: 'Get-MgUserOnenoteSectionGroup [Users[UserId].Onenote.SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgUserOnenoteSectionGroup [Users[UserId].Onenote.SectionGroups]' +Notes :: GetMgUserOnenoteSectionGroup.g.cs: 'Get-MgUserOnenoteSectionGroup [Users[UserId].Onenote.SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgUserOnenoteSectionGroup [Users[UserId].Onenote.SectionGroups]' +Sites :: NewMgGroupSiteTermStoreGroupSetChild.g.cs: 'New-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children]' collides with already-written 'New-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children]' +Sites :: UpdateMgGroupSiteTermStoreGroupSetChild.g.cs: 'Update-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Update-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId]]' +Sites :: RemoveMgGroupSiteTermStoreGroupSetChild.g.cs: 'Remove-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Remove-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId]]' +Sites :: NewMgGroupSiteTermStoreGroupSetChildRelation.g.cs: 'New-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations]' collides with already-written 'New-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: UpdateMgGroupSiteTermStoreGroupSetChildRelation.g.cs: 'Update-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Update-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: RemoveMgGroupSiteTermStoreGroupSetChildRelation.g.cs: 'Remove-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Remove-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: NewMgGroupSiteTermStoreSetChild.g.cs: 'New-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children]' collides with already-written 'New-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: UpdateMgGroupSiteTermStoreSetChild.g.cs: 'Update-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Update-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId]]' +Sites :: RemoveMgGroupSiteTermStoreSetChild.g.cs: 'Remove-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Remove-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId]]' +Sites :: NewMgGroupSiteTermStoreSetChildRelation.g.cs: 'New-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations]' collides with already-written 'New-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: UpdateMgGroupSiteTermStoreSetChildRelation.g.cs: 'Update-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Update-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: RemoveMgGroupSiteTermStoreSetChildRelation.g.cs: 'Remove-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Remove-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: NewMgGroupSiteTermStoreSetParentGroupSetChild.g.cs: 'New-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children]' collides with already-written 'New-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: UpdateMgGroupSiteTermStoreSetParentGroupSetChild.g.cs: 'Update-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1]]' collides with already-written 'Update-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId]]' +Sites :: RemoveMgGroupSiteTermStoreSetParentGroupSetChild.g.cs: 'Remove-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1]]' collides with already-written 'Remove-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId]]' +Sites :: NewMgGroupSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'New-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations]' collides with already-written 'New-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: UpdateMgGroupSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Update-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId]]' collides with already-written 'Update-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: RemoveMgGroupSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Remove-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId]]' collides with already-written 'Remove-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: NewMgSiteTermStoreGroupSetChild.g.cs: 'New-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children]' collides with already-written 'New-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children]' +Sites :: UpdateMgSiteTermStoreGroupSetChild.g.cs: 'Update-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Update-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId]]' +Sites :: RemoveMgSiteTermStoreGroupSetChild.g.cs: 'Remove-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Remove-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId]]' +Sites :: NewMgSiteTermStoreGroupSetChildRelation.g.cs: 'New-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations]' collides with already-written 'New-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: UpdateMgSiteTermStoreGroupSetChildRelation.g.cs: 'Update-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Update-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: RemoveMgSiteTermStoreGroupSetChildRelation.g.cs: 'Remove-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Remove-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: NewMgSiteTermStoreSetChild.g.cs: 'New-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children]' collides with already-written 'New-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: UpdateMgSiteTermStoreSetChild.g.cs: 'Update-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Update-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId]]' +Sites :: RemoveMgSiteTermStoreSetChild.g.cs: 'Remove-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Remove-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId]]' +Sites :: NewMgSiteTermStoreSetChildRelation.g.cs: 'New-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations]' collides with already-written 'New-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: UpdateMgSiteTermStoreSetChildRelation.g.cs: 'Update-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Update-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: RemoveMgSiteTermStoreSetChildRelation.g.cs: 'Remove-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Remove-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: NewMgSiteTermStoreSetParentGroupSetChild.g.cs: 'New-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children]' collides with already-written 'New-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: UpdateMgSiteTermStoreSetParentGroupSetChild.g.cs: 'Update-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1]]' collides with already-written 'Update-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId]]' +Sites :: RemoveMgSiteTermStoreSetParentGroupSetChild.g.cs: 'Remove-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1]]' collides with already-written 'Remove-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId]]' +Sites :: NewMgSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'New-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations]' collides with already-written 'New-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: UpdateMgSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Update-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId]]' collides with already-written 'Update-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: RemoveMgSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Remove-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId]]' collides with already-written 'Remove-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId]]' +Sites :: GetMgGroupSiteOnenoteNotebookSectionGroup.g.cs: 'Get-MgGroupSiteOnenoteNotebookSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgGroupSiteOnenoteNotebookSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups]' +Sites :: GetMgGroupSiteOnenoteNotebookSectionGroup.g.cs: 'Get-MgGroupSiteOnenoteNotebookSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgGroupSiteOnenoteNotebookSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups]' +Sites :: GetMgGroupSiteOnenoteNotebookSectionGroup.g.cs: 'Get-MgGroupSiteOnenoteNotebookSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgGroupSiteOnenoteNotebookSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.Notebooks[NotebookId].SectionGroups]' +Sites :: GetMgGroupSiteOnenoteSectionGroup.g.cs: 'Get-MgGroupSiteOnenoteSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.SectionGroups[SectionGroupId]]' collides with already-written 'Get-MgGroupSiteOnenoteSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.SectionGroups]' +Sites :: GetMgGroupSiteOnenoteSectionGroup.g.cs: 'Get-MgGroupSiteOnenoteSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.SectionGroups[SectionGroupId].SectionGroups]' collides with already-written 'Get-MgGroupSiteOnenoteSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.SectionGroups]' +Sites :: GetMgGroupSiteOnenoteSectionGroup.g.cs: 'Get-MgGroupSiteOnenoteSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.SectionGroups[SectionGroupId].SectionGroups[SectionGroupId1]]' collides with already-written 'Get-MgGroupSiteOnenoteSectionGroup [Groups[GroupId].Sites[SiteId].Onenote.SectionGroups]' +Sites :: GetMgGroupSiteTermStoreGroupSetChild.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId]]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children]' +Sites :: GetMgGroupSiteTermStoreGroupSetChild.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children]' +Sites :: GetMgGroupSiteTermStoreGroupSetChild.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children]' +Sites :: GetMgGroupSiteTermStoreGroupSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreGroupSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreGroupSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreGroupSetChildRelationFromTerm.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChildRelationFromTerm [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations[RelationId].FromTerm]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChildRelationFromTerm [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].FromTerm]' +Sites :: GetMgGroupSiteTermStoreGroupSetChildRelationSet.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChildRelationSet [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations[RelationId].Set]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChildRelationSet [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].Set]' +Sites :: GetMgGroupSiteTermStoreGroupSetChildRelationToTerm.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChildRelationToTerm [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Relations[RelationId].ToTerm]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChildRelationToTerm [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].ToTerm]' +Sites :: GetMgGroupSiteTermStoreGroupSetChildSet.g.cs: 'Get-MgGroupSiteTermStoreGroupSetChildSet [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Set]' collides with already-written 'Get-MgGroupSiteTermStoreGroupSetChildSet [Groups[GroupId].Sites[SiteId].TermStore.Groups[GroupId1].Sets[SetId].Children[TermId].Children[TermId1].Set]' +Sites :: GetMgGroupSiteTermStoreSetChild.g.cs: 'Get-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId]]' collides with already-written 'Get-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: GetMgGroupSiteTermStoreSetChild.g.cs: 'Get-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children]' collides with already-written 'Get-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: GetMgGroupSiteTermStoreSetChild.g.cs: 'Get-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Get-MgGroupSiteTermStoreSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: GetMgGroupSiteTermStoreSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' collides with already-written 'Get-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations]' collides with already-written 'Get-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Get-MgGroupSiteTermStoreSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreSetChildRelationFromTerm.g.cs: 'Get-MgGroupSiteTermStoreSetChildRelationFromTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId].FromTerm]' collides with already-written 'Get-MgGroupSiteTermStoreSetChildRelationFromTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].FromTerm]' +Sites :: GetMgGroupSiteTermStoreSetChildRelationSet.g.cs: 'Get-MgGroupSiteTermStoreSetChildRelationSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId].Set]' collides with already-written 'Get-MgGroupSiteTermStoreSetChildRelationSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].Set]' +Sites :: GetMgGroupSiteTermStoreSetChildRelationToTerm.g.cs: 'Get-MgGroupSiteTermStoreSetChildRelationToTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId].ToTerm]' collides with already-written 'Get-MgGroupSiteTermStoreSetChildRelationToTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].ToTerm]' +Sites :: GetMgGroupSiteTermStoreSetChildSet.g.cs: 'Get-MgGroupSiteTermStoreSetChildSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Set]' collides with already-written 'Get-MgGroupSiteTermStoreSetChildSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Set]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChild.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId]]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChild.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChild.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1]]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChild [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId]]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId]]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId].FromTerm]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId].FromTerm]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChildRelationSet.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId].Set]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId].Set]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId].ToTerm]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId].ToTerm]' +Sites :: GetMgGroupSiteTermStoreSetParentGroupSetChildSet.g.cs: 'Get-MgGroupSiteTermStoreSetParentGroupSetChildSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Set]' collides with already-written 'Get-MgGroupSiteTermStoreSetParentGroupSetChildSet [Groups[GroupId].Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Set]' +Sites :: GetMgSiteTermStoreGroupSetChild.g.cs: 'Get-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId]]' collides with already-written 'Get-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children]' +Sites :: GetMgSiteTermStoreGroupSetChild.g.cs: 'Get-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children]' collides with already-written 'Get-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children]' +Sites :: GetMgSiteTermStoreGroupSetChild.g.cs: 'Get-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Get-MgSiteTermStoreGroupSetChild [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children]' +Sites :: GetMgSiteTermStoreGroupSetChildRelation.g.cs: 'Get-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' collides with already-written 'Get-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreGroupSetChildRelation.g.cs: 'Get-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations]' collides with already-written 'Get-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreGroupSetChildRelation.g.cs: 'Get-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Get-MgSiteTermStoreGroupSetChildRelation [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreGroupSetChildRelationFromTerm.g.cs: 'Get-MgSiteTermStoreGroupSetChildRelationFromTerm [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations[RelationId].FromTerm]' collides with already-written 'Get-MgSiteTermStoreGroupSetChildRelationFromTerm [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].FromTerm]' +Sites :: GetMgSiteTermStoreGroupSetChildRelationSet.g.cs: 'Get-MgSiteTermStoreGroupSetChildRelationSet [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations[RelationId].Set]' collides with already-written 'Get-MgSiteTermStoreGroupSetChildRelationSet [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].Set]' +Sites :: GetMgSiteTermStoreGroupSetChildRelationToTerm.g.cs: 'Get-MgSiteTermStoreGroupSetChildRelationToTerm [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Relations[RelationId].ToTerm]' collides with already-written 'Get-MgSiteTermStoreGroupSetChildRelationToTerm [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].ToTerm]' +Sites :: GetMgSiteTermStoreGroupSetChildSet.g.cs: 'Get-MgSiteTermStoreGroupSetChildSet [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Set]' collides with already-written 'Get-MgSiteTermStoreGroupSetChildSet [Sites[SiteId].TermStore.Groups[GroupId].Sets[SetId].Children[TermId].Children[TermId1].Set]' +Sites :: GetMgSiteTermStoreSetChild.g.cs: 'Get-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId]]' collides with already-written 'Get-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: GetMgSiteTermStoreSetChild.g.cs: 'Get-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children]' collides with already-written 'Get-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: GetMgSiteTermStoreSetChild.g.cs: 'Get-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1]]' collides with already-written 'Get-MgSiteTermStoreSetChild [Sites[SiteId].TermStore.Sets[SetId].Children]' +Sites :: GetMgSiteTermStoreSetChildRelation.g.cs: 'Get-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId]]' collides with already-written 'Get-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreSetChildRelation.g.cs: 'Get-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations]' collides with already-written 'Get-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreSetChildRelation.g.cs: 'Get-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId]]' collides with already-written 'Get-MgSiteTermStoreSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreSetChildRelationFromTerm.g.cs: 'Get-MgSiteTermStoreSetChildRelationFromTerm [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId].FromTerm]' collides with already-written 'Get-MgSiteTermStoreSetChildRelationFromTerm [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].FromTerm]' +Sites :: GetMgSiteTermStoreSetChildRelationSet.g.cs: 'Get-MgSiteTermStoreSetChildRelationSet [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId].Set]' collides with already-written 'Get-MgSiteTermStoreSetChildRelationSet [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].Set]' +Sites :: GetMgSiteTermStoreSetChildRelationToTerm.g.cs: 'Get-MgSiteTermStoreSetChildRelationToTerm [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Relations[RelationId].ToTerm]' collides with already-written 'Get-MgSiteTermStoreSetChildRelationToTerm [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Relations[RelationId].ToTerm]' +Sites :: GetMgSiteTermStoreSetChildSet.g.cs: 'Get-MgSiteTermStoreSetChildSet [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Set]' collides with already-written 'Get-MgSiteTermStoreSetChildSet [Sites[SiteId].TermStore.Sets[SetId].Children[TermId].Children[TermId1].Set]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChild.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId]]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChild.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChild.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1]]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChild [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId]]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChildRelation.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId]]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChildRelation [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChildRelationFromTerm.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChildRelationFromTerm [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId].FromTerm]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChildRelationFromTerm [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId].FromTerm]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChildRelationSet.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChildRelationSet [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId].Set]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChildRelationSet [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId].Set]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChildRelationToTerm.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChildRelationToTerm [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Relations[RelationId].ToTerm]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChildRelationToTerm [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Relations[RelationId].ToTerm]' +Sites :: GetMgSiteTermStoreSetParentGroupSetChildSet.g.cs: 'Get-MgSiteTermStoreSetParentGroupSetChildSet [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Set]' collides with already-written 'Get-MgSiteTermStoreSetParentGroupSetChildSet [Sites[SiteId].TermStore.Sets[SetId].ParentGroup.Sets[SetId1].Children[TermId].Children[TermId1].Set]' diff --git a/tools/WrapperGenerator/data/collision-renames.v1.0.json b/tools/WrapperGenerator/data/collision-renames.v1.0.json new file mode 100644 index 0000000000..5a42578886 --- /dev/null +++ b/tools/WrapperGenerator/data/collision-renames.v1.0.json @@ -0,0 +1,1254 @@ +[ + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRoleResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScopeResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}", + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles", + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}", + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes", + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScope" + ] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScope" + ] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}", + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles", + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource/environment", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource/environment" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}", + "action": "rename", + "evidence": { + "shipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementCatalogResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes", + "action": "rename", + "evidence": { + "shipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceScope" + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes" + ], + "counterpartShipsAs": [] + }, + "replacementNoun": "EntitlementManagementResourceRequestCatalogResourceScope" + } +] diff --git a/tools/WrapperGenerator/data/collision-resolution-ledger.v1.0.csv b/tools/WrapperGenerator/data/collision-resolution-ledger.v1.0.csv new file mode 100644 index 0000000000..4713ff7a9b --- /dev/null +++ b/tools/WrapperGenerator/data/collision-resolution-ledger.v1.0.csv @@ -0,0 +1,366 @@ +"Method","Uri","Modules","OurName","Action","ShipsAs","CounterpartUris","CounterpartShipsAs" +"DELETE","/groups/{}/settings/{}","Groups","Remove-MgGroupSetting","keep","Remove-MgGroupSetting","/groupsettings/{}","" +"DELETE","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}","Sites","Remove-MgGroupSiteTermStoreGroupSetChild","keep","Remove-MgGroupSiteTermStoreGroupSetChild","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","" +"DELETE","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Sites","Remove-MgGroupSiteTermStoreGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}","Remove-MgGroupSiteTermStoreGroupSetChild" +"DELETE","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Sites","Remove-MgGroupSiteTermStoreGroupSetChildRelation","keep","Remove-MgGroupSiteTermStoreGroupSetChildRelation","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","" +"DELETE","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Sites","Remove-MgGroupSiteTermStoreGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Remove-MgGroupSiteTermStoreGroupSetChildRelation" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/children/{}","Sites","Remove-MgGroupSiteTermStoreSetChild","keep","Remove-MgGroupSiteTermStoreSetChild","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}","" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}","Sites","Remove-MgGroupSiteTermStoreSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}","Remove-MgGroupSiteTermStoreSetChild" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Sites","Remove-MgGroupSiteTermStoreSetChildRelation","keep","Remove-MgGroupSiteTermStoreSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}","" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}","Sites","Remove-MgGroupSiteTermStoreSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Remove-MgGroupSiteTermStoreSetChildRelation" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Sites","Remove-MgGroupSiteTermStoreSetParentGroupSetChild","keep","Remove-MgGroupSiteTermStoreSetParentGroupSetChild","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Sites","Remove-MgGroupSiteTermStoreSetParentGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Remove-MgGroupSiteTermStoreSetParentGroupSetChild" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Sites","Remove-MgGroupSiteTermStoreSetParentGroupSetChildRelation","keep","Remove-MgGroupSiteTermStoreSetParentGroupSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","" +"DELETE","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Sites","Remove-MgGroupSiteTermStoreSetParentGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Remove-MgGroupSiteTermStoreSetParentGroupSetChildRelation" +"DELETE","/groupsettings/{}","Groups","Remove-MgGroupSetting","suppress","","/groups/{}/settings/{}","Remove-MgGroupSetting" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","rename","Remove-MgEntitlementManagementCatalogResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource","rename","Remove-MgEntitlementManagementCatalogResourceRoleResource","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","rename","Remove-MgEntitlementManagementCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource","rename","Remove-MgEntitlementManagementCatalogResourceRoleResourceScopeResource","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}","Remove-MgEntitlementManagementCatalogResourceRole" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource","Remove-MgEntitlementManagementCatalogResourceRoleResource" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}","Remove-MgEntitlementManagementCatalogResourceRoleResourceScope" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource","Remove-MgEntitlementManagementCatalogResourceRoleResourceScopeResource" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}","Remove-MgEntitlementManagementCatalogResourceScope" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource","rename","Remove-MgEntitlementManagementCatalogResourceScopeResource","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","rename","Remove-MgEntitlementManagementCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource","rename","Remove-MgEntitlementManagementCatalogResourceScopeResourceRoleResource","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","rename","Remove-MgEntitlementManagementCatalogResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}","" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource","Remove-MgEntitlementManagementCatalogResourceScopeResource" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}","Remove-MgEntitlementManagementCatalogResourceScopeResourceRole" +"DELETE","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource","Remove-MgEntitlementManagementCatalogResourceScopeResourceRoleResource" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}","Remove-MgEntitlementManagementResourceRequestCatalogResourceRole" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource","Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResource" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}","Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource","Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}","Remove-MgEntitlementManagementResourceRequestCatalogResourceScope" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","rename","Remove-MgEntitlementManagementResourceRequestCatalogResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}","" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource","Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResource" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}","Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" +"DELETE","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource","Identity.Governance","Remove-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource","Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" +"DELETE","/sites/{}/termstore/groups/{}/sets/{}/children/{}","Sites","Remove-MgSiteTermStoreGroupSetChild","keep","Remove-MgSiteTermStoreGroupSetChild","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","" +"DELETE","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Sites","Remove-MgSiteTermStoreGroupSetChild","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}","Remove-MgSiteTermStoreGroupSetChild" +"DELETE","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Sites","Remove-MgSiteTermStoreGroupSetChildRelation","keep","Remove-MgSiteTermStoreGroupSetChildRelation","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","" +"DELETE","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Sites","Remove-MgSiteTermStoreGroupSetChildRelation","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Remove-MgSiteTermStoreGroupSetChildRelation" +"DELETE","/sites/{}/termstore/sets/{}/children/{}","Sites","Remove-MgSiteTermStoreSetChild","keep","Remove-MgSiteTermStoreSetChild","/sites/{}/termstore/sets/{}/children/{}/children/{}","" +"DELETE","/sites/{}/termstore/sets/{}/children/{}/children/{}","Sites","Remove-MgSiteTermStoreSetChild","suppress","","/sites/{}/termstore/sets/{}/children/{}","Remove-MgSiteTermStoreSetChild" +"DELETE","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Sites","Remove-MgSiteTermStoreSetChildRelation","keep","Remove-MgSiteTermStoreSetChildRelation","/sites/{}/termstore/sets/{}/children/{}/relations/{}","" +"DELETE","/sites/{}/termstore/sets/{}/children/{}/relations/{}","Sites","Remove-MgSiteTermStoreSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Remove-MgSiteTermStoreSetChildRelation" +"DELETE","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Sites","Remove-MgSiteTermStoreSetParentGroupSetChild","keep","Remove-MgSiteTermStoreSetParentGroupSetChild","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","" +"DELETE","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Sites","Remove-MgSiteTermStoreSetParentGroupSetChild","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Remove-MgSiteTermStoreSetParentGroupSetChild" +"DELETE","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Sites","Remove-MgSiteTermStoreSetParentGroupSetChildRelation","keep","Remove-MgSiteTermStoreSetParentGroupSetChildRelation","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","" +"DELETE","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Sites","Remove-MgSiteTermStoreSetParentGroupSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Remove-MgSiteTermStoreSetParentGroupSetChildRelation" +"GET","/groups/{}/calendar/calendarview","Calendar","Get-MgGroupCalendarView","keep","Get-MgGroupCalendarView","/groups/{}/calendarview","" +"GET","/groups/{}/calendarview","Calendar","Get-MgGroupCalendarView","suppress","","/groups/{}/calendar/calendarview","Get-MgGroupCalendarView" +"GET","/groups/{}/onenote/notebooks/{}/sectiongroups","Notes","Get-MgGroupOnenoteNotebookSectionGroup","keep","Get-MgGroupOnenoteNotebookSectionGroup","/groups/{}/onenote/notebooks/{}/sectiongroups/{};/groups/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups;/groups/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Get-MgGroupOnenoteNotebookSectionGroup" +"GET","/groups/{}/onenote/notebooks/{}/sectiongroups/{}","Notes","Get-MgGroupOnenoteNotebookSectionGroup","keep","Get-MgGroupOnenoteNotebookSectionGroup","/groups/{}/onenote/notebooks/{}/sectiongroups","Get-MgGroupOnenoteNotebookSectionGroup" +"GET","/groups/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups","Notes","Get-MgGroupOnenoteNotebookSectionGroup","suppress","","/groups/{}/onenote/notebooks/{}/sectiongroups","Get-MgGroupOnenoteNotebookSectionGroup" +"GET","/groups/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Notes","Get-MgGroupOnenoteNotebookSectionGroup","suppress","","/groups/{}/onenote/notebooks/{}/sectiongroups","Get-MgGroupOnenoteNotebookSectionGroup" +"GET","/groups/{}/onenote/sectiongroups","Notes","Get-MgGroupOnenoteSectionGroup","keep","Get-MgGroupOnenoteSectionGroup","/groups/{}/onenote/sectiongroups/{};/groups/{}/onenote/sectiongroups/{}/sectiongroups;/groups/{}/onenote/sectiongroups/{}/sectiongroups/{}","Get-MgGroupOnenoteSectionGroup" +"GET","/groups/{}/onenote/sectiongroups/{}","Notes","Get-MgGroupOnenoteSectionGroup","keep","Get-MgGroupOnenoteSectionGroup","/groups/{}/onenote/sectiongroups","Get-MgGroupOnenoteSectionGroup" +"GET","/groups/{}/onenote/sectiongroups/{}/sectiongroups","Notes","Get-MgGroupOnenoteSectionGroup","suppress","","/groups/{}/onenote/sectiongroups","Get-MgGroupOnenoteSectionGroup" +"GET","/groups/{}/onenote/sectiongroups/{}/sectiongroups/{}","Notes","Get-MgGroupOnenoteSectionGroup","suppress","","/groups/{}/onenote/sectiongroups","Get-MgGroupOnenoteSectionGroup" +"GET","/groups/{}/photo","Groups","Get-MgGroupPhoto","keep","Get-MgGroupPhoto","/groups/{}/photos","Get-MgGroupPhoto" +"GET","/groups/{}/photos","Groups","Get-MgGroupPhoto","suppress-deferred","Get-MgGroupPhoto","/groups/{}/photo","Get-MgGroupPhoto" +"GET","/groups/{}/settings","Groups","Get-MgGroupSetting","keep","Get-MgGroupSetting","/groups/{}/settings/{};/groupsettings;/groupsettings/{}","Get-MgGroupSetting" +"GET","/groups/{}/settings/{}","Groups","Get-MgGroupSetting","keep","Get-MgGroupSetting","/groups/{}/settings","Get-MgGroupSetting" +"GET","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups","Sites","Get-MgGroupSiteOnenoteNotebookSectionGroup","keep","Get-MgGroupSiteOnenoteNotebookSectionGroup","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{};/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups;/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Get-MgGroupSiteOnenoteNotebookSectionGroup" +"GET","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{}","Sites","Get-MgGroupSiteOnenoteNotebookSectionGroup","keep","Get-MgGroupSiteOnenoteNotebookSectionGroup","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups","Get-MgGroupSiteOnenoteNotebookSectionGroup" +"GET","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups","Sites","Get-MgGroupSiteOnenoteNotebookSectionGroup","suppress","","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups","Get-MgGroupSiteOnenoteNotebookSectionGroup" +"GET","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Sites","Get-MgGroupSiteOnenoteNotebookSectionGroup","suppress","","/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups","Get-MgGroupSiteOnenoteNotebookSectionGroup" +"GET","/groups/{}/sites/{}/onenote/sectiongroups","Sites","Get-MgGroupSiteOnenoteSectionGroup","keep","Get-MgGroupSiteOnenoteSectionGroup","/groups/{}/sites/{}/onenote/sectiongroups/{};/groups/{}/sites/{}/onenote/sectiongroups/{}/sectiongroups;/groups/{}/sites/{}/onenote/sectiongroups/{}/sectiongroups/{}","Get-MgGroupSiteOnenoteSectionGroup" +"GET","/groups/{}/sites/{}/onenote/sectiongroups/{}","Sites","Get-MgGroupSiteOnenoteSectionGroup","keep","Get-MgGroupSiteOnenoteSectionGroup","/groups/{}/sites/{}/onenote/sectiongroups","Get-MgGroupSiteOnenoteSectionGroup" +"GET","/groups/{}/sites/{}/onenote/sectiongroups/{}/sectiongroups","Sites","Get-MgGroupSiteOnenoteSectionGroup","suppress","","/groups/{}/sites/{}/onenote/sectiongroups","Get-MgGroupSiteOnenoteSectionGroup" +"GET","/groups/{}/sites/{}/onenote/sectiongroups/{}/sectiongroups/{}","Sites","Get-MgGroupSiteOnenoteSectionGroup","suppress","","/groups/{}/sites/{}/onenote/sectiongroups","Get-MgGroupSiteOnenoteSectionGroup" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children","Sites","Get-MgGroupSiteTermStoreGroupSetChild","keep","Get-MgGroupSiteTermStoreGroupSetChild","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{};/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children;/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Get-MgGroupSiteTermStoreGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}","Sites","Get-MgGroupSiteTermStoreGroupSetChild","keep","Get-MgGroupSiteTermStoreGroupSetChild","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children","Get-MgGroupSiteTermStoreGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children","Sites","Get-MgGroupSiteTermStoreGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children","Get-MgGroupSiteTermStoreGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Sites","Get-MgGroupSiteTermStoreGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children","Get-MgGroupSiteTermStoreGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelation","keep","Get-MgGroupSiteTermStoreGroupSetChildRelation","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{};/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations;/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Get-MgGroupSiteTermStoreGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelation","keep","Get-MgGroupSiteTermStoreGroupSetChildRelation","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/fromterm","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelationFromTerm","keep","Get-MgGroupSiteTermStoreGroupSetChildRelationFromTerm","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/fromterm","" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/set","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelationSet","keep","Get-MgGroupSiteTermStoreGroupSetChildRelationSet","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/set","" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/toterm","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelationToTerm","keep","Get-MgGroupSiteTermStoreGroupSetChildRelationToTerm","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/toterm","" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/set","Sites","Get-MgGroupSiteTermStoreGroupSetChildSet","keep","Get-MgGroupSiteTermStoreGroupSetChildSet","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/set","" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/fromterm","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelationFromTerm","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/fromterm","Get-MgGroupSiteTermStoreGroupSetChildRelationFromTerm" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/set","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelationSet","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/set","Get-MgGroupSiteTermStoreGroupSetChildRelationSet" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/toterm","Sites","Get-MgGroupSiteTermStoreGroupSetChildRelationToTerm","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/toterm","Get-MgGroupSiteTermStoreGroupSetChildRelationToTerm" +"GET","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/set","Sites","Get-MgGroupSiteTermStoreGroupSetChildSet","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/set","Get-MgGroupSiteTermStoreGroupSetChildSet" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children","Sites","Get-MgGroupSiteTermStoreSetChild","keep","Get-MgGroupSiteTermStoreSetChild","/groups/{}/sites/{}/termstore/sets/{}/children/{};/groups/{}/sites/{}/termstore/sets/{}/children/{}/children;/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}","Get-MgGroupSiteTermStoreSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}","Sites","Get-MgGroupSiteTermStoreSetChild","keep","Get-MgGroupSiteTermStoreSetChild","/groups/{}/sites/{}/termstore/sets/{}/children","Get-MgGroupSiteTermStoreSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children","Sites","Get-MgGroupSiteTermStoreSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children","Get-MgGroupSiteTermStoreSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}","Sites","Get-MgGroupSiteTermStoreSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children","Get-MgGroupSiteTermStoreSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Sites","Get-MgGroupSiteTermStoreSetChildRelation","keep","Get-MgGroupSiteTermStoreSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{};/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations;/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}","Get-MgGroupSiteTermStoreSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Sites","Get-MgGroupSiteTermStoreSetChildRelation","keep","Get-MgGroupSiteTermStoreSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/fromterm","Sites","Get-MgGroupSiteTermStoreSetChildRelationFromTerm","keep","Get-MgGroupSiteTermStoreSetChildRelationFromTerm","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/fromterm","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/set","Sites","Get-MgGroupSiteTermStoreSetChildRelationSet","keep","Get-MgGroupSiteTermStoreSetChildRelationSet","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/set","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/toterm","Sites","Get-MgGroupSiteTermStoreSetChildRelationToTerm","keep","Get-MgGroupSiteTermStoreSetChildRelationToTerm","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/toterm","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/set","Sites","Get-MgGroupSiteTermStoreSetChildSet","keep","Get-MgGroupSiteTermStoreSetChildSet","/groups/{}/sites/{}/termstore/sets/{}/children/{}/set","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations","Sites","Get-MgGroupSiteTermStoreSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}","Sites","Get-MgGroupSiteTermStoreSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/fromterm","Sites","Get-MgGroupSiteTermStoreSetChildRelationFromTerm","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/fromterm","Get-MgGroupSiteTermStoreSetChildRelationFromTerm" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/set","Sites","Get-MgGroupSiteTermStoreSetChildRelationSet","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/set","Get-MgGroupSiteTermStoreSetChildRelationSet" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/toterm","Sites","Get-MgGroupSiteTermStoreSetChildRelationToTerm","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/toterm","Get-MgGroupSiteTermStoreSetChildRelationToTerm" +"GET","/groups/{}/sites/{}/termstore/sets/{}/children/{}/set","Sites","Get-MgGroupSiteTermStoreSetChildSet","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/set","Get-MgGroupSiteTermStoreSetChildSet" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChild","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChild","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{};/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children;/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Get-MgGroupSiteTermStoreSetParentGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChild","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChild","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Get-MgGroupSiteTermStoreSetParentGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Get-MgGroupSiteTermStoreSetParentGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Get-MgGroupSiteTermStoreSetParentGroupSetChild" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{};/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations;/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/fromterm","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/fromterm","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/set","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationSet","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationSet","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/set","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/toterm","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/toterm","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/set","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildSet","keep","Get-MgGroupSiteTermStoreSetParentGroupSetChildSet","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/set","" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/fromterm","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/fromterm","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/set","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationSet","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/set","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationSet" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/toterm","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/toterm","Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm" +"GET","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/set","Sites","Get-MgGroupSiteTermStoreSetParentGroupSetChildSet","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/set","Get-MgGroupSiteTermStoreSetParentGroupSetChildSet" +"GET","/groupsettings","Groups","Get-MgGroupSetting","suppress","","/groups/{}/settings","Get-MgGroupSetting" +"GET","/groupsettings/{}","Groups","Get-MgGroupSetting","suppress","","/groups/{}/settings","Get-MgGroupSetting" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","rename","Get-MgEntitlementManagementCatalogResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{};/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles;/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}","Get-MgEntitlementManagementCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","rename","Get-MgEntitlementManagementCatalogResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles","Get-MgEntitlementManagementCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource","rename","Get-MgEntitlementManagementCatalogResourceRoleResource","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceEnvironment","rename","Get-MgEntitlementManagementCatalogResourceRoleResourceEnvironment","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","rename","Get-MgEntitlementManagementCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{};/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes;/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}","Get-MgEntitlementManagementCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","rename","Get-MgEntitlementManagementCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes","Get-MgEntitlementManagementCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource","rename","Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResource","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment","rename","Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles","Get-MgEntitlementManagementCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles","Get-MgEntitlementManagementCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource","Get-MgEntitlementManagementCatalogResourceRoleResource" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/environment","Get-MgEntitlementManagementCatalogResourceRoleResourceEnvironment" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes","Get-MgEntitlementManagementCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes","Get-MgEntitlementManagementCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource","Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResource" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource/environment","Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{};/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes;/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}","Get-MgEntitlementManagementCatalogResourceScope" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource","rename","Get-MgEntitlementManagementCatalogResourceScopeResource","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceEnvironment","rename","Get-MgEntitlementManagementCatalogResourceScopeResourceEnvironment","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","rename","Get-MgEntitlementManagementCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{};/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles;/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}","Get-MgEntitlementManagementCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","rename","Get-MgEntitlementManagementCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles","Get-MgEntitlementManagementCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource","rename","Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResource","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment","rename","Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","rename","Get-MgEntitlementManagementCatalogResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","rename","Get-MgEntitlementManagementCatalogResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes","" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource","Get-MgEntitlementManagementCatalogResourceScopeResource" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/environment","Get-MgEntitlementManagementCatalogResourceScopeResourceEnvironment" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles","Get-MgEntitlementManagementCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles","Get-MgEntitlementManagementCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource","Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResource" +"GET","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource/environment","Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{};/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles;/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}","Get-MgEntitlementManagementResourceRequestCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles","Get-MgEntitlementManagementResourceRequestCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{};/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes;/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles","Get-MgEntitlementManagementResourceRequestCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles","Get-MgEntitlementManagementResourceRequestCatalogResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResource" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/environment","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource/environment","Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{};/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes;/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}","Get-MgEntitlementManagementResourceRequestCatalogResourceScope" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{};/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles;/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource/environment","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","rename","Get-MgEntitlementManagementResourceRequestCatalogResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes","" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResource" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/environment","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" +"GET","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource/environment","Identity.Governance","Get-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource/environment","Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment" +"GET","/shares/{}/list/items","Files","Get-MgShareListItem","suppress-deferred","Get-MgShareListItem","/shares/{}/listitem","Get-MgShareListItem" +"GET","/shares/{}/listitem","Files","Get-MgShareListItem","keep","Get-MgShareListItem","/shares/{}/list/items","Get-MgShareListItem" +"GET","/sites/{}/onenote/notebooks/{}/sectiongroups","Notes","Get-MgSiteOnenoteNotebookSectionGroup","keep","Get-MgSiteOnenoteNotebookSectionGroup","/sites/{}/onenote/notebooks/{}/sectiongroups/{};/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups;/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Get-MgSiteOnenoteNotebookSectionGroup" +"GET","/sites/{}/onenote/notebooks/{}/sectiongroups/{}","Notes","Get-MgSiteOnenoteNotebookSectionGroup","keep","Get-MgSiteOnenoteNotebookSectionGroup","/sites/{}/onenote/notebooks/{}/sectiongroups","Get-MgSiteOnenoteNotebookSectionGroup" +"GET","/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups","Notes","Get-MgSiteOnenoteNotebookSectionGroup","suppress","","/sites/{}/onenote/notebooks/{}/sectiongroups","Get-MgSiteOnenoteNotebookSectionGroup" +"GET","/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Notes","Get-MgSiteOnenoteNotebookSectionGroup","suppress","","/sites/{}/onenote/notebooks/{}/sectiongroups","Get-MgSiteOnenoteNotebookSectionGroup" +"GET","/sites/{}/onenote/sectiongroups","Notes","Get-MgSiteOnenoteSectionGroup","keep","Get-MgSiteOnenoteSectionGroup","/sites/{}/onenote/sectiongroups/{};/sites/{}/onenote/sectiongroups/{}/sectiongroups;/sites/{}/onenote/sectiongroups/{}/sectiongroups/{}","Get-MgSiteOnenoteSectionGroup" +"GET","/sites/{}/onenote/sectiongroups/{}","Notes","Get-MgSiteOnenoteSectionGroup","keep","Get-MgSiteOnenoteSectionGroup","/sites/{}/onenote/sectiongroups","Get-MgSiteOnenoteSectionGroup" +"GET","/sites/{}/onenote/sectiongroups/{}/sectiongroups","Notes","Get-MgSiteOnenoteSectionGroup","suppress","","/sites/{}/onenote/sectiongroups","Get-MgSiteOnenoteSectionGroup" +"GET","/sites/{}/onenote/sectiongroups/{}/sectiongroups/{}","Notes","Get-MgSiteOnenoteSectionGroup","suppress","","/sites/{}/onenote/sectiongroups","Get-MgSiteOnenoteSectionGroup" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children","Sites","Get-MgSiteTermStoreGroupSetChild","keep","Get-MgSiteTermStoreGroupSetChild","/sites/{}/termstore/groups/{}/sets/{}/children/{};/sites/{}/termstore/groups/{}/sets/{}/children/{}/children;/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Get-MgSiteTermStoreGroupSetChild" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}","Sites","Get-MgSiteTermStoreGroupSetChild","keep","Get-MgSiteTermStoreGroupSetChild","/sites/{}/termstore/groups/{}/sets/{}/children","Get-MgSiteTermStoreGroupSetChild" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children","Sites","Get-MgSiteTermStoreGroupSetChild","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children","Get-MgSiteTermStoreGroupSetChild" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Sites","Get-MgSiteTermStoreGroupSetChild","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children","Get-MgSiteTermStoreGroupSetChild" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Sites","Get-MgSiteTermStoreGroupSetChildRelation","keep","Get-MgSiteTermStoreGroupSetChildRelation","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{};/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations;/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Get-MgSiteTermStoreGroupSetChildRelation" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Sites","Get-MgSiteTermStoreGroupSetChildRelation","keep","Get-MgSiteTermStoreGroupSetChildRelation","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreGroupSetChildRelation" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/fromterm","Sites","Get-MgSiteTermStoreGroupSetChildRelationFromTerm","keep","Get-MgSiteTermStoreGroupSetChildRelationFromTerm","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/fromterm","" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/set","Sites","Get-MgSiteTermStoreGroupSetChildRelationSet","keep","Get-MgSiteTermStoreGroupSetChildRelationSet","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/set","" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/toterm","Sites","Get-MgSiteTermStoreGroupSetChildRelationToTerm","keep","Get-MgSiteTermStoreGroupSetChildRelationToTerm","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/toterm","" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/set","Sites","Get-MgSiteTermStoreGroupSetChildSet","keep","Get-MgSiteTermStoreGroupSetChildSet","/sites/{}/termstore/groups/{}/sets/{}/children/{}/set","" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations","Sites","Get-MgSiteTermStoreGroupSetChildRelation","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreGroupSetChildRelation" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Sites","Get-MgSiteTermStoreGroupSetChildRelation","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreGroupSetChildRelation" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/fromterm","Sites","Get-MgSiteTermStoreGroupSetChildRelationFromTerm","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/fromterm","Get-MgSiteTermStoreGroupSetChildRelationFromTerm" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/set","Sites","Get-MgSiteTermStoreGroupSetChildRelationSet","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/set","Get-MgSiteTermStoreGroupSetChildRelationSet" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/toterm","Sites","Get-MgSiteTermStoreGroupSetChildRelationToTerm","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/toterm","Get-MgSiteTermStoreGroupSetChildRelationToTerm" +"GET","/sites/{}/termstore/groups/{}/sets/{}/children/{}/set","Sites","Get-MgSiteTermStoreGroupSetChildSet","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/set","Get-MgSiteTermStoreGroupSetChildSet" +"GET","/sites/{}/termstore/sets/{}/children","Sites","Get-MgSiteTermStoreSetChild","keep","Get-MgSiteTermStoreSetChild","/sites/{}/termstore/sets/{}/children/{};/sites/{}/termstore/sets/{}/children/{}/children;/sites/{}/termstore/sets/{}/children/{}/children/{}","Get-MgSiteTermStoreSetChild" +"GET","/sites/{}/termstore/sets/{}/children/{}","Sites","Get-MgSiteTermStoreSetChild","keep","Get-MgSiteTermStoreSetChild","/sites/{}/termstore/sets/{}/children","Get-MgSiteTermStoreSetChild" +"GET","/sites/{}/termstore/sets/{}/children/{}/children","Sites","Get-MgSiteTermStoreSetChild","suppress","","/sites/{}/termstore/sets/{}/children","Get-MgSiteTermStoreSetChild" +"GET","/sites/{}/termstore/sets/{}/children/{}/children/{}","Sites","Get-MgSiteTermStoreSetChild","suppress","","/sites/{}/termstore/sets/{}/children","Get-MgSiteTermStoreSetChild" +"GET","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Sites","Get-MgSiteTermStoreSetChildRelation","keep","Get-MgSiteTermStoreSetChildRelation","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{};/sites/{}/termstore/sets/{}/children/{}/relations;/sites/{}/termstore/sets/{}/children/{}/relations/{}","Get-MgSiteTermStoreSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Sites","Get-MgSiteTermStoreSetChildRelation","keep","Get-MgSiteTermStoreSetChildRelation","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/fromterm","Sites","Get-MgSiteTermStoreSetChildRelationFromTerm","keep","Get-MgSiteTermStoreSetChildRelationFromTerm","/sites/{}/termstore/sets/{}/children/{}/relations/{}/fromterm","" +"GET","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/set","Sites","Get-MgSiteTermStoreSetChildRelationSet","keep","Get-MgSiteTermStoreSetChildRelationSet","/sites/{}/termstore/sets/{}/children/{}/relations/{}/set","" +"GET","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/toterm","Sites","Get-MgSiteTermStoreSetChildRelationToTerm","keep","Get-MgSiteTermStoreSetChildRelationToTerm","/sites/{}/termstore/sets/{}/children/{}/relations/{}/toterm","" +"GET","/sites/{}/termstore/sets/{}/children/{}/children/{}/set","Sites","Get-MgSiteTermStoreSetChildSet","keep","Get-MgSiteTermStoreSetChildSet","/sites/{}/termstore/sets/{}/children/{}/set","" +"GET","/sites/{}/termstore/sets/{}/children/{}/relations","Sites","Get-MgSiteTermStoreSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/children/{}/relations/{}","Sites","Get-MgSiteTermStoreSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/children/{}/relations/{}/fromterm","Sites","Get-MgSiteTermStoreSetChildRelationFromTerm","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/fromterm","Get-MgSiteTermStoreSetChildRelationFromTerm" +"GET","/sites/{}/termstore/sets/{}/children/{}/relations/{}/set","Sites","Get-MgSiteTermStoreSetChildRelationSet","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/set","Get-MgSiteTermStoreSetChildRelationSet" +"GET","/sites/{}/termstore/sets/{}/children/{}/relations/{}/toterm","Sites","Get-MgSiteTermStoreSetChildRelationToTerm","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/toterm","Get-MgSiteTermStoreSetChildRelationToTerm" +"GET","/sites/{}/termstore/sets/{}/children/{}/set","Sites","Get-MgSiteTermStoreSetChildSet","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/set","Get-MgSiteTermStoreSetChildSet" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Sites","Get-MgSiteTermStoreSetParentGroupSetChild","keep","Get-MgSiteTermStoreSetParentGroupSetChild","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{};/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children;/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Get-MgSiteTermStoreSetParentGroupSetChild" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Sites","Get-MgSiteTermStoreSetParentGroupSetChild","keep","Get-MgSiteTermStoreSetParentGroupSetChild","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Get-MgSiteTermStoreSetParentGroupSetChild" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children","Sites","Get-MgSiteTermStoreSetParentGroupSetChild","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Get-MgSiteTermStoreSetParentGroupSetChild" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Sites","Get-MgSiteTermStoreSetParentGroupSetChild","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Get-MgSiteTermStoreSetParentGroupSetChild" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelation","keep","Get-MgSiteTermStoreSetParentGroupSetChildRelation","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{};/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations;/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Get-MgSiteTermStoreSetParentGroupSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelation","keep","Get-MgSiteTermStoreSetParentGroupSetChildRelation","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreSetParentGroupSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/fromterm","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelationFromTerm","keep","Get-MgSiteTermStoreSetParentGroupSetChildRelationFromTerm","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/fromterm","" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/set","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelationSet","keep","Get-MgSiteTermStoreSetParentGroupSetChildRelationSet","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/set","" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/toterm","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelationToTerm","keep","Get-MgSiteTermStoreSetParentGroupSetChildRelationToTerm","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/toterm","" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/set","Sites","Get-MgSiteTermStoreSetParentGroupSetChildSet","keep","Get-MgSiteTermStoreSetParentGroupSetChildSet","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/set","" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreSetParentGroupSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Get-MgSiteTermStoreSetParentGroupSetChildRelation" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/fromterm","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelationFromTerm","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/fromterm","Get-MgSiteTermStoreSetParentGroupSetChildRelationFromTerm" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/set","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelationSet","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/set","Get-MgSiteTermStoreSetParentGroupSetChildRelationSet" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/toterm","Sites","Get-MgSiteTermStoreSetParentGroupSetChildRelationToTerm","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/toterm","Get-MgSiteTermStoreSetParentGroupSetChildRelationToTerm" +"GET","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/set","Sites","Get-MgSiteTermStoreSetParentGroupSetChildSet","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/set","Get-MgSiteTermStoreSetParentGroupSetChildSet" +"GET","/users/{}/calendar/calendarview","Calendar","Get-MgUserCalendarView","keep","Get-MgUserCalendarView","/users/{}/calendars/{}/calendarview;/users/{}/calendarview","" +"GET","/users/{}/calendars/{}/calendarview","Calendar","Get-MgUserCalendarView","suppress","","/users/{}/calendar/calendarview","Get-MgUserCalendarView" +"GET","/users/{}/calendarview","Calendar","Get-MgUserCalendarView","suppress","","/users/{}/calendar/calendarview","Get-MgUserCalendarView" +"GET","/users/{}/onenote/notebooks/{}/sectiongroups","Notes","Get-MgUserOnenoteNotebookSectionGroup","keep","Get-MgUserOnenoteNotebookSectionGroup","/users/{}/onenote/notebooks/{}/sectiongroups/{};/users/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups;/users/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Get-MgUserOnenoteNotebookSectionGroup" +"GET","/users/{}/onenote/notebooks/{}/sectiongroups/{}","Notes","Get-MgUserOnenoteNotebookSectionGroup","keep","Get-MgUserOnenoteNotebookSectionGroup","/users/{}/onenote/notebooks/{}/sectiongroups","Get-MgUserOnenoteNotebookSectionGroup" +"GET","/users/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups","Notes","Get-MgUserOnenoteNotebookSectionGroup","suppress","","/users/{}/onenote/notebooks/{}/sectiongroups","Get-MgUserOnenoteNotebookSectionGroup" +"GET","/users/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}","Notes","Get-MgUserOnenoteNotebookSectionGroup","suppress","","/users/{}/onenote/notebooks/{}/sectiongroups","Get-MgUserOnenoteNotebookSectionGroup" +"GET","/users/{}/onenote/sectiongroups","Notes","Get-MgUserOnenoteSectionGroup","keep","Get-MgUserOnenoteSectionGroup","/users/{}/onenote/sectiongroups/{};/users/{}/onenote/sectiongroups/{}/sectiongroups;/users/{}/onenote/sectiongroups/{}/sectiongroups/{}","Get-MgUserOnenoteSectionGroup" +"GET","/users/{}/onenote/sectiongroups/{}","Notes","Get-MgUserOnenoteSectionGroup","keep","Get-MgUserOnenoteSectionGroup","/users/{}/onenote/sectiongroups","Get-MgUserOnenoteSectionGroup" +"GET","/users/{}/onenote/sectiongroups/{}/sectiongroups","Notes","Get-MgUserOnenoteSectionGroup","suppress","","/users/{}/onenote/sectiongroups","Get-MgUserOnenoteSectionGroup" +"GET","/users/{}/onenote/sectiongroups/{}/sectiongroups/{}","Notes","Get-MgUserOnenoteSectionGroup","suppress","","/users/{}/onenote/sectiongroups","Get-MgUserOnenoteSectionGroup" +"PATCH","/groups/{}/settings/{}","Groups","Update-MgGroupSetting","keep","Update-MgGroupSetting","/groupsettings/{}","" +"PATCH","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}","Sites","Update-MgGroupSiteTermStoreGroupSetChild","keep","Update-MgGroupSiteTermStoreGroupSetChild","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","" +"PATCH","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Sites","Update-MgGroupSiteTermStoreGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}","Update-MgGroupSiteTermStoreGroupSetChild" +"PATCH","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Sites","Update-MgGroupSiteTermStoreGroupSetChildRelation","keep","Update-MgGroupSiteTermStoreGroupSetChildRelation","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","" +"PATCH","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Sites","Update-MgGroupSiteTermStoreGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Update-MgGroupSiteTermStoreGroupSetChildRelation" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/children/{}","Sites","Update-MgGroupSiteTermStoreSetChild","keep","Update-MgGroupSiteTermStoreSetChild","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}","" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}","Sites","Update-MgGroupSiteTermStoreSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}","Update-MgGroupSiteTermStoreSetChild" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Sites","Update-MgGroupSiteTermStoreSetChildRelation","keep","Update-MgGroupSiteTermStoreSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}","" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}","Sites","Update-MgGroupSiteTermStoreSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Update-MgGroupSiteTermStoreSetChildRelation" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Sites","Update-MgGroupSiteTermStoreSetParentGroupSetChild","keep","Update-MgGroupSiteTermStoreSetParentGroupSetChild","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Sites","Update-MgGroupSiteTermStoreSetParentGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Update-MgGroupSiteTermStoreSetParentGroupSetChild" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Sites","Update-MgGroupSiteTermStoreSetParentGroupSetChildRelation","keep","Update-MgGroupSiteTermStoreSetParentGroupSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","" +"PATCH","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Sites","Update-MgGroupSiteTermStoreSetParentGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Update-MgGroupSiteTermStoreSetParentGroupSetChildRelation" +"PATCH","/groupsettings/{}","Groups","Update-MgGroupSetting","suppress","","/groups/{}/settings/{}","Update-MgGroupSetting" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","rename","Update-MgEntitlementManagementCatalogResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","rename","Update-MgEntitlementManagementCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}","Update-MgEntitlementManagementCatalogResourceRole" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}","Update-MgEntitlementManagementCatalogResourceRoleResourceScope" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}","Update-MgEntitlementManagementCatalogResourceScope" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","rename","Update-MgEntitlementManagementCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","rename","Update-MgEntitlementManagementCatalogResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}","Update-MgEntitlementManagementCatalogResourceScopeResourceRole" +"PATCH","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","rename","Update-MgEntitlementManagementResourceRequestCatalogResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","rename","Update-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}","Update-MgEntitlementManagementResourceRequestCatalogResourceRole" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}","Update-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}","Update-MgEntitlementManagementResourceRequestCatalogResourceScope" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","rename","Update-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","rename","Update-MgEntitlementManagementResourceRequestCatalogResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource","" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}","Update-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" +"PATCH","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource","Identity.Governance","Update-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource","" +"PATCH","/sites/{}/termstore/groups/{}/sets/{}/children/{}","Sites","Update-MgSiteTermStoreGroupSetChild","keep","Update-MgSiteTermStoreGroupSetChild","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","" +"PATCH","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}","Sites","Update-MgSiteTermStoreGroupSetChild","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}","Update-MgSiteTermStoreGroupSetChild" +"PATCH","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Sites","Update-MgSiteTermStoreGroupSetChildRelation","keep","Update-MgSiteTermStoreGroupSetChildRelation","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","" +"PATCH","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}","Sites","Update-MgSiteTermStoreGroupSetChildRelation","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}","Update-MgSiteTermStoreGroupSetChildRelation" +"PATCH","/sites/{}/termstore/sets/{}/children/{}","Sites","Update-MgSiteTermStoreSetChild","keep","Update-MgSiteTermStoreSetChild","/sites/{}/termstore/sets/{}/children/{}/children/{}","" +"PATCH","/sites/{}/termstore/sets/{}/children/{}/children/{}","Sites","Update-MgSiteTermStoreSetChild","suppress","","/sites/{}/termstore/sets/{}/children/{}","Update-MgSiteTermStoreSetChild" +"PATCH","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Sites","Update-MgSiteTermStoreSetChildRelation","keep","Update-MgSiteTermStoreSetChildRelation","/sites/{}/termstore/sets/{}/children/{}/relations/{}","" +"PATCH","/sites/{}/termstore/sets/{}/children/{}/relations/{}","Sites","Update-MgSiteTermStoreSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}","Update-MgSiteTermStoreSetChildRelation" +"PATCH","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Sites","Update-MgSiteTermStoreSetParentGroupSetChild","keep","Update-MgSiteTermStoreSetParentGroupSetChild","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","" +"PATCH","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}","Sites","Update-MgSiteTermStoreSetParentGroupSetChild","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}","Update-MgSiteTermStoreSetParentGroupSetChild" +"PATCH","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Sites","Update-MgSiteTermStoreSetParentGroupSetChildRelation","keep","Update-MgSiteTermStoreSetParentGroupSetChildRelation","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","" +"PATCH","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}","Sites","Update-MgSiteTermStoreSetParentGroupSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}","Update-MgSiteTermStoreSetParentGroupSetChildRelation" +"POST","/grouplifecyclepolicies","Groups","New-MgGroupLifecyclePolicy","keep","New-MgGroupLifecyclePolicy","/groups/{}/grouplifecyclepolicies","" +"POST","/groups/{}/grouplifecyclepolicies","Groups","New-MgGroupLifecyclePolicy","suppress","","/grouplifecyclepolicies","New-MgGroupLifecyclePolicy" +"POST","/groups/{}/settings","Groups","New-MgGroupSetting","keep","New-MgGroupSetting","/groupsettings","" +"POST","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children","Sites","New-MgGroupSiteTermStoreGroupSetChild","keep","New-MgGroupSiteTermStoreGroupSetChild","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children","" +"POST","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children","Sites","New-MgGroupSiteTermStoreGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children","New-MgGroupSiteTermStoreGroupSetChild" +"POST","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Sites","New-MgGroupSiteTermStoreGroupSetChildRelation","keep","New-MgGroupSiteTermStoreGroupSetChildRelation","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations","" +"POST","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations","Sites","New-MgGroupSiteTermStoreGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","New-MgGroupSiteTermStoreGroupSetChildRelation" +"POST","/groups/{}/sites/{}/termstore/sets/{}/children","Sites","New-MgGroupSiteTermStoreSetChild","keep","New-MgGroupSiteTermStoreSetChild","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children","" +"POST","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children","Sites","New-MgGroupSiteTermStoreSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children","New-MgGroupSiteTermStoreSetChild" +"POST","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Sites","New-MgGroupSiteTermStoreSetChildRelation","keep","New-MgGroupSiteTermStoreSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations","" +"POST","/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations","Sites","New-MgGroupSiteTermStoreSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","New-MgGroupSiteTermStoreSetChildRelation" +"POST","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Sites","New-MgGroupSiteTermStoreSetParentGroupSetChild","keep","New-MgGroupSiteTermStoreSetParentGroupSetChild","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children","" +"POST","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children","Sites","New-MgGroupSiteTermStoreSetParentGroupSetChild","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","New-MgGroupSiteTermStoreSetParentGroupSetChild" +"POST","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Sites","New-MgGroupSiteTermStoreSetParentGroupSetChildRelation","keep","New-MgGroupSiteTermStoreSetParentGroupSetChildRelation","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations","" +"POST","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations","Sites","New-MgGroupSiteTermStoreSetParentGroupSetChildRelation","suppress","","/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","New-MgGroupSiteTermStoreSetParentGroupSetChildRelation" +"POST","/groupsettings","Groups","New-MgGroupSetting","suppress","","/groups/{}/settings","New-MgGroupSetting" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","rename","New-MgEntitlementManagementCatalogResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles","" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","rename","New-MgEntitlementManagementCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes","" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles","New-MgEntitlementManagementCatalogResourceRole" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes","New-MgEntitlementManagementCatalogResourceRoleResourceScope" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes","New-MgEntitlementManagementCatalogResourceScope" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","rename","New-MgEntitlementManagementCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles","" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceScope","rename","New-MgEntitlementManagementCatalogResourceScope","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes","" +"POST","/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles","New-MgEntitlementManagementCatalogResourceScopeResourceRole" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","rename","New-MgEntitlementManagementResourceRequestCatalogResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles","" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","rename","New-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes","" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles","New-MgEntitlementManagementResourceRequestCatalogResourceRole" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceRoleResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes","New-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes","New-MgEntitlementManagementResourceRequestCatalogResourceScope" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","rename","New-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles","" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScope","rename","New-MgEntitlementManagementResourceRequestCatalogResourceScope","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes","" +"POST","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles","Identity.Governance","New-MgIdentityGovernanceEntitlementManagementResourceRequestCatalogResourceScopeResourceRole","suppress","","/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles","New-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" +"POST","/sites/{}/termstore/groups/{}/sets/{}/children","Sites","New-MgSiteTermStoreGroupSetChild","keep","New-MgSiteTermStoreGroupSetChild","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children","" +"POST","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children","Sites","New-MgSiteTermStoreGroupSetChild","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children","New-MgSiteTermStoreGroupSetChild" +"POST","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","Sites","New-MgSiteTermStoreGroupSetChildRelation","keep","New-MgSiteTermStoreGroupSetChildRelation","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations","" +"POST","/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations","Sites","New-MgSiteTermStoreGroupSetChildRelation","suppress","","/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations","New-MgSiteTermStoreGroupSetChildRelation" +"POST","/sites/{}/termstore/sets/{}/children","Sites","New-MgSiteTermStoreSetChild","keep","New-MgSiteTermStoreSetChild","/sites/{}/termstore/sets/{}/children/{}/children","" +"POST","/sites/{}/termstore/sets/{}/children/{}/children","Sites","New-MgSiteTermStoreSetChild","suppress","","/sites/{}/termstore/sets/{}/children","New-MgSiteTermStoreSetChild" +"POST","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","Sites","New-MgSiteTermStoreSetChildRelation","keep","New-MgSiteTermStoreSetChildRelation","/sites/{}/termstore/sets/{}/children/{}/relations","" +"POST","/sites/{}/termstore/sets/{}/children/{}/relations","Sites","New-MgSiteTermStoreSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/children/{}/children/{}/relations","New-MgSiteTermStoreSetChildRelation" +"POST","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","Sites","New-MgSiteTermStoreSetParentGroupSetChild","keep","New-MgSiteTermStoreSetParentGroupSetChild","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children","" +"POST","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children","Sites","New-MgSiteTermStoreSetParentGroupSetChild","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children","New-MgSiteTermStoreSetParentGroupSetChild" +"POST","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","Sites","New-MgSiteTermStoreSetParentGroupSetChildRelation","keep","New-MgSiteTermStoreSetParentGroupSetChildRelation","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations","" +"POST","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations","Sites","New-MgSiteTermStoreSetParentGroupSetChildRelation","suppress","","/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations","New-MgSiteTermStoreSetParentGroupSetChildRelation" diff --git a/tools/WrapperGenerator/data/collision-suppressions.v1.0.json b/tools/WrapperGenerator/data/collision-suppressions.v1.0.json new file mode 100644 index 0000000000..261407ed1b --- /dev/null +++ b/tools/WrapperGenerator/data/collision-suppressions.v1.0.json @@ -0,0 +1,3792 @@ +[ + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Remove-MgGroupSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Remove-MgGroupSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Remove-MgGroupSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Remove-MgGroupSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Remove-MgGroupSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Remove-MgGroupSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Groups" + ], + "method": "DELETE", + "uri": "/groupsettings/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/settings/{}" + ], + "counterpartShipsAs": [ + "Remove-MgGroupSetting" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceRoleResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementCatalogResourceScopeResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "DELETE", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [ + "Remove-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Remove-MgSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Remove-MgSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/sites/{}/termstore/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Remove-MgSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Remove-MgSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Remove-MgSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "DELETE", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Remove-MgSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Calendar" + ], + "method": "GET", + "uri": "/groups/{}/calendarview", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/calendar/calendarview" + ], + "counterpartShipsAs": [ + "Get-MgGroupCalendarView" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/groups/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/groups/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/groups/{}/onenote/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/groups/{}/onenote/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Groups" + ], + "method": "GET", + "uri": "/groups/{}/photos", + "action": "suppress", + "evidence": { + "shipsAs": [ + "Get-MgGroupPhoto" + ], + "counterpartUris": [ + "/groups/{}/photo" + ], + "counterpartShipsAs": [ + "Get-MgGroupPhoto" + ] + }, + "deferredCrossPathMerge": true + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/onenote/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/onenote/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/fromterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/fromterm" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChildRelationFromTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChildRelationSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/toterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/toterm" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChildRelationToTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreGroupSetChildSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/fromterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/fromterm" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChildRelationFromTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChildRelationSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}/toterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/toterm" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChildRelationToTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetChildSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/fromterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/fromterm" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationFromTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/toterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/toterm" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChildRelationToTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgGroupSiteTermStoreSetParentGroupSetChildSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Groups" + ], + "method": "GET", + "uri": "/groupsettings", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/settings" + ], + "counterpartShipsAs": [ + "Get-MgGroupSetting" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Groups" + ], + "method": "GET", + "uri": "/groupsettings/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/settings" + ], + "counterpartShipsAs": [ + "Get-MgGroupSetting" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceRoleResourceScopeResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}", + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes", + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementCatalogResourceScopeResourceRoleResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScopeResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes", + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResource" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "GET", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource/environment", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource/environment" + ], + "counterpartShipsAs": [ + "Get-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRoleResourceEnvironment" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Files" + ], + "method": "GET", + "uri": "/shares/{}/list/items", + "action": "suppress", + "evidence": { + "shipsAs": [ + "Get-MgShareListItem" + ], + "counterpartUris": [ + "/shares/{}/listitem" + ], + "counterpartShipsAs": [ + "Get-MgShareListItem" + ] + }, + "deferredCrossPathMerge": true + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgSiteOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/sites/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgSiteOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/sites/{}/onenote/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgSiteOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/sites/{}/onenote/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgSiteOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/fromterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/fromterm" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChildRelationFromTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChildRelationSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}/toterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}/toterm" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChildRelationToTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreGroupSetChildSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations/{}/fromterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/fromterm" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChildRelationFromTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChildRelationSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations/{}/toterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}/toterm" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChildRelationToTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/children/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetChildSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/fromterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/fromterm" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChildRelationFromTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChildRelationSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}/toterm", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}/toterm" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChildRelationToTerm" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "GET", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/set", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/set" + ], + "counterpartShipsAs": [ + "Get-MgSiteTermStoreSetParentGroupSetChildSet" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Calendar" + ], + "method": "GET", + "uri": "/users/{}/calendars/{}/calendarview", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/users/{}/calendar/calendarview" + ], + "counterpartShipsAs": [ + "Get-MgUserCalendarView" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Calendar" + ], + "method": "GET", + "uri": "/users/{}/calendarview", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/users/{}/calendar/calendarview" + ], + "counterpartShipsAs": [ + "Get-MgUserCalendarView" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/users/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/users/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgUserOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/users/{}/onenote/notebooks/{}/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/users/{}/onenote/notebooks/{}/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgUserOnenoteNotebookSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/users/{}/onenote/sectiongroups/{}/sectiongroups", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/users/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgUserOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Notes" + ], + "method": "GET", + "uri": "/users/{}/onenote/sectiongroups/{}/sectiongroups/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/users/{}/onenote/sectiongroups" + ], + "counterpartShipsAs": [ + "Get-MgUserOnenoteSectionGroup" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Update-MgGroupSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Update-MgGroupSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Update-MgGroupSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Update-MgGroupSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Update-MgGroupSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Update-MgGroupSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Groups" + ], + "method": "PATCH", + "uri": "/groupsettings/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/settings/{}" + ], + "counterpartShipsAs": [ + "Update-MgGroupSetting" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}" + ], + "counterpartShipsAs": [ + "Update-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "PATCH", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles/{}/resource", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles/{}/resource" + ], + "counterpartShipsAs": [] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Update-MgSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Update-MgSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/sites/{}/termstore/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Update-MgSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Update-MgSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}" + ], + "counterpartShipsAs": [ + "Update-MgSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "PATCH", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations/{}", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations/{}" + ], + "counterpartShipsAs": [ + "Update-MgSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Groups" + ], + "method": "POST", + "uri": "/groups/{}/grouplifecyclepolicies", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/grouplifecyclepolicies" + ], + "counterpartShipsAs": [ + "New-MgGroupLifecyclePolicy" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children" + ], + "counterpartShipsAs": [ + "New-MgGroupSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "New-MgGroupSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children" + ], + "counterpartShipsAs": [ + "New-MgGroupSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "New-MgGroupSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children" + ], + "counterpartShipsAs": [ + "New-MgGroupSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "New-MgGroupSiteTermStoreSetParentGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Groups" + ], + "method": "POST", + "uri": "/groupsettings", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/groups/{}/settings" + ], + "counterpartShipsAs": [ + "New-MgGroupSetting" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/roles/{}/resource/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/catalogs/{}/resourcescopes/{}/resource/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/catalogs/{}/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/roles/{}/resource/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourceroles/{}/resource/scopes" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceRoleResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceScope" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Identity.Governance" + ], + "method": "POST", + "uri": "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resourcescopes/{}/resource/roles", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/identitygovernance/entitlementmanagement/resourcerequests/{}/catalog/resources/{}/scopes/{}/resource/roles" + ], + "counterpartShipsAs": [ + "New-MgEntitlementManagementResourceRequestCatalogResourceScopeResourceRole" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children" + ], + "counterpartShipsAs": [ + "New-MgSiteTermStoreGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/sites/{}/termstore/groups/{}/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/groups/{}/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "New-MgSiteTermStoreGroupSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/sites/{}/termstore/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children" + ], + "counterpartShipsAs": [ + "New-MgSiteTermStoreSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/sites/{}/termstore/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "New-MgSiteTermStoreSetChildRelation" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children" + ], + "counterpartShipsAs": [ + "New-MgSiteTermStoreSetParentGroupSetChild" + ] + } + }, + { + "apiVersion": "v1.0", + "modules": [ + "Sites" + ], + "method": "POST", + "uri": "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/relations", + "action": "suppress", + "evidence": { + "shipsAs": [ + null + ], + "counterpartUris": [ + "/sites/{}/termstore/sets/{}/parentgroup/sets/{}/children/{}/children/{}/relations" + ], + "counterpartShipsAs": [ + "New-MgSiteTermStoreSetParentGroupSetChildRelation" + ] + } + } +] diff --git a/tools/WrapperGenerator/edge-cases/crosspath-merge-edge-cases.md b/tools/WrapperGenerator/edge-cases/crosspath-merge-edge-cases.md new file mode 100644 index 0000000000..6d13334f7a --- /dev/null +++ b/tools/WrapperGenerator/edge-cases/crosspath-merge-edge-cases.md @@ -0,0 +1,49 @@ +# Cross-path variant merge edge cases + +This file covers one class of issue: **cross-path variant merges** — cases where the +published SDK serves ONE cmdlet from several unrelated request URIs, as AutoRest parameter-set +variants. The wrapper generator emits one cmdlet per route (plus the list/item dispatcher), so +it cannot express these yet; the resolution policy is deterministic deferral. The derivation +sweep of every v1.0 collision route (`tools/Derive-CollisionResolutions.ps1`, ledger in +`artifacts/collision-resolution-ledger.v1.0.csv`) found exactly two. + +**Policy:** among same-command routes, the shallowest list/item pair survives (fewest path +parameters; tie broken by shortest, then ordinal — fully deterministic); the other routes are +suppressed with `deferredCrossPathMerge: true` in `data/collision-suppressions.v1.0.json`. +They come back when cross-path parameter sets are implemented (tracked with the operation +shapes / parameter-set work). + +## Group photo: `/photo` vs `/photos` + +- **Class:** crosspath-merge +- **Status:** workaround (singleton kept, collection deferred) +- **Evidence:** oracle ships `Get-MgGroupPhoto` for both `GET /groups/{id}/photo` and + `GET /groups/{id}/photos`; `/photos/{id}` ships nothing. Mirrors the `/users/{id}/photo(s)` + pair already curated in `NamingOverrides.cs`. +- **Decision:** generate from the `/photo` singleton (the primary published variant); defer + `/photos` (the all-sizes collection) until parameter sets can put both URIs behind one + cmdlet. +- **Migration impact:** `Get-MgGroupPhoto` exists with identical name; listing all photo + sizes via `-All`-style enumeration is not available until the deferral lifts. +- **References:** `data/collision-suppressions.v1.0.json` (`GET /groups/{}/photos`), + DerivedCollisionResolutionsTests. + +## Shared list items: `/listItem` vs `/list/items` + +- **Class:** crosspath-merge +- **Status:** workaround (singleton kept, collection deferred) +- **Evidence:** oracle ships `Get-MgShareListItem` for both `GET /shares/{id}/listItem` and + `GET /shares/{id}/list/items`; the bare `/list/items/{id}` item GET ships nothing (curated + suppression, `NamingOverrides.cs`). +- **Decision:** generate from the `/listItem` singleton; defer the `/list/items` collection. +- **Migration impact:** `Get-MgShareListItem` exists with identical name; enumerating a + shared list's items through this cmdlet is not available until the deferral lifts. +- **References:** `data/collision-suppressions.v1.0.json` (`GET /shares/{}/list/items`), + DerivedCollisionResolutionsTests. + +## Status summary + +| Case | Class | Status | +|---|---|---| +| `/groups/{id}/photo` vs `/photos` | crosspath-merge | workaround | +| `/shares/{id}/listItem` vs `/list/items` | crosspath-merge | workaround | From 5608540b483c468975548e83120748c53576af63 Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Thu, 13 Aug 2026 21:20:54 -0700 Subject: [PATCH 09/11] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tools/Build-WrapperModule.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Build-WrapperModule.ps1 b/tools/Build-WrapperModule.ps1 index 7630a2563e..52a42169f6 100644 --- a/tools/Build-WrapperModule.ps1 +++ b/tools/Build-WrapperModule.ps1 @@ -148,7 +148,7 @@ function Build-OneModule { $result.FailedAt = 'wrapper-generator' $lines = @($wrapperOut | ForEach-Object { "$_" }) $exception = $lines | Where-Object { $_ -match 'Unhandled exception|Exception:' } | Select-Object -First 1 - $exceptionIndex = if ($exception) { $lines.IndexOf($exception) } else { -1 } + $exceptionIndex = if ($exception) { [Array]::IndexOf($lines, $exception) } else { -1 } $result.Error = if ($exceptionIndex -ge 0) { ($lines[$exceptionIndex..([Math]::Min($exceptionIndex + 5, $lines.Count - 1))] | Where-Object { $_ -notmatch '^\s+at ' }) -join ' | ' } else { From b7bf79a2b246a8007edbf6ae51fa587e42e33f38 Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Thu, 13 Aug 2026 21:21:09 -0700 Subject: [PATCH 10/11] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../WrapperGenerator/PowerShellWrapperGenerationService.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs index 82974e0db3..5c1b6a8e1a 100644 --- a/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs +++ b/tools/WrapperGenerator/PowerShellWrapperGenerationService.cs @@ -315,7 +315,12 @@ private async Task EmitGetOperationsAsync(List getOpera private async Task WriteCmdletFileAsync(CmdletNaming naming, string source, CancellationToken cancellationToken) { - var fileName = naming.ClassName.Replace("Command", "", StringComparison.Ordinal) + ".g.cs"; + const string cmdletClassSuffix = "Command"; + var className = naming.ClassName; + var fileBaseName = className.EndsWith(cmdletClassSuffix, StringComparison.Ordinal) + ? className[..^cmdletClassSuffix.Length] + : className; + var fileName = fileBaseName + ".g.cs"; // Both colliding cmdlets usually share the same name, so the builder expression (the // request path) is what actually identifies which two operations collided. var cmdletName = $"{naming.VerbName}-{naming.Noun} [{naming.BuilderExpression}]"; From dec945a585660c539386684de69ff4880b7aeeb7 Mon Sep 17 00:00:00 2001 From: Joywambui-maina Date: Fri, 14 Aug 2026 00:41:45 -0700 Subject: [PATCH 11/11] fix(wrapper-generator): align wrapper packaging projects --- tools/Build-WrapperModule.ps1 | 109 ++++++++++-------- tools/Templates/WrapperClient.csproj.template | 17 +++ tools/Templates/WrapperModule.csproj.template | 29 +++++ 3 files changed, 108 insertions(+), 47 deletions(-) create mode 100644 tools/Templates/WrapperClient.csproj.template create mode 100644 tools/Templates/WrapperModule.csproj.template diff --git a/tools/Build-WrapperModule.ps1 b/tools/Build-WrapperModule.ps1 index 52a42169f6..cab8c6a189 100644 --- a/tools/Build-WrapperModule.ps1 +++ b/tools/Build-WrapperModule.ps1 @@ -8,9 +8,10 @@ For each module name, reproduces the pipeline the Mail spike proved: 1. kiota generate -> //src/Client (ApiClient + models) 2. WrapperGenerator -> //src/Cmdlets (one *.g.cs per cmdlet) - 3. write csproj -> //src/ - 4. dotnet build -> //src/bin//net10.0/ - 5. New-ModuleManifest -> .psd1 next to the dll + 3. write client project -> //src/Client/Client.csproj + 4. write wrapper project -> //src/.csproj + 5. dotnet build -> //src/bin//net10.0/ + 6. New-ModuleManifest -> .psd1 next to the dll Both generators consume the SAME OpenAPI document, so the wrappers always match the client they compile against. @@ -76,26 +77,55 @@ if (-not $SpecRoot) { $SpecRoot = Join-Path $repoRoot 'openApiDocs_KiotaCompat' if (-not $OutputRoot) { $OutputRoot = Join-Path $repoRoot 'artifacts\wrapper-modules' } $generatorProject = Join-Path $repoRoot 'tools\WrapperGenerator' $authCsproj = Join-Path $repoRoot 'src\Authentication\Authentication\Microsoft.Graph.Authentication.csproj' +$clientProjectTemplate = Join-Path $PSScriptRoot 'Templates\WrapperClient.csproj.template' +$moduleProjectTemplate = Join-Path $PSScriptRoot 'Templates\WrapperModule.csproj.template' if (-not (Get-Command kiota -ErrorAction SilentlyContinue)) { Write-Error "kiota CLI not found on PATH. Install: dotnet tool install --global Microsoft.OpenApi.Kiota" exit 1 } -# Same extraction the parity gate uses: the emitted [Cmdlet(VerbsX.Verb, "Noun")] attribute -# is the source of truth for what the dll will export, without having to load the assembly. -$cmdletAttrPattern = '\[Cmdlet\(Verbs\w+\.(\w+),\s*"((?:\\.|[^"\\])*)"' -function Get-EmittedCmdletNames { - param([string]$CmdletsDir) - Get-ChildItem -Path $CmdletsDir -Filter '*.g.cs' -File | ForEach-Object { - $match = [regex]::Match((Get-Content -Path $_.FullName -Raw), $cmdletAttrPattern) - if ($match.Success) { - "$($match.Groups[1].Value)-$([regex]::Unescape($match.Groups[2].Value))" - } +function New-ProjectFromTemplate { + param( + [Parameter(Mandatory)][string]$TemplatePath, + [Parameter(Mandatory)][string]$DestinationPath, + [Parameter(Mandatory)][hashtable]$Replacements + ) + + $content = Get-Content -Path $TemplatePath -Raw + foreach ($placeholder in $Replacements.Keys) { + $content = $content.Replace("{$placeholder}", $Replacements[$placeholder]) + } + $unresolved = [regex]::Matches($content, '\{[A-Za-z][A-Za-z0-9]*\}') | ForEach-Object Value | Sort-Object -Unique + if ($unresolved) { + throw "unresolved placeholder(s) in $TemplatePath`: $($unresolved -join ', ')" + } + Set-Content -Path $DestinationPath -Value $content -Encoding utf8 +} + +function Get-CompiledCmdletNames { + param([Parameter(Mandatory)][string]$AssemblyPath) + + # Import in a child process so discovery observes the compiled binary PowerShell will load, + # and so assemblies from one module cannot contaminate or lock the next module's build. + $escapedAssemblyPath = $AssemblyPath.Replace("'", "''") + $discovery = @" +`$ErrorActionPreference = 'Stop' +`$module = Import-Module -Name '$escapedAssemblyPath' -PassThru +[pscustomobject]@{ Cmdlets = @(`$module.ExportedCmdlets.Keys | Sort-Object) } | + ConvertTo-Json -Compress +"@ + $encodedDiscovery = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($discovery)) + $output = & pwsh -NoProfile -NonInteractive -EncodedCommand $encodedDiscovery 2>&1 + if ($LASTEXITCODE -ne 0) { + throw "compiled module discovery failed: $(($output | Select-Object -Last 3) -join ' | ')" } + $json = $output | Where-Object { $_ -match '^\{' } | Select-Object -Last 1 + if (-not $json) { throw 'compiled module discovery produced no result' } + @((ConvertFrom-Json $json).Cmdlets) } -function Build-OneModule { +function Build-Module { param([string]$Name) $started = Get-Date @@ -157,38 +187,22 @@ function Build-OneModule { return $result } - # Relative to $srcDir rather than the absolute $authCsproj, so the csproj is portable - # across clones and stays correct if a module's output folder ever moves (the eventual - # src/// commit target sits at a different depth than - # artifacts/wrapper-modules//src/). + $clientAssemblyName = "$moduleName.Client" + $clientCsprojPath = Join-Path $clientDir 'Client.csproj' + New-ProjectFromTemplate -TemplatePath $clientProjectTemplate -DestinationPath $clientCsprojPath -Replacements @{ + ClientAssemblyName = $clientAssemblyName + } + + # Project references are relative so generated projects remain portable across clones + # and across the artifacts and eventual src///wrapper layouts. $csprojPath = Join-Path $srcDir "$moduleName.csproj" $authCsprojRelative = [System.IO.Path]::GetRelativePath($srcDir, $authCsproj) -replace '/', '\' - @" - - - - - net10.0 - latest - enable - enable - $moduleName - - true - `$(NoWarn);CS1591 - - - - - - - - - - - - -"@ | Set-Content -Path $csprojPath -Encoding utf8 + $clientCsprojRelative = [System.IO.Path]::GetRelativePath($srcDir, $clientCsprojPath) -replace '/', '\' + New-ProjectFromTemplate -TemplatePath $moduleProjectTemplate -DestinationPath $csprojPath -Replacements @{ + ModuleAssemblyName = $moduleName + ClientProjectPath = $clientCsprojRelative + AuthenticationProjectPath = $authCsprojRelative + } $buildOut = & dotnet build $csprojPath -c $Configuration --nologo -v minimal 2>&1 if ($LASTEXITCODE -ne 0) { @@ -197,10 +211,11 @@ function Build-OneModule { return $result } - $cmdlets = @(Get-EmittedCmdletNames -CmdletsDir $cmdletsDir) + $binDir = Join-Path $srcDir "bin\$Configuration\net10.0" + $assemblyPath = Join-Path $binDir "$moduleName.dll" + $cmdlets = @(Get-CompiledCmdletNames -AssemblyPath $assemblyPath) if ($cmdlets.Count -eq 0) { $result.FailedAt = 'manifest'; $result.Error = 'no cmdlets emitted'; return $result } - $binDir = Join-Path $srcDir "bin\$Configuration\net10.0" $psd1Path = Join-Path $binDir "$moduleName.psd1" New-ModuleManifest -Path $psd1Path ` -RootModule "$moduleName.dll" ` @@ -227,7 +242,7 @@ function Build-OneModule { $results = foreach ($name in $Module) { Write-Host "=== $name ===" -ForegroundColor Cyan - $r = Build-OneModule -Name $name + $r = Build-Module -Name $name if ($r.Status -eq 'OK') { Write-Host " OK: $($r.CmdletCount) cmdlets -> $($r.Psd1) ($($r.Seconds)s)" -ForegroundColor Green } diff --git a/tools/Templates/WrapperClient.csproj.template b/tools/Templates/WrapperClient.csproj.template new file mode 100644 index 0000000000..def417080f --- /dev/null +++ b/tools/Templates/WrapperClient.csproj.template @@ -0,0 +1,17 @@ + + + + + net10.0 + latest + enable + enable + {ClientAssemblyName} + $(NoWarn);CS1591 + + + + + + + \ No newline at end of file diff --git a/tools/Templates/WrapperModule.csproj.template b/tools/Templates/WrapperModule.csproj.template new file mode 100644 index 0000000000..aad5320630 --- /dev/null +++ b/tools/Templates/WrapperModule.csproj.template @@ -0,0 +1,29 @@ + + + + + net10.0 + latest + enable + enable + false + {ModuleAssemblyName} + + true + $(NoWarn);CS1591 + + + + + + + + + + + + + + + + \ No newline at end of file