From ad22989bf806f3f3621ae20123dee441fda1569f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 07:20:28 +0000 Subject: [PATCH 1/6] Initial plan From 73cb73868d79fd9d8fc7e6c08d45aae8143964e6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 18:11:58 +0000 Subject: [PATCH 2/6] Add URL generation cmdlets and tests Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com> --- .../GetDataverseAdminPortalUrlCmdlet.cs | 83 +++++++++ .../GetDataverseMakerPortalUrlCmdlet.cs | 82 ++++++++ .../Commands/GetDataverseRecordUrlCmdlet.cs | 100 ++++++++++ .../docs/Get-DataverseAdminPortalUrl.md | 131 +++++++++++++ .../docs/Get-DataverseMakerPortalUrl.md | 126 +++++++++++++ .../docs/Get-DataverseRecordUrl.md | 175 ++++++++++++++++++ tests/Get-DataverseAdminPortalUrl.Tests.ps1 | 116 ++++++++++++ tests/Get-DataverseMakerPortalUrl.Tests.ps1 | 125 +++++++++++++ tests/Get-DataverseRecordUrl.Tests.ps1 | 107 +++++++++++ 9 files changed, 1045 insertions(+) create mode 100644 Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs create mode 100644 Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs create mode 100644 Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs create mode 100644 Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md create mode 100644 Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md create mode 100644 Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md create mode 100644 tests/Get-DataverseAdminPortalUrl.Tests.ps1 create mode 100644 tests/Get-DataverseMakerPortalUrl.Tests.ps1 create mode 100644 tests/Get-DataverseRecordUrl.Tests.ps1 diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs new file mode 100644 index 000000000..49f31867a --- /dev/null +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs @@ -0,0 +1,83 @@ +using System; +using System.Management.Automation; +using Microsoft.PowerPlatform.Dataverse.Client; +using Microsoft.Crm.Sdk.Messages; + +namespace Rnwood.Dataverse.Data.PowerShell.Commands +{ + /// + /// Generates a URL to open the Power Platform Admin Center for the current environment. + /// + [Cmdlet(VerbsCommon.Get, "DataverseAdminPortalUrl")] + [OutputType(typeof(string))] + public class GetDataverseAdminPortalUrlCmdlet : OrganizationServiceCmdlet + { + /// + /// Gets or sets the specific page to navigate to in the admin portal. + /// + [Parameter(Mandatory = false, HelpMessage = "Specific page to navigate to in the admin portal (e.g., 'environments', 'analytics', 'resources').")] + [ValidateSet("home", "environments", "analytics", "resources", "dataintegration", "datapolicies", "helpandsupport")] + public string Page { get; set; } = "environments"; + + /// + /// Processes the cmdlet to generate the admin portal URL. + /// + protected override void ProcessRecord() + { + base.ProcessRecord(); + + if (Connection == null) + { + ThrowTerminatingError(new ErrorRecord( + new InvalidOperationException("No connection provided. Use -Connection parameter or set a default connection."), + "NoConnection", + ErrorCategory.InvalidOperation, + null)); + return; + } + + // Get the environment ID from the organization + WhoAmIRequest whoAmIRequest = new WhoAmIRequest(); + WhoAmIResponse whoAmIResponse = (WhoAmIResponse)Connection.Execute(whoAmIRequest); + Guid orgId = whoAmIResponse.OrganizationId; + + // Build the admin portal URL + string baseUrl = "https://admin.powerplatform.microsoft.com"; + + // For environments page, include the specific environment + if (Page.ToLowerInvariant() == "environments") + { + string url = $"{baseUrl}/environments/{orgId:D}/hub"; + WriteObject(url); + } + else + { + // For other pages, navigate to the general section + string url = baseUrl; + switch (Page.ToLowerInvariant()) + { + case "analytics": + url += "/analytics"; + break; + case "resources": + url += "/resources"; + break; + case "dataintegration": + url += "/dataintegration"; + break; + case "datapolicies": + url += "/datapolicies"; + break; + case "helpandsupport": + url += "/support"; + break; + case "home": + default: + url += "/home"; + break; + } + WriteObject(url); + } + } + } +} diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs new file mode 100644 index 000000000..ebf138308 --- /dev/null +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs @@ -0,0 +1,82 @@ +using System; +using System.Management.Automation; +using Microsoft.PowerPlatform.Dataverse.Client; +using Microsoft.Crm.Sdk.Messages; + +namespace Rnwood.Dataverse.Data.PowerShell.Commands +{ + /// + /// Generates a URL to open the Power Apps Maker Portal for the current environment. + /// + [Cmdlet(VerbsCommon.Get, "DataverseMakerPortalUrl")] + [OutputType(typeof(string))] + public class GetDataverseMakerPortalUrlCmdlet : OrganizationServiceCmdlet + { + /// + /// Gets or sets the specific page to navigate to in the maker portal. + /// + [Parameter(Mandatory = false, HelpMessage = "Specific page to navigate to in the maker portal (e.g., 'solutions', 'tables', 'apps').")] + [ValidateSet("home", "solutions", "tables", "apps", "flows", "chatbots", "connections", "dataflows", "entities")] + public string Page { get; set; } = "home"; + + /// + /// Processes the cmdlet to generate the maker portal URL. + /// + protected override void ProcessRecord() + { + base.ProcessRecord(); + + if (Connection == null) + { + ThrowTerminatingError(new ErrorRecord( + new InvalidOperationException("No connection provided. Use -Connection parameter or set a default connection."), + "NoConnection", + ErrorCategory.InvalidOperation, + null)); + return; + } + + // Get the environment ID from the organization + WhoAmIRequest whoAmIRequest = new WhoAmIRequest(); + WhoAmIResponse whoAmIResponse = (WhoAmIResponse)Connection.Execute(whoAmIRequest); + Guid orgId = whoAmIResponse.OrganizationId; + + // Build the maker portal URL + string baseUrl = "https://make.powerapps.com"; + string url = $"{baseUrl}/environments/{orgId:D}"; + + // Add page-specific path + switch (Page.ToLowerInvariant()) + { + case "solutions": + url += "/solutions"; + break; + case "tables": + case "entities": + url += "/entities"; + break; + case "apps": + url += "/apps"; + break; + case "flows": + url += "/flows"; + break; + case "chatbots": + url += "/chatbots"; + break; + case "connections": + url += "/connections"; + break; + case "dataflows": + url += "/dataflows"; + break; + case "home": + default: + url += "/home"; + break; + } + + WriteObject(url); + } + } +} diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs new file mode 100644 index 000000000..4b3684fd8 --- /dev/null +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs @@ -0,0 +1,100 @@ +using System; +using System.Management.Automation; +using Microsoft.PowerPlatform.Dataverse.Client; +using Microsoft.Xrm.Sdk; + +namespace Rnwood.Dataverse.Data.PowerShell.Commands +{ + /// + /// Generates a URL to open a record in the Dataverse web interface. + /// + [Cmdlet(VerbsCommon.Get, "DataverseRecordUrl")] + [OutputType(typeof(string))] + public class GetDataverseRecordUrlCmdlet : OrganizationServiceCmdlet + { + /// + /// Gets or sets the logical name of the table (entity). + /// + [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true, HelpMessage = "Logical name of the table (e.g., 'account', 'contact').")] + [Alias("EntityName", "LogicalName")] + public string TableName { get; set; } + + /// + /// Gets or sets the ID of the record. If not provided, generates a URL for creating a new record. + /// + [Parameter(Mandatory = false, Position = 1, ValueFromPipelineByPropertyName = true, HelpMessage = "ID of the record. If not provided, generates a URL for creating a new record.")] + [Alias("RecordId")] + public Guid? Id { get; set; } + + /// + /// Gets or sets the app ID to open the record in a specific app. + /// + [Parameter(Mandatory = false, HelpMessage = "App ID to open the record in a specific model-driven app.")] + public Guid? AppId { get; set; } + + /// + /// Gets or sets the form ID to open a specific form. + /// + [Parameter(Mandatory = false, HelpMessage = "Form ID to open a specific form for the record.")] + public Guid? FormId { get; set; } + + /// + /// Processes the cmdlet to generate the record URL. + /// + protected override void ProcessRecord() + { + base.ProcessRecord(); + + if (Connection == null) + { + ThrowTerminatingError(new ErrorRecord( + new InvalidOperationException("No connection provided. Use -Connection parameter or set a default connection."), + "NoConnection", + ErrorCategory.InvalidOperation, + null)); + return; + } + + // Extract the base URL from the connection + string baseUrl = Connection.ConnectedOrgUriActual?.ToString(); + if (string.IsNullOrEmpty(baseUrl)) + { + ThrowTerminatingError(new ErrorRecord( + new InvalidOperationException("Unable to determine organization URL from connection."), + "InvalidConnection", + ErrorCategory.InvalidOperation, + null)); + return; + } + + // Remove trailing slash + baseUrl = baseUrl.TrimEnd('/'); + + // Build the URL + string url; + if (Id.HasValue) + { + // URL for existing record + url = $"{baseUrl}/main.aspx?etn={TableName}&id={Id.Value:D}&pagetype=entityrecord"; + } + else + { + // URL for creating new record + url = $"{baseUrl}/main.aspx?etn={TableName}&pagetype=entityrecord"; + } + + // Add optional parameters + if (AppId.HasValue) + { + url += $"&appid={AppId.Value:D}"; + } + + if (FormId.HasValue) + { + url += $"&formid={FormId.Value:D}"; + } + + WriteObject(url); + } + } +} diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md new file mode 100644 index 000000000..2dd3cc011 --- /dev/null +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md @@ -0,0 +1,131 @@ +--- +external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml +Module Name: Rnwood.Dataverse.Data.PowerShell +online version: +schema: 2.0.0 +--- + +# Get-DataverseAdminPortalUrl + +## SYNOPSIS +Generates a URL to open the Power Platform Admin Center for the current environment. + +## SYNTAX + +``` +Get-DataverseAdminPortalUrl [-Page ] [-Connection ] + [-ProgressAction ] [] +``` + +## DESCRIPTION + +This cmdlet generates a URL that opens the Power Platform Admin Center for the Dataverse environment associated with the current connection. + +The Admin Center is where administrators can: +- Manage environments +- View analytics and reports +- Configure data integration +- Manage resources and capacity +- Set up data policies +- Access help and support + +You can optionally specify which section of the Admin Center to navigate to directly. + +## EXAMPLES + +### Example 1: Get URL for specific environment in Admin Center +```powershell +PS C:\> Get-DataverseAdminPortalUrl -Connection $c +``` + +Returns a URL to open the Admin Center for the connected environment (defaults to environments page). + +### Example 2: Get URL for analytics page +```powershell +PS C:\> Get-DataverseAdminPortalUrl -Connection $c -Page "analytics" +``` + +Returns a URL to open the Analytics page in the Admin Center. + +### Example 3: Get URL for data policies page +```powershell +PS C:\> Get-DataverseAdminPortalUrl -Connection $c -Page "datapolicies" +``` + +Returns a URL to open the Data Policies page in the Admin Center. + +### Example 4: Open Admin Center directly in browser +```powershell +PS C:\> Start-Process (Get-DataverseAdminPortalUrl -Connection $c -Page "resources") +``` + +Opens the Resources page of the Admin Center directly in the default web browser. + +## PARAMETERS + +### -Page +Specific page to navigate to in the admin portal. Valid values are: home, environments, analytics, resources, dataintegration, datapolicies, helpandsupport. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: environments +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Connection +DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. + +```yaml +Type: ServiceClient +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### System.String + +## NOTES + +The Admin Center URL format varies by page: +- For environments: https://admin.powerplatform.microsoft.com/environments/{environmentId}/hub +- For other pages: https://admin.powerplatform.microsoft.com/{page} + +Administrative permissions may be required to access certain sections of the Admin Center. + +## RELATED LINKS +[Power Platform Admin Center](https://admin.powerplatform.microsoft.com) diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md new file mode 100644 index 000000000..5eed63450 --- /dev/null +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md @@ -0,0 +1,126 @@ +--- +external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml +Module Name: Rnwood.Dataverse.Data.PowerShell +online version: +schema: 2.0.0 +--- + +# Get-DataverseMakerPortalUrl + +## SYNOPSIS +Generates a URL to open the Power Apps Maker Portal for the current environment. + +## SYNTAX + +``` +Get-DataverseMakerPortalUrl [-Page ] [-Connection ] + [-ProgressAction ] [] +``` + +## DESCRIPTION + +This cmdlet generates a URL that opens the Power Apps Maker Portal for the Dataverse environment associated with the current connection. + +The Maker Portal is where you can: +- Build and configure Power Apps +- Manage solutions +- View and manage tables (entities) +- Create and manage flows +- Work with connections and data sources + +You can optionally specify which page of the Maker Portal to navigate to directly. + +## EXAMPLES + +### Example 1: Get URL for Maker Portal home page +```powershell +PS C:\> Get-DataverseMakerPortalUrl -Connection $c +``` + +Returns a URL to open the Maker Portal home page for the connected environment. + +### Example 2: Get URL for solutions page +```powershell +PS C:\> Get-DataverseMakerPortalUrl -Connection $c -Page "solutions" +``` + +Returns a URL to open the Solutions page in the Maker Portal. + +### Example 3: Get URL for tables page +```powershell +PS C:\> Get-DataverseMakerPortalUrl -Connection $c -Page "tables" +``` + +Returns a URL to open the Tables page in the Maker Portal. + +### Example 4: Open Maker Portal directly in browser +```powershell +PS C:\> Start-Process (Get-DataverseMakerPortalUrl -Connection $c -Page "apps") +``` + +Opens the Apps page of the Maker Portal directly in the default web browser. + +## PARAMETERS + +### -Page +Specific page to navigate to in the maker portal. Valid values are: home, solutions, tables, apps, flows, chatbots, connections, dataflows, entities. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: home +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Connection +DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. + +```yaml +Type: ServiceClient +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +## OUTPUTS + +### System.String + +## NOTES + +The Maker Portal URL is always in the format: https://make.powerapps.com/environments/{environmentId}/{page} + +## RELATED LINKS +[Power Apps Maker Portal](https://make.powerapps.com) diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md new file mode 100644 index 000000000..a195c4bd4 --- /dev/null +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md @@ -0,0 +1,175 @@ +--- +external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml +Module Name: Rnwood.Dataverse.Data.PowerShell +online version: +schema: 2.0.0 +--- + +# Get-DataverseRecordUrl + +## SYNOPSIS +Generates a URL to open a record in the Dataverse web interface. + +## SYNTAX + +``` +Get-DataverseRecordUrl [-TableName] [[-Id] ] [-AppId ] [-FormId ] + [-Connection ] [-ProgressAction ] [] +``` + +## DESCRIPTION + +This cmdlet generates a URL that can be used to open a record in the Dataverse web interface. If an ID is provided, the URL will open that specific record. If no ID is provided, the URL will open a form to create a new record. + +The generated URL can be: +- Opened directly in a web browser +- Shared with users via email or other communication +- Embedded in custom applications or workflows +- Used for deep-linking into specific records or forms + +The cmdlet can optionally include parameters to open the record in a specific app or with a specific form. + +## EXAMPLES + +### Example 1: Get URL for a specific record +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" +``` + +Returns a URL to open the contact record with the specified ID. + +### Example 2: Get URL to create a new record +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" +``` + +Returns a URL to open a form for creating a new account record. + +### Example 3: Get URL for a record in a specific app +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -AppId "87654321-4321-4321-4321-210987654321" +``` + +Returns a URL to open the contact record in the specified model-driven app. + +### Example 4: Get URL with a specific form +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" -FormId "abcdefgh-abcd-abcd-abcd-abcdefghijkl" +``` + +Returns a URL to create a new account using the specified form. + +### Example 5: Generate URLs from pipeline +```powershell +PS C:\> Get-DataverseRecord -Connection $c -TableName "contact" | Get-DataverseRecordUrl -Connection $c -TableName "contact" +``` + +Generates URLs for all contact records returned by Get-DataverseRecord. + +## PARAMETERS + +### -TableName +The logical name of the table (e.g., 'account', 'contact'). + +```yaml +Type: String +Parameter Sets: (All) +Aliases: EntityName, LogicalName + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Id +The ID of the record. If not provided, generates a URL for creating a new record. + +```yaml +Type: Guid +Parameter Sets: (All) +Aliases: RecordId + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -AppId +The App ID to open the record in a specific model-driven app. + +```yaml +Type: Guid +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -FormId +The Form ID to open a specific form for the record. + +```yaml +Type: Guid +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Connection +DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. + +```yaml +Type: ServiceClient +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String +### System.Guid + +## OUTPUTS + +### System.String + +## NOTES + +## RELATED LINKS diff --git a/tests/Get-DataverseAdminPortalUrl.Tests.ps1 b/tests/Get-DataverseAdminPortalUrl.Tests.ps1 new file mode 100644 index 000000000..4ff6b487f --- /dev/null +++ b/tests/Get-DataverseAdminPortalUrl.Tests.ps1 @@ -0,0 +1,116 @@ +. $PSScriptRoot/Common.ps1 + +Describe 'Get-DataverseAdminPortalUrl' { + Context 'Admin Portal URL Generation' { + It "Generates URL for environment page by default" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection + + # Verify URL structure + $url | Should -Not -BeNullOrEmpty + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/environments/*" + $url | Should -BeLike "*/hub" + } + + It "Generates URL for analytics page" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "analytics" + + # Verify URL points to analytics + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/analytics" + } + + It "Generates URL for resources page" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "resources" + + # Verify URL points to resources + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/resources" + } + + It "Generates URL for data integration page" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "dataintegration" + + # Verify URL points to data integration + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/dataintegration" + } + + It "Generates URL for data policies page" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "datapolicies" + + # Verify URL points to data policies + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/datapolicies" + } + + It "Generates URL for help and support page" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "helpandsupport" + + # Verify URL points to support + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/support" + } + + It "Generates URL for home page" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "home" + + # Verify URL points to home + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/home" + } + + It "Includes environment ID for environments page" { + $connection = getMockConnection + + # Get the organization ID (which is the environment ID) + $whoami = Get-DataverseWhoAmI -Connection $connection + $envId = $whoami.OrganizationId + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "environments" + + # Verify URL includes the environment ID + $url | Should -BeLike "*/environments/$envId/hub" + } + + It "Does not include environment ID for non-environment pages" { + $connection = getMockConnection + + $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "analytics" + + # Verify URL does not include /environments/ path + $url | Should -Not -BeLike "*/environments/*" + } + + It "Works with default connection" { + $connection = getMockConnection + Set-DataverseConnectionAsDefault -Connection $connection + + # Call without explicit connection + $url = Get-DataverseAdminPortalUrl + + # Verify URL generated + $url | Should -Not -BeNullOrEmpty + $url | Should -BeLike "https://admin.powerplatform.microsoft.com/*" + } + + It "Handles case-insensitive page parameter" { + $connection = getMockConnection + + $url1 = Get-DataverseAdminPortalUrl -Connection $connection -Page "Analytics" + $url2 = Get-DataverseAdminPortalUrl -Connection $connection -Page "ANALYTICS" + $url3 = Get-DataverseAdminPortalUrl -Connection $connection -Page "analytics" + + # All should produce the same URL + $url1 | Should -Be $url2 + $url2 | Should -Be $url3 + } + } +} diff --git a/tests/Get-DataverseMakerPortalUrl.Tests.ps1 b/tests/Get-DataverseMakerPortalUrl.Tests.ps1 new file mode 100644 index 000000000..6fb38865b --- /dev/null +++ b/tests/Get-DataverseMakerPortalUrl.Tests.ps1 @@ -0,0 +1,125 @@ +. $PSScriptRoot/Common.ps1 + +Describe 'Get-DataverseMakerPortalUrl' { + Context 'Maker Portal URL Generation' { + It "Generates URL for maker portal home page by default" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection + + # Verify URL structure + $url | Should -Not -BeNullOrEmpty + $url | Should -BeLike "https://make.powerapps.com/environments/*" + $url | Should -BeLike "*/home" + } + + It "Generates URL for solutions page" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "solutions" + + # Verify URL points to solutions + $url | Should -BeLike "*/solutions" + } + + It "Generates URL for tables page" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "tables" + + # Verify URL points to entities (tables) + $url | Should -BeLike "*/entities" + } + + It "Generates URL for entities page (alias for tables)" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "entities" + + # Verify URL points to entities + $url | Should -BeLike "*/entities" + } + + It "Generates URL for apps page" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "apps" + + # Verify URL points to apps + $url | Should -BeLike "*/apps" + } + + It "Generates URL for flows page" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "flows" + + # Verify URL points to flows + $url | Should -BeLike "*/flows" + } + + It "Generates URL for chatbots page" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "chatbots" + + # Verify URL points to chatbots + $url | Should -BeLike "*/chatbots" + } + + It "Generates URL for connections page" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "connections" + + # Verify URL points to connections + $url | Should -BeLike "*/connections" + } + + It "Generates URL for dataflows page" { + $connection = getMockConnection + + $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "dataflows" + + # Verify URL points to dataflows + $url | Should -BeLike "*/dataflows" + } + + It "Includes environment ID from connection" { + $connection = getMockConnection + + # Get the organization ID (which is the environment ID) + $whoami = Get-DataverseWhoAmI -Connection $connection + $envId = $whoami.OrganizationId + + $url = Get-DataverseMakerPortalUrl -Connection $connection + + # Verify URL includes the environment ID + $url | Should -BeLike "*/environments/$envId/*" + } + + It "Works with default connection" { + $connection = getMockConnection + Set-DataverseConnectionAsDefault -Connection $connection + + # Call without explicit connection + $url = Get-DataverseMakerPortalUrl + + # Verify URL generated + $url | Should -Not -BeNullOrEmpty + $url | Should -BeLike "https://make.powerapps.com/*" + } + + It "Handles case-insensitive page parameter" { + $connection = getMockConnection + + $url1 = Get-DataverseMakerPortalUrl -Connection $connection -Page "Solutions" + $url2 = Get-DataverseMakerPortalUrl -Connection $connection -Page "SOLUTIONS" + $url3 = Get-DataverseMakerPortalUrl -Connection $connection -Page "solutions" + + # All should produce the same URL + $url1 | Should -Be $url2 + $url2 | Should -Be $url3 + } + } +} diff --git a/tests/Get-DataverseRecordUrl.Tests.ps1 b/tests/Get-DataverseRecordUrl.Tests.ps1 new file mode 100644 index 000000000..57e789820 --- /dev/null +++ b/tests/Get-DataverseRecordUrl.Tests.ps1 @@ -0,0 +1,107 @@ +. $PSScriptRoot/Common.ps1 + +Describe 'Get-DataverseRecordUrl' { + Context 'URL Generation for Records' { + It "Generates URL for existing record with ID" { + $connection = getMockConnection + + # Generate URL for a specific contact record + $recordId = [Guid]::NewGuid() + $url = Get-DataverseRecordUrl -Connection $connection -TableName "contact" -Id $recordId + + # Verify URL structure + $url | Should -Not -BeNullOrEmpty + $url | Should -BeLike "*main.aspx*" + $url | Should -BeLike "*etn=contact*" + $url | Should -BeLike "*id=$recordId*" + $url | Should -BeLike "*pagetype=entityrecord*" + } + + It "Generates URL for creating new record without ID" { + $connection = getMockConnection + + # Generate URL for creating a new account record + $url = Get-DataverseRecordUrl -Connection $connection -TableName "account" + + # Verify URL structure (no ID parameter) + $url | Should -Not -BeNullOrEmpty + $url | Should -BeLike "*main.aspx*" + $url | Should -BeLike "*etn=account*" + $url | Should -Not -BeLike "*id=*" + $url | Should -BeLike "*pagetype=entityrecord*" + } + + It "Includes AppId parameter when provided" { + $connection = getMockConnection + + $recordId = [Guid]::NewGuid() + $appId = [Guid]::NewGuid() + $url = Get-DataverseRecordUrl -Connection $connection -TableName "contact" -Id $recordId -AppId $appId + + # Verify URL includes appid + $url | Should -BeLike "*appid=$appId*" + } + + It "Includes FormId parameter when provided" { + $connection = getMockConnection + + $recordId = [Guid]::NewGuid() + $formId = [Guid]::NewGuid() + $url = Get-DataverseRecordUrl -Connection $connection -TableName "contact" -Id $recordId -FormId $formId + + # Verify URL includes formid + $url | Should -BeLike "*formid=$formId*" + } + + It "Includes both AppId and FormId when provided" { + $connection = getMockConnection + + $recordId = [Guid]::NewGuid() + $appId = [Guid]::NewGuid() + $formId = [Guid]::NewGuid() + $url = Get-DataverseRecordUrl -Connection $connection -TableName "contact" -Id $recordId -AppId $appId -FormId $formId + + # Verify URL includes both parameters + $url | Should -BeLike "*appid=$appId*" + $url | Should -BeLike "*formid=$formId*" + } + + It "Works with pipeline input from Get-DataverseRecord" { + $connection = getMockConnection -Entities contact + + # Create test records + $contact1 = @{ firstname = "John"; lastname = "Doe" } | Set-DataverseRecord -Connection $connection -TableName contact -CreateOnly -PassThru + $contact2 = @{ firstname = "Jane"; lastname = "Smith" } | Set-DataverseRecord -Connection $connection -TableName contact -CreateOnly -PassThru + + # Generate URLs from pipeline + $urls = Get-DataverseRecord -Connection $connection -TableName contact | Get-DataverseRecordUrl -Connection $connection -TableName contact + + # Verify URLs generated for both records + $urls | Should -HaveCount 2 + $urls[0] | Should -BeLike "*id=$($contact1.Id)*" + $urls[1] | Should -BeLike "*id=$($contact2.Id)*" + } + + It "Uses connection's organization URL" { + $connection = getMockConnection + + $url = Get-DataverseRecordUrl -Connection $connection -TableName "contact" + + # Verify URL uses the connection's org URL + $url | Should -BeLike "https://*" + } + + It "Works with default connection" { + $connection = getMockConnection + Set-DataverseConnectionAsDefault -Connection $connection + + # Call without explicit connection + $recordId = [Guid]::NewGuid() + $url = Get-DataverseRecordUrl -TableName "contact" -Id $recordId + + # Verify URL generated + $url | Should -Not -BeNullOrEmpty + $url | Should -BeLike "*id=$recordId*" + } + } +} From 1df15ee52bcc3f5c41281c9c765bd006f1ab8bcf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 18:26:26 +0000 Subject: [PATCH 3/6] Fix maker and admin portal URLs - remove extra pages, add table context and app uniquename Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com> --- .../GetDataverseAdminPortalUrlCmdlet.cs | 46 +-------- .../GetDataverseMakerPortalUrlCmdlet.cs | 55 +++++------ .../docs/Get-DataverseAdminPortalUrl.md | 59 ++++-------- .../docs/Get-DataverseMakerPortalUrl.md | 77 +++++++++++---- tests/Get-DataverseAdminPortalUrl.Tests.ps1 | 81 +--------------- tests/Get-DataverseMakerPortalUrl.Tests.ps1 | 95 +++++-------------- 6 files changed, 129 insertions(+), 284 deletions(-) diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs index 49f31867a..782a90b64 100644 --- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs @@ -12,13 +12,6 @@ namespace Rnwood.Dataverse.Data.PowerShell.Commands [OutputType(typeof(string))] public class GetDataverseAdminPortalUrlCmdlet : OrganizationServiceCmdlet { - /// - /// Gets or sets the specific page to navigate to in the admin portal. - /// - [Parameter(Mandatory = false, HelpMessage = "Specific page to navigate to in the admin portal (e.g., 'environments', 'analytics', 'resources').")] - [ValidateSet("home", "environments", "analytics", "resources", "dataintegration", "datapolicies", "helpandsupport")] - public string Page { get; set; } = "environments"; - /// /// Processes the cmdlet to generate the admin portal URL. /// @@ -41,43 +34,10 @@ protected override void ProcessRecord() WhoAmIResponse whoAmIResponse = (WhoAmIResponse)Connection.Execute(whoAmIRequest); Guid orgId = whoAmIResponse.OrganizationId; - // Build the admin portal URL - string baseUrl = "https://admin.powerplatform.microsoft.com"; + // Build the admin portal URL for the specific environment + string url = $"https://admin.powerplatform.microsoft.com/environments/{orgId:D}/hub"; - // For environments page, include the specific environment - if (Page.ToLowerInvariant() == "environments") - { - string url = $"{baseUrl}/environments/{orgId:D}/hub"; - WriteObject(url); - } - else - { - // For other pages, navigate to the general section - string url = baseUrl; - switch (Page.ToLowerInvariant()) - { - case "analytics": - url += "/analytics"; - break; - case "resources": - url += "/resources"; - break; - case "dataintegration": - url += "/dataintegration"; - break; - case "datapolicies": - url += "/datapolicies"; - break; - case "helpandsupport": - url += "/support"; - break; - case "home": - default: - url += "/home"; - break; - } - WriteObject(url); - } + WriteObject(url); } } } diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs index ebf138308..ce06a10e6 100644 --- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs @@ -13,11 +13,18 @@ namespace Rnwood.Dataverse.Data.PowerShell.Commands public class GetDataverseMakerPortalUrlCmdlet : OrganizationServiceCmdlet { /// - /// Gets or sets the specific page to navigate to in the maker portal. + /// Gets or sets the logical name of the table to open in the maker portal. /// - [Parameter(Mandatory = false, HelpMessage = "Specific page to navigate to in the maker portal (e.g., 'solutions', 'tables', 'apps').")] - [ValidateSet("home", "solutions", "tables", "apps", "flows", "chatbots", "connections", "dataflows", "entities")] - public string Page { get; set; } = "home"; + [Parameter(Mandatory = false, ParameterSetName = "Table", ValueFromPipelineByPropertyName = true, HelpMessage = "Logical name of the table to open in the maker portal (e.g., 'account', 'contact').")] + [Alias("EntityName", "LogicalName")] + public string TableName { get; set; } + + /// + /// Gets or sets the unique name of the app to open in the maker portal. + /// + [Parameter(Mandatory = false, ParameterSetName = "App", ValueFromPipelineByPropertyName = true, HelpMessage = "Unique name of the app to open in the maker portal.")] + [Alias("UniqueName")] + public string AppUniqueName { get; set; } /// /// Processes the cmdlet to generate the maker portal URL. @@ -45,35 +52,19 @@ protected override void ProcessRecord() string baseUrl = "https://make.powerapps.com"; string url = $"{baseUrl}/environments/{orgId:D}"; - // Add page-specific path - switch (Page.ToLowerInvariant()) + // If table name is provided, navigate to that table + if (!string.IsNullOrEmpty(TableName)) + { + url += $"/entities/entity/{TableName}"; + } + // If app unique name is provided, navigate to that app + else if (!string.IsNullOrEmpty(AppUniqueName)) + { + url += $"/apps/{AppUniqueName}"; + } + else { - case "solutions": - url += "/solutions"; - break; - case "tables": - case "entities": - url += "/entities"; - break; - case "apps": - url += "/apps"; - break; - case "flows": - url += "/flows"; - break; - case "chatbots": - url += "/chatbots"; - break; - case "connections": - url += "/connections"; - break; - case "dataflows": - url += "/dataflows"; - break; - case "home": - default: - url += "/home"; - break; + url += "/home"; } WriteObject(url); diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md index 2dd3cc011..3257471b8 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md @@ -13,7 +13,7 @@ Generates a URL to open the Power Platform Admin Center for the current environm ## SYNTAX ``` -Get-DataverseAdminPortalUrl [-Page ] [-Connection ] +Get-DataverseAdminPortalUrl [-Connection ] [-ProgressAction ] [] ``` @@ -22,62 +22,37 @@ Get-DataverseAdminPortalUrl [-Page ] [-Connection ] This cmdlet generates a URL that opens the Power Platform Admin Center for the Dataverse environment associated with the current connection. The Admin Center is where administrators can: -- Manage environments -- View analytics and reports -- Configure data integration -- Manage resources and capacity -- Set up data policies -- Access help and support - -You can optionally specify which section of the Admin Center to navigate to directly. +- Manage environment settings +- View environment details +- Configure environment resources +- Monitor environment health +- Manage environment access and security ## EXAMPLES -### Example 1: Get URL for specific environment in Admin Center +### Example 1: Get URL for environment in Admin Center ```powershell PS C:\> Get-DataverseAdminPortalUrl -Connection $c ``` -Returns a URL to open the Admin Center for the connected environment (defaults to environments page). - -### Example 2: Get URL for analytics page -```powershell -PS C:\> Get-DataverseAdminPortalUrl -Connection $c -Page "analytics" -``` - -Returns a URL to open the Analytics page in the Admin Center. +Returns a URL to open the Admin Center for the connected environment. -### Example 3: Get URL for data policies page +### Example 2: Open Admin Center directly in browser ```powershell -PS C:\> Get-DataverseAdminPortalUrl -Connection $c -Page "datapolicies" +PS C:\> Start-Process (Get-DataverseAdminPortalUrl -Connection $c) ``` -Returns a URL to open the Data Policies page in the Admin Center. +Opens the Admin Center for the environment directly in the default web browser. -### Example 4: Open Admin Center directly in browser +### Example 3: Get Admin URLs for multiple connections ```powershell -PS C:\> Start-Process (Get-DataverseAdminPortalUrl -Connection $c -Page "resources") +PS C:\> $connections | ForEach-Object { Get-DataverseAdminPortalUrl -Connection $_ } ``` -Opens the Resources page of the Admin Center directly in the default web browser. +Generates Admin Center URLs for multiple connections. ## PARAMETERS -### -Page -Specific page to navigate to in the admin portal. Valid values are: home, environments, analytics, resources, dataintegration, datapolicies, helpandsupport. - -```yaml -Type: String -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: environments -Accept pipeline input: False -Accept wildcard characters: False -``` - ### -Connection DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. @@ -121,11 +96,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ## NOTES -The Admin Center URL format varies by page: -- For environments: https://admin.powerplatform.microsoft.com/environments/{environmentId}/hub -- For other pages: https://admin.powerplatform.microsoft.com/{page} +The Admin Center URL format is: https://admin.powerplatform.microsoft.com/environments/{environmentId}/hub -Administrative permissions may be required to access certain sections of the Admin Center. +Administrative permissions may be required to access the Admin Center. ## RELATED LINKS [Power Platform Admin Center](https://admin.powerplatform.microsoft.com) diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md index 5eed63450..713e65eae 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md @@ -12,8 +12,15 @@ Generates a URL to open the Power Apps Maker Portal for the current environment. ## SYNTAX +### Table ``` -Get-DataverseMakerPortalUrl [-Page ] [-Connection ] +Get-DataverseMakerPortalUrl [-TableName ] [-Connection ] + [-ProgressAction ] [] +``` + +### App +``` +Get-DataverseMakerPortalUrl [-AppUniqueName ] [-Connection ] [-ProgressAction ] [] ``` @@ -28,7 +35,7 @@ The Maker Portal is where you can: - Create and manage flows - Work with connections and data sources -You can optionally specify which page of the Maker Portal to navigate to directly. +Optionally, you can specify a table name or app unique name to open that specific resource's detail page in the Maker Portal. ## EXAMPLES @@ -39,41 +46,70 @@ PS C:\> Get-DataverseMakerPortalUrl -Connection $c Returns a URL to open the Maker Portal home page for the connected environment. -### Example 2: Get URL for solutions page +### Example 2: Get URL for a specific table in Maker Portal +```powershell +PS C:\> Get-DataverseMakerPortalUrl -Connection $c -TableName "contact" +``` + +Returns a URL to open the contact table's detail page in the Maker Portal. + +### Example 3: Get URL for a specific app in Maker Portal ```powershell -PS C:\> Get-DataverseMakerPortalUrl -Connection $c -Page "solutions" +PS C:\> Get-DataverseMakerPortalUrl -Connection $c -AppUniqueName "myapp_12345" ``` -Returns a URL to open the Solutions page in the Maker Portal. +Returns a URL to open the app with unique name "myapp_12345" in the Maker Portal. -### Example 3: Get URL for tables page +### Example 4: Open table from pipeline ```powershell -PS C:\> Get-DataverseMakerPortalUrl -Connection $c -Page "tables" +PS C:\> Get-DataverseEntityMetadata -Connection $c -TableName "account" | Get-DataverseMakerPortalUrl -Connection $c ``` -Returns a URL to open the Tables page in the Maker Portal. +Gets the account table metadata and generates a URL to open it in the Maker Portal. -### Example 4: Open Maker Portal directly in browser +### Example 5: Open app from pipeline ```powershell -PS C:\> Start-Process (Get-DataverseMakerPortalUrl -Connection $c -Page "apps") +PS C:\> Get-DataverseAppModule -Connection $c -Name "Sales Hub" | Get-DataverseMakerPortalUrl -Connection $c ``` -Opens the Apps page of the Maker Portal directly in the default web browser. +Gets the Sales Hub app and generates a URL to open it in the Maker Portal. + +### Example 6: Open Maker Portal directly in browser +```powershell +PS C:\> Start-Process (Get-DataverseMakerPortalUrl -Connection $c -TableName "contact") +``` + +Opens the contact table in the Maker Portal directly in the default web browser. ## PARAMETERS -### -Page -Specific page to navigate to in the maker portal. Valid values are: home, solutions, tables, apps, flows, chatbots, connections, dataflows, entities. +### -TableName +The logical name of the table to open in the maker portal (e.g., 'account', 'contact'). If not provided, opens the Maker Portal home page. ```yaml Type: String -Parameter Sets: (All) -Aliases: +Parameter Sets: Table +Aliases: EntityName, LogicalName Required: False Position: Named -Default value: home -Accept pipeline input: False +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -AppUniqueName +The unique name of the app to open in the maker portal. If not provided, opens the Maker Portal home page. + +```yaml +Type: String +Parameter Sets: App +Aliases: UniqueName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` @@ -112,7 +148,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ## INPUTS -### None +### System.String ## OUTPUTS @@ -120,7 +156,10 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ## NOTES -The Maker Portal URL is always in the format: https://make.powerapps.com/environments/{environmentId}/{page} +The Maker Portal URL format is: +- Home page: https://make.powerapps.com/environments/{environmentId}/home +- Table page: https://make.powerapps.com/environments/{environmentId}/entities/entity/{tableName} +- App page: https://make.powerapps.com/environments/{environmentId}/apps/{appUniqueName} ## RELATED LINKS [Power Apps Maker Portal](https://make.powerapps.com) diff --git a/tests/Get-DataverseAdminPortalUrl.Tests.ps1 b/tests/Get-DataverseAdminPortalUrl.Tests.ps1 index 4ff6b487f..f8f16226d 100644 --- a/tests/Get-DataverseAdminPortalUrl.Tests.ps1 +++ b/tests/Get-DataverseAdminPortalUrl.Tests.ps1 @@ -2,7 +2,7 @@ Describe 'Get-DataverseAdminPortalUrl' { Context 'Admin Portal URL Generation' { - It "Generates URL for environment page by default" { + It "Generates URL for environment page" { $connection = getMockConnection $url = Get-DataverseAdminPortalUrl -Connection $connection @@ -13,82 +13,19 @@ Describe 'Get-DataverseAdminPortalUrl' { $url | Should -BeLike "*/hub" } - It "Generates URL for analytics page" { - $connection = getMockConnection - - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "analytics" - - # Verify URL points to analytics - $url | Should -BeLike "https://admin.powerplatform.microsoft.com/analytics" - } - - It "Generates URL for resources page" { - $connection = getMockConnection - - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "resources" - - # Verify URL points to resources - $url | Should -BeLike "https://admin.powerplatform.microsoft.com/resources" - } - - It "Generates URL for data integration page" { - $connection = getMockConnection - - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "dataintegration" - - # Verify URL points to data integration - $url | Should -BeLike "https://admin.powerplatform.microsoft.com/dataintegration" - } - - It "Generates URL for data policies page" { - $connection = getMockConnection - - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "datapolicies" - - # Verify URL points to data policies - $url | Should -BeLike "https://admin.powerplatform.microsoft.com/datapolicies" - } - - It "Generates URL for help and support page" { - $connection = getMockConnection - - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "helpandsupport" - - # Verify URL points to support - $url | Should -BeLike "https://admin.powerplatform.microsoft.com/support" - } - - It "Generates URL for home page" { - $connection = getMockConnection - - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "home" - - # Verify URL points to home - $url | Should -BeLike "https://admin.powerplatform.microsoft.com/home" - } - - It "Includes environment ID for environments page" { + It "Includes environment ID from connection" { $connection = getMockConnection # Get the organization ID (which is the environment ID) $whoami = Get-DataverseWhoAmI -Connection $connection $envId = $whoami.OrganizationId - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "environments" + $url = Get-DataverseAdminPortalUrl -Connection $connection # Verify URL includes the environment ID $url | Should -BeLike "*/environments/$envId/hub" } - It "Does not include environment ID for non-environment pages" { - $connection = getMockConnection - - $url = Get-DataverseAdminPortalUrl -Connection $connection -Page "analytics" - - # Verify URL does not include /environments/ path - $url | Should -Not -BeLike "*/environments/*" - } - It "Works with default connection" { $connection = getMockConnection Set-DataverseConnectionAsDefault -Connection $connection @@ -100,17 +37,5 @@ Describe 'Get-DataverseAdminPortalUrl' { $url | Should -Not -BeNullOrEmpty $url | Should -BeLike "https://admin.powerplatform.microsoft.com/*" } - - It "Handles case-insensitive page parameter" { - $connection = getMockConnection - - $url1 = Get-DataverseAdminPortalUrl -Connection $connection -Page "Analytics" - $url2 = Get-DataverseAdminPortalUrl -Connection $connection -Page "ANALYTICS" - $url3 = Get-DataverseAdminPortalUrl -Connection $connection -Page "analytics" - - # All should produce the same URL - $url1 | Should -Be $url2 - $url2 | Should -Be $url3 - } } } diff --git a/tests/Get-DataverseMakerPortalUrl.Tests.ps1 b/tests/Get-DataverseMakerPortalUrl.Tests.ps1 index 6fb38865b..f3c1ff827 100644 --- a/tests/Get-DataverseMakerPortalUrl.Tests.ps1 +++ b/tests/Get-DataverseMakerPortalUrl.Tests.ps1 @@ -13,76 +13,22 @@ Describe 'Get-DataverseMakerPortalUrl' { $url | Should -BeLike "*/home" } - It "Generates URL for solutions page" { + It "Generates URL for a specific table" { $connection = getMockConnection - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "solutions" + $url = Get-DataverseMakerPortalUrl -Connection $connection -TableName "contact" - # Verify URL points to solutions - $url | Should -BeLike "*/solutions" + # Verify URL points to the table + $url | Should -BeLike "*/entities/entity/contact" } - It "Generates URL for tables page" { + It "Generates URL for a specific app by unique name" { $connection = getMockConnection - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "tables" + $url = Get-DataverseMakerPortalUrl -Connection $connection -AppUniqueName "myapp_12345" - # Verify URL points to entities (tables) - $url | Should -BeLike "*/entities" - } - - It "Generates URL for entities page (alias for tables)" { - $connection = getMockConnection - - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "entities" - - # Verify URL points to entities - $url | Should -BeLike "*/entities" - } - - It "Generates URL for apps page" { - $connection = getMockConnection - - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "apps" - - # Verify URL points to apps - $url | Should -BeLike "*/apps" - } - - It "Generates URL for flows page" { - $connection = getMockConnection - - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "flows" - - # Verify URL points to flows - $url | Should -BeLike "*/flows" - } - - It "Generates URL for chatbots page" { - $connection = getMockConnection - - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "chatbots" - - # Verify URL points to chatbots - $url | Should -BeLike "*/chatbots" - } - - It "Generates URL for connections page" { - $connection = getMockConnection - - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "connections" - - # Verify URL points to connections - $url | Should -BeLike "*/connections" - } - - It "Generates URL for dataflows page" { - $connection = getMockConnection - - $url = Get-DataverseMakerPortalUrl -Connection $connection -Page "dataflows" - - # Verify URL points to dataflows - $url | Should -BeLike "*/dataflows" + # Verify URL points to the app + $url | Should -BeLike "*/apps/myapp_12345" } It "Includes environment ID from connection" { @@ -110,16 +56,27 @@ Describe 'Get-DataverseMakerPortalUrl' { $url | Should -BeLike "https://make.powerapps.com/*" } - It "Handles case-insensitive page parameter" { + It "Supports pipeline input for TableName" { + $connection = getMockConnection -Entities contact + + # Create a table metadata object with LogicalName property + $metadata = Get-DataverseEntityMetadata -Connection $connection -TableName "contact" + + $url = $metadata | Get-DataverseMakerPortalUrl -Connection $connection + + # Verify URL includes the table + $url | Should -BeLike "*/entities/entity/contact" + } + + It "Prioritizes TableName over AppUniqueName when both provided" { $connection = getMockConnection - $url1 = Get-DataverseMakerPortalUrl -Connection $connection -Page "Solutions" - $url2 = Get-DataverseMakerPortalUrl -Connection $connection -Page "SOLUTIONS" - $url3 = Get-DataverseMakerPortalUrl -Connection $connection -Page "solutions" + # Note: This shouldn't happen in normal use due to parameter sets + # but testing the logic + $url = Get-DataverseMakerPortalUrl -Connection $connection -TableName "account" - # All should produce the same URL - $url1 | Should -Be $url2 - $url2 | Should -Be $url3 + # Verify URL uses table + $url | Should -BeLike "*/entities/entity/account" } } } From 4d8b4d225742dc89d39ba9d78955beafd8339781 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 21:15:51 +0000 Subject: [PATCH 4/6] Move AppUniqueName to Get-DataverseRecordUrl, keep AppId as alternate, add URL generation docs Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com> --- README.md | 1 + .../GetDataverseMakerPortalUrlCmdlet.cs | 14 +- .../Commands/GetDataverseRecordUrlCmdlet.cs | 48 +++- .../docs/Get-DataverseMakerPortalUrl.md | 45 +--- .../docs/Get-DataverseRecordUrl.md | 137 +++++++++++- docs/core-concepts/url-generation.md | 208 ++++++++++++++++++ 6 files changed, 390 insertions(+), 63 deletions(-) create mode 100644 docs/core-concepts/url-generation.md diff --git a/README.md b/README.md index c78df217e..084edb1cf 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ For more advanced scenarios including view management and app module management, - [Working with Metadata](docs/core-concepts/metadata.md) - Reading and managing schema (entities, attributes, relationships, option sets) - [Error Handling and Batch Operations](docs/core-concepts/error-handling.md) - Error handling and retry logic - [Environment Variables and Connection References](docs/core-concepts/environment-variables-connection-references.md) - Managing configuration and connections +- [URL Generation](docs/core-concepts/url-generation.md) - Generate URLs for records, maker portal, and admin center ### Advanced Topics - [Parallelization](docs/advanced/parallelization.md) - Parallel processing for best performance diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs index ce06a10e6..a90a50de3 100644 --- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs @@ -15,17 +15,10 @@ public class GetDataverseMakerPortalUrlCmdlet : OrganizationServiceCmdlet /// /// Gets or sets the logical name of the table to open in the maker portal. /// - [Parameter(Mandatory = false, ParameterSetName = "Table", ValueFromPipelineByPropertyName = true, HelpMessage = "Logical name of the table to open in the maker portal (e.g., 'account', 'contact').")] + [Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "Logical name of the table to open in the maker portal (e.g., 'account', 'contact').")] [Alias("EntityName", "LogicalName")] public string TableName { get; set; } - /// - /// Gets or sets the unique name of the app to open in the maker portal. - /// - [Parameter(Mandatory = false, ParameterSetName = "App", ValueFromPipelineByPropertyName = true, HelpMessage = "Unique name of the app to open in the maker portal.")] - [Alias("UniqueName")] - public string AppUniqueName { get; set; } - /// /// Processes the cmdlet to generate the maker portal URL. /// @@ -57,11 +50,6 @@ protected override void ProcessRecord() { url += $"/entities/entity/{TableName}"; } - // If app unique name is provided, navigate to that app - else if (!string.IsNullOrEmpty(AppUniqueName)) - { - url += $"/apps/{AppUniqueName}"; - } else { url += "/home"; diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs index 4b3684fd8..31b4001e3 100644 --- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs @@ -1,7 +1,9 @@ using System; +using System.Linq; using System.Management.Automation; using Microsoft.PowerPlatform.Dataverse.Client; using Microsoft.Xrm.Sdk; +using Microsoft.Xrm.Sdk.Query; namespace Rnwood.Dataverse.Data.PowerShell.Commands { @@ -27,9 +29,16 @@ public class GetDataverseRecordUrlCmdlet : OrganizationServiceCmdlet public Guid? Id { get; set; } /// - /// Gets or sets the app ID to open the record in a specific app. + /// Gets or sets the unique name of the app to open the record in a specific model-driven app. /// - [Parameter(Mandatory = false, HelpMessage = "App ID to open the record in a specific model-driven app.")] + [Parameter(Mandatory = false, ParameterSetName = "ByAppUniqueName", ValueFromPipelineByPropertyName = true, HelpMessage = "Unique name of the app to open the record in a specific model-driven app. The app ID will be looked up (including unpublished apps).")] + [Alias("UniqueName")] + public string AppUniqueName { get; set; } + + /// + /// Gets or sets the app ID to open the record in a specific model-driven app. + /// + [Parameter(Mandatory = false, ParameterSetName = "ByAppId", HelpMessage = "App ID to open the record in a specific model-driven app.")] public Guid? AppId { get; set; } /// @@ -70,6 +79,37 @@ protected override void ProcessRecord() // Remove trailing slash baseUrl = baseUrl.TrimEnd('/'); + // Resolve AppId from AppUniqueName if provided + Guid? resolvedAppId = AppId; + if (!string.IsNullOrEmpty(AppUniqueName)) + { + WriteVerbose($"Looking up app module by unique name: {AppUniqueName}"); + + var query = new QueryExpression("appmodule") + { + ColumnSet = new ColumnSet("appmoduleid"), + Criteria = new FilterExpression() + }; + query.Criteria.AddCondition("uniquename", ConditionOperator.Equal, AppUniqueName); + + // Query including unpublished apps + var appModules = QueryHelpers.ExecuteQueryWithPaging(query, Connection, WriteVerbose, unpublished: true); + var appModule = appModules.FirstOrDefault(); + + if (appModule == null) + { + ThrowTerminatingError(new ErrorRecord( + new InvalidOperationException($"App module with unique name '{AppUniqueName}' not found."), + "AppModuleNotFound", + ErrorCategory.ObjectNotFound, + AppUniqueName)); + return; + } + + resolvedAppId = appModule.Id; + WriteVerbose($"Resolved app module ID: {resolvedAppId}"); + } + // Build the URL string url; if (Id.HasValue) @@ -84,9 +124,9 @@ protected override void ProcessRecord() } // Add optional parameters - if (AppId.HasValue) + if (resolvedAppId.HasValue) { - url += $"&appid={AppId.Value:D}"; + url += $"&appid={resolvedAppId.Value:D}"; } if (FormId.HasValue) diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md index 713e65eae..d9aa12a5d 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md @@ -12,18 +12,11 @@ Generates a URL to open the Power Apps Maker Portal for the current environment. ## SYNTAX -### Table ``` Get-DataverseMakerPortalUrl [-TableName ] [-Connection ] [-ProgressAction ] [] ``` -### App -``` -Get-DataverseMakerPortalUrl [-AppUniqueName ] [-Connection ] - [-ProgressAction ] [] -``` - ## DESCRIPTION This cmdlet generates a URL that opens the Power Apps Maker Portal for the Dataverse environment associated with the current connection. @@ -35,7 +28,7 @@ The Maker Portal is where you can: - Create and manage flows - Work with connections and data sources -Optionally, you can specify a table name or app unique name to open that specific resource's detail page in the Maker Portal. +Optionally, you can specify a table name to open that specific table's detail page in the Maker Portal. ## EXAMPLES @@ -53,28 +46,14 @@ PS C:\> Get-DataverseMakerPortalUrl -Connection $c -TableName "contact" Returns a URL to open the contact table's detail page in the Maker Portal. -### Example 3: Get URL for a specific app in Maker Portal -```powershell -PS C:\> Get-DataverseMakerPortalUrl -Connection $c -AppUniqueName "myapp_12345" -``` - -Returns a URL to open the app with unique name "myapp_12345" in the Maker Portal. - -### Example 4: Open table from pipeline +### Example 3: Open table from pipeline ```powershell PS C:\> Get-DataverseEntityMetadata -Connection $c -TableName "account" | Get-DataverseMakerPortalUrl -Connection $c ``` Gets the account table metadata and generates a URL to open it in the Maker Portal. -### Example 5: Open app from pipeline -```powershell -PS C:\> Get-DataverseAppModule -Connection $c -Name "Sales Hub" | Get-DataverseMakerPortalUrl -Connection $c -``` - -Gets the Sales Hub app and generates a URL to open it in the Maker Portal. - -### Example 6: Open Maker Portal directly in browser +### Example 4: Open Maker Portal directly in browser ```powershell PS C:\> Start-Process (Get-DataverseMakerPortalUrl -Connection $c -TableName "contact") ``` @@ -88,7 +67,7 @@ The logical name of the table to open in the maker portal (e.g., 'account', 'con ```yaml Type: String -Parameter Sets: Table +Parameter Sets: (All) Aliases: EntityName, LogicalName Required: False @@ -98,21 +77,6 @@ Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` -### -AppUniqueName -The unique name of the app to open in the maker portal. If not provided, opens the Maker Portal home page. - -```yaml -Type: String -Parameter Sets: App -Aliases: UniqueName - -Required: False -Position: Named -Default value: None -Accept pipeline input: True (ByPropertyName) -Accept wildcard characters: False -``` - ### -Connection DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. @@ -159,7 +123,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable The Maker Portal URL format is: - Home page: https://make.powerapps.com/environments/{environmentId}/home - Table page: https://make.powerapps.com/environments/{environmentId}/entities/entity/{tableName} -- App page: https://make.powerapps.com/environments/{environmentId}/apps/{appUniqueName} ## RELATED LINKS [Power Apps Maker Portal](https://make.powerapps.com) diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md index a195c4bd4..4d0e0dc61 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md @@ -12,6 +12,13 @@ Generates a URL to open a record in the Dataverse web interface. ## SYNTAX +### ByAppUniqueName +``` +Get-DataverseRecordUrl [-TableName] [[-Id] ] [-AppUniqueName ] [-FormId ] + [-Connection ] [-ProgressAction ] [] +``` + +### ByAppId ``` Get-DataverseRecordUrl [-TableName] [[-Id] ] [-AppId ] [-FormId ] [-Connection ] [-ProgressAction ] [] @@ -27,7 +34,7 @@ The generated URL can be: - Embedded in custom applications or workflows - Used for deep-linking into specific records or forms -The cmdlet can optionally include parameters to open the record in a specific app or with a specific form. +The cmdlet can optionally include parameters to open the record in a specific app (by app ID or unique name) or with a specific form. ## EXAMPLES @@ -45,21 +52,28 @@ PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" Returns a URL to open a form for creating a new account record. -### Example 3: Get URL for a record in a specific app +### Example 3: Get URL for a record in a specific app by unique name +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -AppUniqueName "myapp_12345" +``` + +Returns a URL to open the contact record in the app with unique name "myapp_12345". The app ID is automatically looked up (including unpublished apps). + +### Example 4: Get URL for a record in a specific app by ID ```powershell PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -AppId "87654321-4321-4321-4321-210987654321" ``` -Returns a URL to open the contact record in the specified model-driven app. +Returns a URL to open the contact record in the specified model-driven app by app ID. -### Example 4: Get URL with a specific form +### Example 5: Get URL with a specific form ```powershell PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" -FormId "abcdefgh-abcd-abcd-abcd-abcdefghijkl" ``` Returns a URL to create a new account using the specified form. -### Example 5: Generate URLs from pipeline +### Example 6: Generate URLs from pipeline ```powershell PS C:\> Get-DataverseRecord -Connection $c -TableName "contact" | Get-DataverseRecordUrl -Connection $c -TableName "contact" ``` @@ -98,6 +112,119 @@ Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` +### -AppUniqueName +The unique name of the app to open the record in a specific model-driven app. The app ID will be looked up automatically (including unpublished apps). + +```yaml +Type: String +Parameter Sets: ByAppUniqueName +Aliases: UniqueName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -AppId +The App ID to open the record in a specific model-driven app. + +```yaml +Type: Guid +Parameter Sets: ByAppId +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -FormId +The Form ID to open a specific form for the record. + +```yaml +Type: Guid +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Connection +DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. + +```yaml +Type: ServiceClient +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String +### System.Guid + +## OUTPUTS + +### System.String + +## NOTES + +When using AppUniqueName, the cmdlet will query the appmodule entity to find the app ID, including unpublished apps. + +## RELATED LINKS + +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Id +The ID of the record. If not provided, generates a URL for creating a new record. + +```yaml +Type: Guid +Parameter Sets: (All) +Aliases: RecordId + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + ### -AppId The App ID to open the record in a specific model-driven app. diff --git a/docs/core-concepts/url-generation.md b/docs/core-concepts/url-generation.md new file mode 100644 index 000000000..435d7097a --- /dev/null +++ b/docs/core-concepts/url-generation.md @@ -0,0 +1,208 @@ +# URL Generation + +Generate URLs for accessing Dataverse resources in web browsers. These cmdlets help you create deep links to records, navigate to the Power Apps Maker Portal, or open the Power Platform Admin Center. + +## Overview + +The URL generation cmdlets provide a convenient way to: +- Share links to specific records with team members +- Create bookmarks for frequently accessed resources +- Integrate Dataverse URLs into custom applications or workflows +- Quickly navigate to administrative interfaces + +## Available Cmdlets + +### Get-DataverseRecordUrl + +Generates URLs to open specific records or create new records in the Dataverse web interface. + +**Basic Usage:** + +```powershell +# Get URL for a specific contact record +$url = Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id $contactId + +# Get URL to create a new account +$url = Get-DataverseRecordUrl -Connection $c -TableName "account" + +# Open record in a specific app by unique name +$url = Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id $contactId -AppUniqueName "sales_app" + +# Open record in a specific app by ID +$url = Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id $contactId -AppId $appId + +# Open record with a specific form +$url = Get-DataverseRecordUrl -Connection $c -TableName "account" -FormId $formId +``` + +**Key Features:** +- Supports both existing records (with ID) and new record creation (without ID) +- Can specify app context using either: + - **AppUniqueName**: Looks up the app ID automatically (including unpublished apps) + - **AppId**: Uses the app ID directly +- Optional form ID parameter to open specific forms +- Works with pipeline input for batch URL generation + +### Get-DataverseMakerPortalUrl + +Generates URLs to open the Power Apps Maker Portal for the current environment. + +**Basic Usage:** + +```powershell +# Get URL for Maker Portal home page +$url = Get-DataverseMakerPortalUrl -Connection $c + +# Get URL for a specific table in the Maker Portal +$url = Get-DataverseMakerPortalUrl -Connection $c -TableName "contact" + +# Open Maker Portal directly in browser +Start-Process (Get-DataverseMakerPortalUrl -Connection $c -TableName "account") +``` + +**Key Features:** +- Opens the Maker Portal home page by default +- Optional table context to open a specific table's detail page +- Automatically determines the environment ID from the connection + +### Get-DataverseAdminPortalUrl + +Generates URLs to open the Power Platform Admin Center for the current environment. + +**Basic Usage:** + +```powershell +# Get URL for Admin Center +$url = Get-DataverseAdminPortalUrl -Connection $c + +# Open Admin Center directly in browser +Start-Process (Get-DataverseAdminPortalUrl -Connection $c) +``` + +**Key Features:** +- Opens the environment hub page in the Admin Center +- Automatically determines the environment ID from the connection + +## Common Scenarios + +### Sharing Record Links + +Generate and share URLs for specific records: + +```powershell +# Get URLs for all high-priority cases +$cases = Get-DataverseRecord -Connection $c -TableName "incident" -FilterValues @{ prioritycode = 1 } +$caseUrls = $cases | ForEach-Object { + [PSCustomObject]@{ + Title = $_.title + CaseNumber = $_.ticketnumber + URL = Get-DataverseRecordUrl -Connection $c -TableName "incident" -Id $_.incidentid + } +} +$caseUrls | Export-Csv -Path "high-priority-cases.csv" -NoTypeInformation +``` + +### Opening Records in Specific Apps + +Open records in different app contexts: + +```powershell +# Open contact in Sales Hub app +$salesUrl = Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id $contactId -AppUniqueName "SalesHub" + +# Open same contact in Customer Service Hub +$serviceUrl = Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id $contactId -AppUniqueName "CustomerServiceHub" +``` + +### Bulk URL Generation + +Generate URLs for multiple records efficiently: + +```powershell +# Generate URLs for all active accounts +Get-DataverseRecord -Connection $c -TableName "account" -FilterValues @{ statecode = 0 } | + Select-Object name, accountid, + @{Name='URL'; Expression={ Get-DataverseRecordUrl -Connection $c -TableName "account" -Id $_.accountid }} | + Export-Csv -Path "active-accounts-with-urls.csv" -NoTypeInformation +``` + +### Navigation Helper Functions + +Create helper functions for quick navigation: + +```powershell +function Open-DataverseRecord { + param( + [Parameter(Mandatory)] + [string]$TableName, + [Parameter(Mandatory)] + [guid]$Id, + [string]$AppUniqueName + ) + + $url = if ($AppUniqueName) { + Get-DataverseRecordUrl -TableName $TableName -Id $Id -AppUniqueName $AppUniqueName + } else { + Get-DataverseRecordUrl -TableName $TableName -Id $Id + } + + Start-Process $url +} + +# Usage +Open-DataverseRecord -TableName "contact" -Id $contactId -AppUniqueName "sales_app" +``` + +### Admin Portal Quick Access + +Quickly access the admin portal for your environment: + +```powershell +# Create a shortcut function +function Open-AdminPortal { + Start-Process (Get-DataverseAdminPortalUrl) +} + +# Usage +Open-AdminPortal +``` + +## URL Format Reference + +### Record URLs +``` +https://{org}.crm.dynamics.com/main.aspx?etn={table}&id={recordid}&pagetype=entityrecord +https://{org}.crm.dynamics.com/main.aspx?etn={table}&id={recordid}&pagetype=entityrecord&appid={appid} +https://{org}.crm.dynamics.com/main.aspx?etn={table}&pagetype=entityrecord (new record) +``` + +### Maker Portal URLs +``` +https://make.powerapps.com/environments/{envid}/home +https://make.powerapps.com/environments/{envid}/entities/entity/{tablename} +``` + +### Admin Portal URLs +``` +https://admin.powerplatform.microsoft.com/environments/{envid}/hub +``` + +## Best Practices + +1. **Use AppUniqueName when possible**: It's more maintainable than app IDs and works with unpublished apps +2. **Cache generated URLs**: If you're generating many URLs for the same records, consider caching them +3. **Validate app existence**: When using AppUniqueName, the cmdlet will error if the app isn't found +4. **Consider permissions**: Generated URLs still require the user to have appropriate permissions +5. **Use default connections**: Set a default connection to avoid repeating the `-Connection` parameter + +## Related Cmdlets + +- [`Get-DataverseConnection`](../../../Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseConnection.md) — Create or retrieve connections +- [`Get-DataverseRecord`](../../../Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecord.md) — Query records +- [`Get-DataverseAppModule`](../../../Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModule.md) — Query app modules + +## See Also + +- [Cmdlet Documentation](../../../Rnwood.Dataverse.Data.PowerShell/docs/) +- [Connection Management](connections.md) +- [App Module Management](app-module-management.md) From 3b73b93e4462d651d4047f4879bbccb93799a870 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 21:17:19 +0000 Subject: [PATCH 5/6] Update tests for URL cmdlets - add AppUniqueName test, remove from maker portal Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com> --- tests/Get-DataverseMakerPortalUrl.Tests.ps1 | 20 -------------------- tests/Get-DataverseRecordUrl.Tests.ps1 | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/tests/Get-DataverseMakerPortalUrl.Tests.ps1 b/tests/Get-DataverseMakerPortalUrl.Tests.ps1 index f3c1ff827..b608d2d5b 100644 --- a/tests/Get-DataverseMakerPortalUrl.Tests.ps1 +++ b/tests/Get-DataverseMakerPortalUrl.Tests.ps1 @@ -22,15 +22,6 @@ Describe 'Get-DataverseMakerPortalUrl' { $url | Should -BeLike "*/entities/entity/contact" } - It "Generates URL for a specific app by unique name" { - $connection = getMockConnection - - $url = Get-DataverseMakerPortalUrl -Connection $connection -AppUniqueName "myapp_12345" - - # Verify URL points to the app - $url | Should -BeLike "*/apps/myapp_12345" - } - It "Includes environment ID from connection" { $connection = getMockConnection @@ -67,16 +58,5 @@ Describe 'Get-DataverseMakerPortalUrl' { # Verify URL includes the table $url | Should -BeLike "*/entities/entity/contact" } - - It "Prioritizes TableName over AppUniqueName when both provided" { - $connection = getMockConnection - - # Note: This shouldn't happen in normal use due to parameter sets - # but testing the logic - $url = Get-DataverseMakerPortalUrl -Connection $connection -TableName "account" - - # Verify URL uses table - $url | Should -BeLike "*/entities/entity/account" - } } } diff --git a/tests/Get-DataverseRecordUrl.Tests.ps1 b/tests/Get-DataverseRecordUrl.Tests.ps1 index 57e789820..3d08d8fea 100644 --- a/tests/Get-DataverseRecordUrl.Tests.ps1 +++ b/tests/Get-DataverseRecordUrl.Tests.ps1 @@ -42,6 +42,24 @@ Describe 'Get-DataverseRecordUrl' { $url | Should -BeLike "*appid=$appId*" } + It "Resolves AppUniqueName to AppId" { + $connection = getMockConnection + + # Create a mock app module + $appId = [Guid]::NewGuid() + $appModule = @{ + appmoduleid = $appId + uniquename = "testapp_123" + name = "Test App" + } | Set-DataverseRecord -Connection $connection -TableName appmodule -CreateOnly -PassThru + + $recordId = [Guid]::NewGuid() + $url = Get-DataverseRecordUrl -Connection $connection -TableName "contact" -Id $recordId -AppUniqueName "testapp_123" + + # Verify URL includes the resolved appid + $url | Should -BeLike "*appid=$appId*" + } + It "Includes FormId parameter when provided" { $connection = getMockConnection From aad1142695726b5c4dcc24239be96e089e73b882 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:33:17 +0000 Subject: [PATCH 6/6] Fix URL cmdlet bugs found via manual testing; add E2E tests Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com> --- .../GetDataverseAdminPortalUrlCmdlet.cs | 7 +- .../GetDataverseMakerPortalUrlCmdlet.cs | 7 +- .../Commands/GetDataverseRecordUrlCmdlet.cs | 11 +- .../Urls/UrlCmdletTests.cs | 200 +++++++ .../docs/Get-DataverseAdminPortalUrl.md | 207 ++++--- .../docs/Get-DataverseMakerPortalUrl.md | 255 +++++---- .../docs/Get-DataverseRecordUrl.md | 506 +++++++----------- .../docs/Rnwood.Dataverse.Data.PowerShell.md | 9 + 8 files changed, 655 insertions(+), 547 deletions(-) create mode 100644 Rnwood.Dataverse.Data.PowerShell.E2ETests/Urls/UrlCmdletTests.cs diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs index 782a90b64..1ddaddf5b 100644 --- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseAdminPortalUrlCmdlet.cs @@ -1,7 +1,6 @@ using System; using System.Management.Automation; using Microsoft.PowerPlatform.Dataverse.Client; -using Microsoft.Crm.Sdk.Messages; namespace Rnwood.Dataverse.Data.PowerShell.Commands { @@ -29,10 +28,8 @@ protected override void ProcessRecord() return; } - // Get the environment ID from the organization - WhoAmIRequest whoAmIRequest = new WhoAmIRequest(); - WhoAmIResponse whoAmIResponse = (WhoAmIResponse)Connection.Execute(whoAmIRequest); - Guid orgId = whoAmIResponse.OrganizationId; + // Use ConnectedOrgId directly - avoids an extra WhoAmI network call + Guid orgId = Connection.ConnectedOrgId; // Build the admin portal URL for the specific environment string url = $"https://admin.powerplatform.microsoft.com/environments/{orgId:D}/hub"; diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs index a90a50de3..e2381c5a4 100644 --- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseMakerPortalUrlCmdlet.cs @@ -1,7 +1,6 @@ using System; using System.Management.Automation; using Microsoft.PowerPlatform.Dataverse.Client; -using Microsoft.Crm.Sdk.Messages; namespace Rnwood.Dataverse.Data.PowerShell.Commands { @@ -36,10 +35,8 @@ protected override void ProcessRecord() return; } - // Get the environment ID from the organization - WhoAmIRequest whoAmIRequest = new WhoAmIRequest(); - WhoAmIResponse whoAmIResponse = (WhoAmIResponse)Connection.Execute(whoAmIRequest); - Guid orgId = whoAmIResponse.OrganizationId; + // Use ConnectedOrgId directly - avoids an extra WhoAmI network call + Guid orgId = Connection.ConnectedOrgId; // Build the maker portal URL string baseUrl = "https://make.powerapps.com"; diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs index 31b4001e3..4f1583625 100644 --- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs +++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseRecordUrlCmdlet.cs @@ -10,7 +10,7 @@ namespace Rnwood.Dataverse.Data.PowerShell.Commands /// /// Generates a URL to open a record in the Dataverse web interface. /// - [Cmdlet(VerbsCommon.Get, "DataverseRecordUrl")] + [Cmdlet(VerbsCommon.Get, "DataverseRecordUrl", DefaultParameterSetName = "ByAppUniqueName")] [OutputType(typeof(string))] public class GetDataverseRecordUrlCmdlet : OrganizationServiceCmdlet { @@ -64,8 +64,13 @@ protected override void ProcessRecord() return; } - // Extract the base URL from the connection - string baseUrl = Connection.ConnectedOrgUriActual?.ToString(); + // Extract the base URL from the connection using the WebApplication endpoint + string baseUrl = null; + if (Connection.ConnectedOrgPublishedEndpoints?.ContainsKey(Microsoft.Xrm.Sdk.Discovery.EndpointType.WebApplication) == true) + { + baseUrl = Connection.ConnectedOrgPublishedEndpoints[Microsoft.Xrm.Sdk.Discovery.EndpointType.WebApplication]?.ToString(); + } + if (string.IsNullOrEmpty(baseUrl)) { ThrowTerminatingError(new ErrorRecord( diff --git a/Rnwood.Dataverse.Data.PowerShell.E2ETests/Urls/UrlCmdletTests.cs b/Rnwood.Dataverse.Data.PowerShell.E2ETests/Urls/UrlCmdletTests.cs new file mode 100644 index 000000000..6f5b3f904 --- /dev/null +++ b/Rnwood.Dataverse.Data.PowerShell.E2ETests/Urls/UrlCmdletTests.cs @@ -0,0 +1,200 @@ +using FluentAssertions; +using Rnwood.Dataverse.Data.PowerShell.E2ETests.Infrastructure; +using Xunit; + +namespace Rnwood.Dataverse.Data.PowerShell.E2ETests.Urls +{ + /// + /// E2E tests for URL generation cmdlets: Get-DataverseRecordUrl, Get-DataverseMakerPortalUrl, Get-DataverseAdminPortalUrl. + /// + public class UrlCmdletTests : E2ETestBase + { + [Fact] + public void GetDataverseRecordUrl_ExistingRecord_ReturnsCorrectUrl() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +# Get an existing contact record +$contacts = Get-DataverseRecord -Connection $connection -TableName contact -Top 1 -Columns contactid +if (-not $contacts) { throw 'No contact records found for testing' } +$contactId = $contacts.contactid + +$url = Get-DataverseRecordUrl -Connection $connection -TableName contact -Id $contactId + +Write-Host ""URL: $url"" + +# Validate URL format +$orgUrl = $connection.ConnectedOrgPublishedEndpoints['WebApplication'].TrimEnd('/') +if (-not $url.StartsWith($orgUrl)) { throw ""URL does not start with org URL. Expected start: $orgUrl, Got: $url"" } +if ($url -notmatch 'main\.aspx') { throw ""URL does not contain main.aspx"" } +if ($url -notmatch 'etn=contact') { throw ""URL does not contain etn=contact"" } +if ($url -notmatch ""id=$contactId"") { throw ""URL does not contain record ID"" } +if ($url -notmatch 'pagetype=entityrecord') { throw ""URL does not contain pagetype=entityrecord"" } + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + + [Fact] + public void GetDataverseRecordUrl_NewRecord_ReturnsUrlWithoutId() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +$url = Get-DataverseRecordUrl -Connection $connection -TableName account + +Write-Host ""URL: $url"" + +$orgUrl = $connection.ConnectedOrgPublishedEndpoints['WebApplication'].TrimEnd('/') +if (-not $url.StartsWith($orgUrl)) { throw ""URL does not start with org URL"" } +if ($url -notmatch 'etn=account') { throw ""URL does not contain etn=account"" } +if ($url -match '&id=') { throw ""URL should not contain an id parameter"" } +if ($url -notmatch 'pagetype=entityrecord') { throw ""URL does not contain pagetype=entityrecord"" } + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + + [Fact] + public void GetDataverseRecordUrl_WithAppUniqueName_ResolvesAppIdAndIncludesInUrl() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +# Get an existing app module and a contact record +$apps = Get-DataverseRecord -Connection $connection -TableName appmodule -Columns appmoduleid,uniquename -Top 1 +if (-not $apps) { throw 'No app modules found for testing' } +$app = $apps[0] +Write-Host ""Using app: $($app.uniquename) / $($app.appmoduleid)"" + +$contacts = Get-DataverseRecord -Connection $connection -TableName contact -Top 1 -Columns contactid +$contactId = $contacts.contactid + +$url = Get-DataverseRecordUrl -Connection $connection -TableName contact -Id $contactId -AppUniqueName $app.uniquename + +Write-Host ""URL: $url"" + +if ($url -notmatch ""appid=$($app.appmoduleid)"") { throw ""URL does not contain expected appid $($app.appmoduleid). URL: $url"" } + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + + [Fact] + public void GetDataverseRecordUrl_WithAppId_IncludesAppIdInUrl() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +$apps = Get-DataverseRecord -Connection $connection -TableName appmodule -Columns appmoduleid -Top 1 +if (-not $apps) { throw 'No app modules found for testing' } +$appId = $apps[0].appmoduleid + +$contacts = Get-DataverseRecord -Connection $connection -TableName contact -Top 1 -Columns contactid +$contactId = $contacts.contactid + +$url = Get-DataverseRecordUrl -Connection $connection -TableName contact -Id $contactId -AppId $appId + +Write-Host ""URL: $url"" + +if ($url -notmatch ""appid=$appId"") { throw ""URL does not contain appid. URL: $url"" } + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + + [Fact] + public void GetDataverseRecordUrl_WithInvalidAppUniqueName_ThrowsError() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +try { + Get-DataverseRecordUrl -Connection $connection -TableName contact -AppUniqueName 'nonexistent_app_xyz_12345' + throw 'Should have thrown an error for non-existent app' +} catch { + if ($_.Exception.Message -notmatch 'nonexistent_app_xyz_12345') { + throw ""Unexpected error message: $($_.Exception.Message)"" + } + Write-Host ""Correctly threw error for missing app"" +} + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + + [Fact] + public void GetDataverseMakerPortalUrl_NoParameters_ReturnsHomePageUrl() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +$url = Get-DataverseMakerPortalUrl -Connection $connection + +Write-Host ""URL: $url"" + +$orgId = $connection.ConnectedOrgId.ToString('D') +if (-not $url.StartsWith('https://make.powerapps.com/environments/')) { throw ""URL does not start with expected prefix: $url"" } +if ($url -notmatch $orgId) { throw ""URL does not contain org ID $orgId. URL: $url"" } +if (-not $url.EndsWith('/home')) { throw ""URL does not end with /home: $url"" } + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + + [Fact] + public void GetDataverseMakerPortalUrl_WithTableName_ReturnsTableContextUrl() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +$url = Get-DataverseMakerPortalUrl -Connection $connection -TableName contact + +Write-Host ""URL: $url"" + +$orgId = $connection.ConnectedOrgId.ToString('D') +if (-not $url.StartsWith('https://make.powerapps.com/environments/')) { throw ""URL does not start with expected prefix: $url"" } +if ($url -notmatch $orgId) { throw ""URL does not contain org ID $orgId. URL: $url"" } +if (-not $url.EndsWith('/entities/entity/contact')) { throw ""URL does not end with table path: $url"" } + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + + [Fact] + public void GetDataverseAdminPortalUrl_ReturnsEnvironmentHubUrl() + { + var script = GetConnectionScript(@" +$ErrorActionPreference = 'Stop' + +$url = Get-DataverseAdminPortalUrl -Connection $connection + +Write-Host ""URL: $url"" + +$orgId = $connection.ConnectedOrgId.ToString('D') +if (-not $url.StartsWith('https://admin.powerplatform.microsoft.com/environments/')) { throw ""URL does not start with expected prefix: $url"" } +if ($url -notmatch $orgId) { throw ""URL does not contain org ID $orgId. URL: $url"" } +if (-not $url.EndsWith('/hub')) { throw ""URL does not end with /hub: $url"" } + +Write-Host 'SUCCESS' +"); + var result = RunScript(script); + result.StandardOutput.Should().Contain("SUCCESS", because: result.GetFullOutput()); + } + } +} diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md index 3257471b8..a539ec4ba 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAdminPortalUrl.md @@ -1,104 +1,103 @@ ---- -external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml -Module Name: Rnwood.Dataverse.Data.PowerShell -online version: -schema: 2.0.0 ---- - -# Get-DataverseAdminPortalUrl - -## SYNOPSIS -Generates a URL to open the Power Platform Admin Center for the current environment. - -## SYNTAX - -``` -Get-DataverseAdminPortalUrl [-Connection ] - [-ProgressAction ] [] -``` - -## DESCRIPTION - -This cmdlet generates a URL that opens the Power Platform Admin Center for the Dataverse environment associated with the current connection. - -The Admin Center is where administrators can: -- Manage environment settings -- View environment details -- Configure environment resources -- Monitor environment health -- Manage environment access and security - -## EXAMPLES - -### Example 1: Get URL for environment in Admin Center -```powershell -PS C:\> Get-DataverseAdminPortalUrl -Connection $c -``` - -Returns a URL to open the Admin Center for the connected environment. - -### Example 2: Open Admin Center directly in browser -```powershell -PS C:\> Start-Process (Get-DataverseAdminPortalUrl -Connection $c) -``` - -Opens the Admin Center for the environment directly in the default web browser. - -### Example 3: Get Admin URLs for multiple connections -```powershell -PS C:\> $connections | ForEach-Object { Get-DataverseAdminPortalUrl -Connection $_ } -``` - -Generates Admin Center URLs for multiple connections. - -## PARAMETERS - -### -Connection -DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. - -```yaml -Type: ServiceClient -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -ProgressAction -{{ Fill ProgressAction Description }} - -```yaml -Type: ActionPreference -Parameter Sets: (All) -Aliases: proga - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### None - -## OUTPUTS - -### System.String - -## NOTES - -The Admin Center URL format is: https://admin.powerplatform.microsoft.com/environments/{environmentId}/hub - -Administrative permissions may be required to access the Admin Center. - -## RELATED LINKS -[Power Platform Admin Center](https://admin.powerplatform.microsoft.com) +--- +external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml +Module Name: Rnwood.Dataverse.Data.PowerShell +online version: +schema: 2.0.0 +--- + +# Get-DataverseAdminPortalUrl + +## SYNOPSIS +Generates a URL to open the Power Platform Admin Center for the current environment. + +## SYNTAX + +``` +Get-DataverseAdminPortalUrl [-Connection ] [-ProgressAction ] + [] +``` + +## DESCRIPTION + +This cmdlet generates a URL that opens the Power Platform Admin Center for the Dataverse environment associated with the current connection. + +The Admin Center is where administrators can: +- Manage environment settings +- View environment details +- Configure environment resources +- Monitor environment health +- Manage environment access and security + +## EXAMPLES + +### Example 1: Get URL for environment in Admin Center +```powershell +PS C:\> Get-DataverseAdminPortalUrl -Connection $c +``` + +Returns a URL to open the Admin Center for the connected environment. + +### Example 2: Open Admin Center directly in browser +```powershell +PS C:\> Start-Process (Get-DataverseAdminPortalUrl -Connection $c) +``` + +Opens the Admin Center for the environment directly in the default web browser. + +### Example 3: Get Admin URLs for multiple connections +```powershell +PS C:\> $connections | ForEach-Object { Get-DataverseAdminPortalUrl -Connection $_ } +``` + +Generates Admin Center URLs for multiple connections. + +## PARAMETERS + +### -Connection +DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. + +```yaml +Type: ServiceClient +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None +## OUTPUTS + +### System.String +## NOTES + +The Admin Center URL format is: https://admin.powerplatform.microsoft.com/environments/{environmentId}/hub + +Administrative permissions may be required to access the Admin Center. + +## RELATED LINKS + +[Power Platform Admin Center](https://admin.powerplatform.microsoft.com) diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md index d9aa12a5d..295d68b35 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseMakerPortalUrl.md @@ -1,128 +1,127 @@ ---- -external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml -Module Name: Rnwood.Dataverse.Data.PowerShell -online version: -schema: 2.0.0 ---- - -# Get-DataverseMakerPortalUrl - -## SYNOPSIS -Generates a URL to open the Power Apps Maker Portal for the current environment. - -## SYNTAX - -``` -Get-DataverseMakerPortalUrl [-TableName ] [-Connection ] - [-ProgressAction ] [] -``` - -## DESCRIPTION - -This cmdlet generates a URL that opens the Power Apps Maker Portal for the Dataverse environment associated with the current connection. - -The Maker Portal is where you can: -- Build and configure Power Apps -- Manage solutions -- View and manage tables (entities) -- Create and manage flows -- Work with connections and data sources - -Optionally, you can specify a table name to open that specific table's detail page in the Maker Portal. - -## EXAMPLES - -### Example 1: Get URL for Maker Portal home page -```powershell -PS C:\> Get-DataverseMakerPortalUrl -Connection $c -``` - -Returns a URL to open the Maker Portal home page for the connected environment. - -### Example 2: Get URL for a specific table in Maker Portal -```powershell -PS C:\> Get-DataverseMakerPortalUrl -Connection $c -TableName "contact" -``` - -Returns a URL to open the contact table's detail page in the Maker Portal. - -### Example 3: Open table from pipeline -```powershell -PS C:\> Get-DataverseEntityMetadata -Connection $c -TableName "account" | Get-DataverseMakerPortalUrl -Connection $c -``` - -Gets the account table metadata and generates a URL to open it in the Maker Portal. - -### Example 4: Open Maker Portal directly in browser -```powershell -PS C:\> Start-Process (Get-DataverseMakerPortalUrl -Connection $c -TableName "contact") -``` - -Opens the contact table in the Maker Portal directly in the default web browser. - -## PARAMETERS - -### -TableName -The logical name of the table to open in the maker portal (e.g., 'account', 'contact'). If not provided, opens the Maker Portal home page. - -```yaml -Type: String -Parameter Sets: (All) -Aliases: EntityName, LogicalName - -Required: False -Position: Named -Default value: None -Accept pipeline input: True (ByPropertyName) -Accept wildcard characters: False -``` - -### -Connection -DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. - -```yaml -Type: ServiceClient -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -ProgressAction -{{ Fill ProgressAction Description }} - -```yaml -Type: ActionPreference -Parameter Sets: (All) -Aliases: proga - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### System.String - -## OUTPUTS - -### System.String - -## NOTES - -The Maker Portal URL format is: -- Home page: https://make.powerapps.com/environments/{environmentId}/home -- Table page: https://make.powerapps.com/environments/{environmentId}/entities/entity/{tableName} - -## RELATED LINKS -[Power Apps Maker Portal](https://make.powerapps.com) +--- +external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml +Module Name: Rnwood.Dataverse.Data.PowerShell +online version: +schema: 2.0.0 +--- + +# Get-DataverseMakerPortalUrl + +## SYNOPSIS +Generates a URL to open the Power Apps Maker Portal for the current environment. + +## SYNTAX + +``` +Get-DataverseMakerPortalUrl [-TableName ] [-Connection ] + [-ProgressAction ] [] +``` + +## DESCRIPTION + +This cmdlet generates a URL that opens the Power Apps Maker Portal for the Dataverse environment associated with the current connection. + +The Maker Portal is where you can: +- Build and configure Power Apps +- Manage solutions +- View and manage tables (entities) +- Create and manage flows +- Work with connections and data sources + +Optionally, you can specify a table name to open that specific table's detail page in the Maker Portal. + +## EXAMPLES + +### Example 1: Get URL for Maker Portal home page +```powershell +PS C:\> Get-DataverseMakerPortalUrl -Connection $c +``` + +Returns a URL to open the Maker Portal home page for the connected environment. + +### Example 2: Get URL for a specific table in Maker Portal +```powershell +PS C:\> Get-DataverseMakerPortalUrl -Connection $c -TableName "contact" +``` + +Returns a URL to open the contact table's detail page in the Maker Portal. + +### Example 3: Open table from pipeline +```powershell +PS C:\> Get-DataverseEntityMetadata -Connection $c -TableName "account" | Get-DataverseMakerPortalUrl -Connection $c +``` + +Gets the account table metadata and generates a URL to open it in the Maker Portal. + +### Example 4: Open Maker Portal directly in browser +```powershell +PS C:\> Start-Process (Get-DataverseMakerPortalUrl -Connection $c -TableName "contact") +``` + +Opens the contact table in the Maker Portal directly in the default web browser. + +## PARAMETERS + +### -Connection +DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. + +```yaml +Type: ServiceClient +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -TableName +The logical name of the table to open in the maker portal (e.g., 'account', 'contact'). If not provided, opens the Maker Portal home page. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: EntityName, LogicalName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String +## OUTPUTS + +### System.String +## NOTES + +The Maker Portal URL format is: +- Home page: https://make.powerapps.com/environments/{environmentId}/home +- Table page: https://make.powerapps.com/environments/{environmentId}/entities/entity/{tableName} + +## RELATED LINKS + +[Power Apps Maker Portal](https://make.powerapps.com) diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md index 4d0e0dc61..75d153c97 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordUrl.md @@ -1,302 +1,204 @@ ---- -external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml -Module Name: Rnwood.Dataverse.Data.PowerShell -online version: -schema: 2.0.0 ---- - -# Get-DataverseRecordUrl - -## SYNOPSIS -Generates a URL to open a record in the Dataverse web interface. - -## SYNTAX - -### ByAppUniqueName -``` -Get-DataverseRecordUrl [-TableName] [[-Id] ] [-AppUniqueName ] [-FormId ] - [-Connection ] [-ProgressAction ] [] -``` - -### ByAppId -``` -Get-DataverseRecordUrl [-TableName] [[-Id] ] [-AppId ] [-FormId ] - [-Connection ] [-ProgressAction ] [] -``` - -## DESCRIPTION - -This cmdlet generates a URL that can be used to open a record in the Dataverse web interface. If an ID is provided, the URL will open that specific record. If no ID is provided, the URL will open a form to create a new record. - -The generated URL can be: -- Opened directly in a web browser -- Shared with users via email or other communication -- Embedded in custom applications or workflows -- Used for deep-linking into specific records or forms - -The cmdlet can optionally include parameters to open the record in a specific app (by app ID or unique name) or with a specific form. - -## EXAMPLES - -### Example 1: Get URL for a specific record -```powershell -PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -``` - -Returns a URL to open the contact record with the specified ID. - -### Example 2: Get URL to create a new record -```powershell -PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" -``` - -Returns a URL to open a form for creating a new account record. - -### Example 3: Get URL for a record in a specific app by unique name -```powershell -PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -AppUniqueName "myapp_12345" -``` - -Returns a URL to open the contact record in the app with unique name "myapp_12345". The app ID is automatically looked up (including unpublished apps). - -### Example 4: Get URL for a record in a specific app by ID -```powershell -PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -AppId "87654321-4321-4321-4321-210987654321" -``` - -Returns a URL to open the contact record in the specified model-driven app by app ID. - -### Example 5: Get URL with a specific form -```powershell -PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" -FormId "abcdefgh-abcd-abcd-abcd-abcdefghijkl" -``` - -Returns a URL to create a new account using the specified form. - -### Example 6: Generate URLs from pipeline -```powershell -PS C:\> Get-DataverseRecord -Connection $c -TableName "contact" | Get-DataverseRecordUrl -Connection $c -TableName "contact" -``` - -Generates URLs for all contact records returned by Get-DataverseRecord. - -## PARAMETERS - -### -TableName -The logical name of the table (e.g., 'account', 'contact'). - -```yaml -Type: String -Parameter Sets: (All) -Aliases: EntityName, LogicalName - -Required: True -Position: 0 -Default value: None -Accept pipeline input: True (ByPropertyName) -Accept wildcard characters: False -``` - -### -Id -The ID of the record. If not provided, generates a URL for creating a new record. - -```yaml -Type: Guid -Parameter Sets: (All) -Aliases: RecordId - -Required: False -Position: 1 -Default value: None -Accept pipeline input: True (ByPropertyName) -Accept wildcard characters: False -``` - -### -AppUniqueName -The unique name of the app to open the record in a specific model-driven app. The app ID will be looked up automatically (including unpublished apps). - -```yaml -Type: String -Parameter Sets: ByAppUniqueName -Aliases: UniqueName - -Required: False -Position: Named -Default value: None -Accept pipeline input: True (ByPropertyName) -Accept wildcard characters: False -``` - -### -AppId -The App ID to open the record in a specific model-driven app. - -```yaml -Type: Guid -Parameter Sets: ByAppId -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -FormId -The Form ID to open a specific form for the record. - -```yaml -Type: Guid -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Connection -DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. - -```yaml -Type: ServiceClient -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -ProgressAction -{{ Fill ProgressAction Description }} - -```yaml -Type: ActionPreference -Parameter Sets: (All) -Aliases: proga - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### System.String -### System.Guid - -## OUTPUTS - -### System.String - -## NOTES - -When using AppUniqueName, the cmdlet will query the appmodule entity to find the app ID, including unpublished apps. - -## RELATED LINKS - -Default value: None -Accept pipeline input: True (ByPropertyName) -Accept wildcard characters: False -``` - -### -Id -The ID of the record. If not provided, generates a URL for creating a new record. - -```yaml -Type: Guid -Parameter Sets: (All) -Aliases: RecordId - -Required: False -Position: 1 -Default value: None -Accept pipeline input: True (ByPropertyName) -Accept wildcard characters: False -``` - -### -AppId -The App ID to open the record in a specific model-driven app. - -```yaml -Type: Guid -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -FormId -The Form ID to open a specific form for the record. - -```yaml -Type: Guid -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -Connection -DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. - -```yaml -Type: ServiceClient -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -ProgressAction -{{ Fill ProgressAction Description }} - -```yaml -Type: ActionPreference -Parameter Sets: (All) -Aliases: proga - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### System.String -### System.Guid - -## OUTPUTS - -### System.String - -## NOTES - -## RELATED LINKS +--- +external help file: Rnwood.Dataverse.Data.PowerShell.Cmdlets.dll-Help.xml +Module Name: Rnwood.Dataverse.Data.PowerShell +online version: +schema: 2.0.0 +--- + +# Get-DataverseRecordUrl + +## SYNOPSIS +Generates a URL to open a record in the Dataverse web interface. + +## SYNTAX + +### ByAppUniqueName (Default) +``` +Get-DataverseRecordUrl [-TableName] [[-Id] ] [-AppUniqueName ] [-FormId ] + [-Connection ] [-ProgressAction ] [] +``` + +### ByAppId +``` +Get-DataverseRecordUrl [-TableName] [[-Id] ] [-AppId ] [-FormId ] + [-Connection ] [-ProgressAction ] [] +``` + +## DESCRIPTION + +This cmdlet generates a URL that can be used to open a record in the Dataverse web interface. If an ID is provided, the URL will open that specific record. If no ID is provided, the URL will open a form to create a new record. + +The generated URL can be: +- Opened directly in a web browser +- Shared with users via email or other communication +- Embedded in custom applications or workflows +- Used for deep-linking into specific records or forms + +The cmdlet can optionally include parameters to open the record in a specific app (by app ID or unique name) or with a specific form. + +## EXAMPLES + +### Example 1: Get URL for a specific record +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" +``` + +Returns a URL to open the contact record with the specified ID. + +### Example 2: Get URL to create a new record +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" +``` + +Returns a URL to open a form for creating a new account record. + +### Example 3: Get URL for a record in a specific app by unique name +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -AppUniqueName "myapp_12345" +``` + +Returns a URL to open the contact record in the app with unique name "myapp_12345". The app ID is automatically looked up (including unpublished apps). + +### Example 4: Get URL for a record in a specific app by ID +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "contact" -Id "12345678-1234-1234-1234-123456789012" -AppId "87654321-4321-4321-4321-210987654321" +``` + +Returns a URL to open the contact record in the specified model-driven app by app ID. + +### Example 5: Get URL with a specific form +```powershell +PS C:\> Get-DataverseRecordUrl -Connection $c -TableName "account" -FormId "abcdefgh-abcd-abcd-abcd-abcdefghijkl" +``` + +Returns a URL to create a new account using the specified form. + +### Example 6: Generate URLs from pipeline +```powershell +PS C:\> Get-DataverseRecord -Connection $c -TableName "contact" | Get-DataverseRecordUrl -Connection $c -TableName "contact" +``` + +Generates URLs for all contact records returned by Get-DataverseRecord. + +## PARAMETERS + +### -AppId +The App ID to open the record in a specific model-driven app. + +```yaml +Type: Guid +Parameter Sets: ByAppId +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -AppUniqueName +The unique name of the app to open the record in a specific model-driven app. The app ID will be looked up automatically (including unpublished apps). + +```yaml +Type: String +Parameter Sets: ByAppUniqueName +Aliases: UniqueName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Connection +DataverseConnection instance obtained from Get-DataverseConnection cmdlet, or string specifying Dataverse organization URL (e.g. http://server.com/MyOrg/). If not provided, uses the default connection set via Get-DataverseConnection -SetAsDefault. + +```yaml +Type: ServiceClient +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -FormId +The Form ID to open a specific form for the record. + +```yaml +Type: Guid +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Id +The ID of the record. If not provided, generates a URL for creating a new record. + +```yaml +Type: Guid +Parameter Sets: (All) +Aliases: RecordId + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -TableName +The logical name of the table (e.g., 'account', 'contact'). + +```yaml +Type: String +Parameter Sets: (All) +Aliases: EntityName, LogicalName + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String +### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] +## OUTPUTS + +### System.String +## NOTES + +When using AppUniqueName, the cmdlet will query the appmodule entity to find the app ID, including unpublished apps. + +## RELATED LINKS diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Rnwood.Dataverse.Data.PowerShell.md b/Rnwood.Dataverse.Data.PowerShell/docs/Rnwood.Dataverse.Data.PowerShell.md index d34c81b4d..11c136399 100644 --- a/Rnwood.Dataverse.Data.PowerShell/docs/Rnwood.Dataverse.Data.PowerShell.md +++ b/Rnwood.Dataverse.Data.PowerShell/docs/Rnwood.Dataverse.Data.PowerShell.md @@ -26,6 +26,9 @@ Unpacks a Dataverse solution file using the Power Apps CLI. ### [Export-DataverseSolution](Export-DataverseSolution.md) Exports a solution from Dataverse using an asynchronous job with progress reporting. +### [Get-DataverseAdminPortalUrl](Get-DataverseAdminPortalUrl.md) +Generates a URL to open the Power Platform Admin Center for the current environment. + ### [Get-DataverseAppModule](Get-DataverseAppModule.md) Retrieves app module (model-driven app) information from a Dataverse environment. @@ -93,6 +96,9 @@ Retrieves tab information from a Dataverse form. ### [Get-DataverseIconSetIcon](Get-DataverseIconSetIcon.md) Retrieves available icons from supported online icon sets. +### [Get-DataverseMakerPortalUrl](Get-DataverseMakerPortalUrl.md) +Generates a URL to open the Power Apps Maker Portal for the current environment. + ### [Get-DataverseMsAppComponent](Get-DataverseMsAppComponent.md) Retrieves components from a .msapp file. @@ -142,6 +148,9 @@ Retrieves all principals (users or teams) who have shared access to a specific r Reads a folder of JSON files written out by `Set-DataverseRecordFolder` and converts back into a stream of PS objects. Together these commands can be used to extract and import data to and from files, for instance for inclusion in source control, or build/deployment assets. +### [Get-DataverseRecordUrl](Get-DataverseRecordUrl.md) +Generates a URL to open a record in the Dataverse web interface. + ### [Get-DataverseRelationshipMetadata](Get-DataverseRelationshipMetadata.md) Retrieves relationship metadata from Dataverse.