diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index d918dc3d5..196f0c36d 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -530,6 +530,56 @@ jobs:
if-no-files-found: ignore
retention-days: 1
+ # Build and publish MCP Server as .NET Global Tool
+ - if: ${{ matrix.publish }}
+ name: Build MCP Server Tool
+ shell: pwsh
+ run: |
+ # Get version from the module manifest or CI version file
+ if (Test-Path "ci-version.txt") {
+ $version = Get-Content "ci-version.txt" -Raw | ForEach-Object { $_.Trim() }
+ Write-Host "Using CI version: $version"
+ } elseif ($env:GITHUB_REF -like "refs/tags/*") {
+ $version = $env:GITHUB_REF -replace "refs/tags/v?", ""
+ Write-Host "Using release version: $version"
+ } else {
+ $version = "1.0.0"
+ Write-Host "Using default version: $version"
+ }
+
+ # Update version in MCP Server project file
+ $projectPath = "Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj"
+ $content = Get-Content $projectPath -Raw
+ $content = $content -replace '.*?', "$version"
+ $content | Set-Content $projectPath -Encoding UTF8
+
+ # Build the main module first (required for bundling)
+ dotnet build -c Release ./Rnwood.Dataverse.Data.PowerShell/Rnwood.Dataverse.Data.PowerShell.csproj
+
+ # Pack the MCP Server as a global tool
+ dotnet pack -c Release ./Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj -o ./nupkgs
+
+ Write-Host "Package created successfully"
+ Get-ChildItem ./nupkgs
+
+ - if: ${{ matrix.publish && github.event_name == 'release' && github.event.action == 'published' }}
+ name: Publish MCP Server to NuGet.org
+ env:
+ NUGET_KEY: ${{ secrets.NUGET_KEY }}
+ shell: pwsh
+ run: |
+ # Push stable release to NuGet.org
+ dotnet nuget push ./nupkgs/*.nupkg --api-key $env:NUGET_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate
+
+ - if: ${{ matrix.publish && github.ref == 'refs/heads/main' && github.event_name == 'push' }}
+ name: Publish MCP Server CI Build to NuGet.org
+ env:
+ NUGET_KEY: ${{ secrets.NUGET_KEY }}
+ shell: pwsh
+ run: |
+ # Push prerelease to NuGet.org
+ dotnet nuget push ./nupkgs/*.nupkg --api-key $env:NUGET_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate
+
# Upload test failure reports as artifacts
- name: Upload test failure report
if: failure() && github.event_name == 'pull_request'
diff --git a/README.md b/README.md
index bc3ebc737..f1282ac1d 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@ This module works in PowerShell Desktop and PowerShell Core, supporting Windows,
- Automatic data type conversion using metadata - use friendly labels for choices and names for lookups
- Automatic lookup conversion - use record names instead of GUIDs (when unique)
- On behalf of (delegation) support for create/update operations
+- **🤖 MCP Server for AI Assistants**: Model Context Protocol server that enables AI assistants like Claude to execute PowerShell scripts with Dataverse module. Features URL allowlist security, auto-connection, and persistent sessions. [Learn More ⬇](#mcp-server-for-ai-assistants)
- Duplicate detection support for create/update/upsert operations
- Full support for automatic paging
- Concise PowerShell-friendly hashtable-based filters with grouped logical expressions (and/or/not/xor) and arbitrary nesting
@@ -259,6 +260,167 @@ For operations not covered by the cmdlets above, use [`Invoke-DataverseRequest`]
See the [Invoke-DataverseRequest documentation](Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseRequest.md) for details on response conversion and parameter sets.
+## MCP Server for AI Assistants
+
+The **Model Context Protocol (MCP) Server** enables AI assistants like Claude Desktop to execute PowerShell scripts with the Dataverse module pre-loaded. This powerful integration allows AI to:
+
+- Query and analyze Dataverse data
+- Create, update, and delete records
+- Work with metadata and schema
+- Execute complex data operations
+- All with enterprise-grade security controls
+
+### Quick Start
+
+**1. No Installation Required - Use `dnx` (Recommended):**
+
+Configure in Claude Desktop by editing `claude_desktop_config.json` (location varies by platform):
+
+```json
+{
+ "mcpServers": {
+ "dataverse": {
+ "command": "dnx",
+ "args": [
+ "rnwood-dataverse-mcp",
+ "--allowed-urls",
+ "https://yourorg.crm.dynamics.com"
+ ]
+ }
+ }
+}
+```
+
+The `dnx` command (new in .NET 10 SDK) automatically downloads and runs the latest version from NuGet without any installation.
+
+**Alternative: Install as Global Tool:**
+
+```bash
+dotnet tool install --global Rnwood.Dataverse.Data.PowerShell.McpServer
+```
+
+Then configure with simpler syntax:
+```json
+{
+ "mcpServers": {
+ "dataverse": {
+ "command": "rnwood-dataverse-mcp",
+ "args": [
+ "--allowed-urls",
+ "https://yourorg.crm.dynamics.com"
+ ]
+ }
+ }
+}
+```
+
+**2. Restart Claude Desktop**
+
+The server will auto-connect to your Dataverse environment when first used.
+
+### Example Use Cases
+
+Once configured, you can ask Claude to help with Dataverse tasks:
+
+**"Show me all active contacts in our CRM"**
+```powershell
+Get-DataverseRecord -TableName contact -FilterValues @{ statecode = 0 } |
+ Select-Object fullname, emailaddress1, telephone1
+```
+
+**"Create a new account for Contoso Ltd"**
+```powershell
+Set-DataverseRecord -TableName account -InputObject @{
+ name = 'Contoso Ltd'
+ telephone1 = '555-0100'
+ websiteurl = 'https://contoso.com'
+} -CreateOnly
+```
+
+**"Find all opportunities worth more than $50,000"**
+```powershell
+Get-DataverseRecord -TableName opportunity -FilterValues @{
+ estimatedvalue = @{ GreaterThan = 50000 }
+ statecode = 0 # Active
+} | Select-Object name, estimatedvalue, customeridname
+```
+
+**"Generate a report of accounts created this month"**
+```powershell
+$startOfMonth = Get-Date -Day 1 -Hour 0 -Minute 0 -Second 0
+Get-DataverseRecord -TableName account -FilterValues @{
+ createdon = @{ GreaterThanOrEqual = $startOfMonth }
+} | Group-Object owneridname |
+ Select-Object Name, Count |
+ Sort-Object Count -Descending
+```
+
+**"Update all contacts at Fabrikam to have a new category"**
+```powershell
+# First, find the account
+$fabrikam = Get-DataverseRecord -TableName account -FilterValues @{ name = 'Fabrikam' }
+
+# Then update all related contacts
+Get-DataverseRecord -TableName contact -FilterValues @{
+ parentcustomerid = $fabrikam.accountid
+} | ForEach-Object {
+ Set-DataverseRecord -TableName contact -Id $_.contactid -InputObject @{
+ customertypecode = 3 # Strategic partner
+ }
+}
+```
+
+### Security Features
+
+The MCP Server includes enterprise-grade security:
+
+- **URL Allowlist**: Connections restricted to approved Dataverse environments only
+- **Restricted Language Mode**: Prevents .NET type access by default
+- **Provider Restrictions**: Filesystem and registry access disabled by default
+- **Auto-Connection**: Automatically connects to first allowed URL using interactive auth
+- **Session Isolation**: Each AI session runs in an isolated PowerShell environment
+
+### Advanced Configuration
+
+**Multiple Environments (using `dnx`):**
+```json
+{
+ "mcpServers": {
+ "dataverse": {
+ "command": "dnx",
+ "args": [
+ "rnwood-dataverse-mcp",
+ "--allowed-urls",
+ "https://dev.crm.dynamics.com",
+ "https://test.crm.dynamics.com",
+ "https://prod.crm.dynamics.com"
+ ]
+ }
+ }
+}
+```
+
+**Unrestricted Mode (for trusted environments, using `dnx`):**
+```json
+{
+ "mcpServers": {
+ "dataverse": {
+ "command": "dnx",
+ "args": [
+ "rnwood-dataverse-mcp",
+ "--allowed-urls",
+ "https://yourorg.crm.dynamics.com",
+ "--unrestricted-mode",
+ "--enable-providers"
+ ]
+ }
+ }
+}
+```
+
+For complete documentation including all MCP tools, security considerations, and troubleshooting, see the [**MCP Server Documentation**](Rnwood.Dataverse.Data.PowerShell.McpServer/README.md).
+
+
## Support and Contributing
- Report issues: [GitHub Issues](https://github.com/rnwood/Rnwood.Dataverse.Data.PowerShell/issues)
diff --git a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseConnectionCmdlet.cs b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseConnectionCmdlet.cs
index b7ba2aebd..2686eb2ac 100644
--- a/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseConnectionCmdlet.cs
+++ b/Rnwood.Dataverse.Data.PowerShell.Cmdlets/Commands/GetDataverseConnectionCmdlet.cs
@@ -271,8 +271,47 @@ public GetDataverseConnectionCmdlet()
[Parameter]
public Guid? TenantId { get; set; }
- // Cancellation token source that is cancelled when the user hits Ctrl+C (StopProcessing)
- private CancellationTokenSource _userCancellationCts;
+ private void ValidateUrlIfRestricted(Uri url)
+ {
+ if (url == null)
+ {
+ return;
+ }
+
+ var allowedUrlsVar = SessionState.PSVariable.Get("Global:AllowedDataverseUrls");
+ if (allowedUrlsVar == null || allowedUrlsVar.Value == null)
+ {
+ return;
+ }
+
+ var allowedUrls = allowedUrlsVar.Value as object[];
+ if (allowedUrls == null || allowedUrls.Length == 0)
+ {
+ return;
+ }
+
+ string normalizedInputUrl = url.ToString().TrimEnd('/').ToLowerInvariant();
+
+ foreach (var allowedUrl in allowedUrls)
+ {
+ if (allowedUrl == null)
+ {
+ continue;
+ }
+
+ string normalizedAllowedUrl = allowedUrl.ToString().TrimEnd('/').ToLowerInvariant();
+ if (normalizedInputUrl == normalizedAllowedUrl)
+ {
+ return;
+ }
+ }
+
+ ThrowTerminatingError(new ErrorRecord(
+ new UnauthorizedAccessException($"Access to URL '{url}' is not allowed. The URL is not in the list of allowed Dataverse URLs."),
+ "UrlNotAllowed",
+ ErrorCategory.PermissionDenied,
+ url));
+ }
///
/// Initializes the cmdlet processing.
@@ -308,6 +347,8 @@ protected override void EndProcessing()
_userCancellationCts = null;
}
+ private CancellationTokenSource _userCancellationCts;
+
private CancellationTokenSource CreateLinkedCts(TimeSpan timeout)
{
var timeoutCts = new CancellationTokenSource(timeout);
@@ -401,6 +442,7 @@ protected override void ProcessRecord()
// Restore connection parameters from metadata
Url = new Uri(metadata.Url);
+ ValidateUrlIfRestricted(Url);
ClientId = string.IsNullOrEmpty(metadata.ClientId) ? ClientId : new Guid(metadata.ClientId);
Username = metadata.Username;
ManagedIdentityClientId = metadata.ManagedIdentityClientId;
@@ -520,6 +562,8 @@ protected override void ProcessRecord()
Url = new Uri(discoveryUrl);
}
+ ValidateUrlIfRestricted(Url);
+
result = new ServiceClientWithTokenProvider(Url, url => GetTokenInteractive(publicClient, url));
// Save connection metadata if a name was provided
@@ -561,6 +605,7 @@ protected override void ProcessRecord()
var discoveryUrl = PromptToSelectEnvironmentUrl(url => GetTokenWithUsernamePassword(publicClient, url)).GetAwaiter().GetResult();
Url = new Uri(discoveryUrl);
}
+ ValidateUrlIfRestricted(Url);
result = new ServiceClientWithTokenProvider(Url, url => GetTokenWithUsernamePassword(publicClient, url));
@@ -602,6 +647,7 @@ protected override void ProcessRecord()
.WithRedirectUri("http://localhost")
.Build();
+ ValidateUrlIfRestricted(Url);
// Register MSAL cache if saving a named connection
if (!string.IsNullOrEmpty(Name))
{
@@ -657,6 +703,8 @@ protected override void ProcessRecord()
Url = new Uri(discoveryUrl);
}
+ ValidateUrlIfRestricted(Url);
+
// Now get the authority for the selected environment
string authority = GetAuthority();
@@ -706,6 +754,7 @@ protected override void ProcessRecord()
break;
}
+ ValidateUrlIfRestricted(Url);
case PARAMSET_CLIENTCERTIFICATE:
{
@@ -747,6 +796,8 @@ protected override void ProcessRecord()
store.RegisterCache(confApp);
}
+ ValidateUrlIfRestricted(Url);
+
result = new ServiceClientWithTokenProvider(Url, url => GetTokenWithClientCertificate(confApp, url));
// Save connection metadata if a name was provided
@@ -786,7 +837,7 @@ protected override void ProcessRecord()
break;
}
-
+ ValidateUrlIfRestricted(Url);
case PARAMSET_DEFAULTAZURECREDENTIAL:
{
var credential = new Azure.Identity.DefaultAzureCredential();
@@ -805,6 +856,7 @@ protected override void ProcessRecord()
result = new ServiceClientWithTokenProvider(Url, url => GetTokenWithAzureCredential(credential, url));
+ ValidateUrlIfRestricted(Url);
// Save connection metadata if a name was provided
if (!string.IsNullOrEmpty(Name))
{
diff --git a/Rnwood.Dataverse.Data.PowerShell.McpServer/Program.cs b/Rnwood.Dataverse.Data.PowerShell.McpServer/Program.cs
new file mode 100644
index 000000000..e7abefb18
--- /dev/null
+++ b/Rnwood.Dataverse.Data.PowerShell.McpServer/Program.cs
@@ -0,0 +1,54 @@
+using System;
+using System.CommandLine;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Rnwood.Dataverse.Data.PowerShell.McpServer.Tools;
+
+// Define command line options
+var allowedUrlsOption = new Option(
+ name: "--allowed-urls",
+ description: "List of allowed Dataverse URLs for connections (required). Connections can only be made to these URLs. Server will auto-connect to first URL.")
+{
+ IsRequired = true,
+ AllowMultipleArgumentsPerToken = true
+};
+allowedUrlsOption.AddAlias("-u");
+
+var rootCommand = new RootCommand("Dataverse PowerShell MCP Server - Execute PowerShell scripts with Dataverse module via Model Context Protocol")
+{
+ allowedUrlsOption
+};
+
+rootCommand.SetHandler(async (allowedUrls) =>
+{
+ // Normalize URLs (remove trailing slashes)
+ var normalizedUrls = allowedUrls.Select(url => url.TrimEnd('/')).ToArray();
+
+ var config = new PowerShellExecutorConfig
+ {
+ AllowedUrls = normalizedUrls
+ };
+
+ // STDIO mode
+ var builder = Host.CreateApplicationBuilder();
+
+ builder.Services.AddSingleton(config);
+ builder.Services.AddSingleton();
+ builder.Services.AddSingleton();
+
+ builder.Services.AddMcpServer()
+ .WithStdioServerTransport()
+ .WithTools();
+
+ builder.Logging.AddConsole(options =>
+ {
+ options.LogToStandardErrorThreshold = LogLevel.Trace;
+ });
+
+ await builder.Build().RunAsync();
+}, allowedUrlsOption);
+
+return await rootCommand.InvokeAsync(args);
diff --git a/Rnwood.Dataverse.Data.PowerShell.McpServer/README.md b/Rnwood.Dataverse.Data.PowerShell.McpServer/README.md
new file mode 100644
index 000000000..cb42a4889
--- /dev/null
+++ b/Rnwood.Dataverse.Data.PowerShell.McpServer/README.md
@@ -0,0 +1,221 @@
+# Rnwood.Dataverse.Data.PowerShell.McpServer
+
+A Model Context Protocol (MCP) server that exposes PowerShell with the Dataverse Data PowerShell module pre-loaded via STDIO transport.
+
+## Overview
+
+This MCP server allows AI assistants and other MCP clients to execute PowerShell scripts with the Rnwood.Dataverse.Data.PowerShell module pre-loaded. The server provides a configurable PowerShell environment with:
+
+- Dataverse Data PowerShell module pre-loaded
+- **Persistent sessions** - create sessions and run multiple scripts sequentially
+- **URL allowlist** - restricts connections to specified Dataverse URLs only
+- **Auto-connection** - automatically connects to the first allowed URL on session creation
+- Incremental output retrieval
+
+## Requirements
+
+- .NET 8.0 or later
+- PowerShell 7.4.6 or later (provided via Microsoft.PowerShell.SDK)
+- Built Rnwood.Dataverse.Data.PowerShell module
+- **One or more allowed Dataverse URLs** (required parameter)
+
+## Installation
+
+### Using `dnx` (Recommended - No Installation Required)
+
+Run the MCP server directly from NuGet without installing it globally using the new `dnx` command (available in .NET 10 SDK):
+
+```bash
+dnx rnwood-dataverse-mcp --allowed-urls https://myorg.crm.dynamics.com
+```
+
+This approach:
+- **No installation needed** - downloads and runs the tool on-demand
+- **Always uses the latest version** - automatically fetches updates from NuGet
+- **Simpler syntax** - streamlined command compared to `dotnet exec`
+- **No global PATH pollution** - doesn't install anything permanently
+
+> **Note**: The `dnx` command is available in .NET 10 SDK and later. For earlier versions of .NET, use the global tool installation method below.
+
+### As a .NET Global Tool (Alternative)
+
+Install the MCP server as a global tool from NuGet.org:
+
+```bash
+dotnet tool install --global Rnwood.Dataverse.Data.PowerShell.McpServer
+```
+
+To update to the latest version:
+```bash
+dotnet tool update --global Rnwood.Dataverse.Data.PowerShell.McpServer
+```
+
+To uninstall:
+```bash
+dotnet tool uninstall --global Rnwood.Dataverse.Data.PowerShell.McpServer
+```
+
+### From Source
+
+```bash
+dotnet build Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj
+```
+
+## Running
+
+The server requires specifying allowed Dataverse URLs and supports several command-line options:
+
+### Required Options
+
+- `-u, --allowed-urls ...` - List of allowed Dataverse URLs for connections. Connections can only be made to these URLs. The server will auto-connect to the first URL on session creation.
+
+### Optional Flags
+
+- `--help` - Display help information
+
+### Examples
+
+**Basic usage (auto-connect to first URL):**
+```bash
+rnwood-dataverse-mcp --allowed-urls https://myorg.crm.dynamics.com
+```
+
+**Multiple allowed URLs:**
+```bash
+rnwood-dataverse-mcp --allowed-urls https://dev.crm.dynamics.com https://prod.crm.dynamics.com
+```
+
+## URL Restrictions and Auto-Connection
+
+### How it Works
+
+1. **URL Allowlist**: The server wraps the `Get-DataverseConnection` cmdlet to enforce the list of allowed URLs. Any attempt to connect to a URL not in the allowlist will fail with an error message.
+
+2. **Auto-Connection**: On session creation, the server automatically creates an interactive connection to the first allowed URL and sets it as the default.
+
+## Claude Desktop Integration
+
+Configure the server in Claude Desktop's `claude_desktop_config.json`:
+
+### Using `dnx` (Recommended - No Installation Required)
+
+**Basic configuration:**
+```json
+{
+ "mcpServers": {
+ "dataverse-powershell": {
+ "command": "dnx",
+ "args": [
+ "rnwood-dataverse-mcp",
+ "--allowed-urls",
+ "https://myorg.crm.dynamics.com"
+ ]
+ }
+ }
+}
+```
+
+**With multiple environments:**
+```json
+{
+ "mcpServers": {
+ "dataverse-powershell": {
+ "command": "dnx",
+ "args": [
+ "rnwood-dataverse-mcp",
+ "--allowed-urls",
+ "https://dev.crm.dynamics.com",
+ "https://test.crm.dynamics.com",
+ "https://prod.crm.dynamics.com"
+ ]
+ }
+ }
+}
+```
+
+### Using Global Tool (Alternative)
+
+If you prefer to install the tool globally first:
+
+```bash
+dotnet tool install --global Rnwood.Dataverse.Data.PowerShell.McpServer
+```
+
+Then configure:
+```json
+{
+ "mcpServers": {
+ "dataverse-powershell": {
+ "command": "rnwood-dataverse-mcp",
+ "args": [
+ "--allowed-urls",
+ "https://myorg.crm.dynamics.com"
+ ]
+ }
+ }
+}
+```
+
+## Available MCP Tools
+
+The server exposes the following MCP tools:
+
+### GetCmdletList
+
+Returns a list of all available Dataverse cmdlets with their synopsis.
+
+**Returns:** JSON array of cmdlets with name and synopsis
+
+### GetCmdletHelp
+
+Returns detailed help for a specific cmdlet including description, parameters, and examples.
+
+**Parameters:**
+- `cmdletName` (string) - Name of the cmdlet
+
+**Returns:** JSON object with detailed help information
+
+### CreateSession
+
+Creates a new persistent PowerShell session with the Dataverse module pre-loaded and auto-connects to the first allowed URL.
+
+**Returns:** Session ID (string)
+
+**Notes:**
+- Session is initialized with `$connection` variable containing the default connection
+- Variables and state persist across script executions within the session
+
+### RunScriptInSession
+
+Executes a PowerShell script in an existing session.
+
+**Parameters:**
+- `sessionId` (string) - Session ID from CreateSession
+- `script` (string) - PowerShell script to execute
+
+**Returns:** Script execution ID (string)
+
+**Notes:**
+- Script runs asynchronously
+- Use GetScriptOutput to retrieve results
+
+### GetScriptOutput
+
+Retrieves output from a script execution.
+
+**Parameters:**
+- `sessionId` (string) - Session ID
+- `scriptExecutionId` (string) - Script execution ID from RunScriptInSession
+- `onlyNew` (boolean) - If true, returns only output since last call; if false, returns all output
+
+**Returns:** JSON object with:
+- `isComplete` (boolean) - Whether script execution has finished
+- `output` (string) - Script output
+- `error` (string) - Error output if any
+
+### EndSession
+
+Closes and cleans up a persistent session.
+
+**Parameters:**
+- `sessionId` (string) - Session ID to end
diff --git a/Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj b/Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj
new file mode 100644
index 000000000..e05fa52d6
--- /dev/null
+++ b/Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj
@@ -0,0 +1,53 @@
+
+
+ Exe
+ net8.0
+ Rnwood.Dataverse.Data.PowerShell.McpServer
+ Rnwood.Dataverse.Data.PowerShell
+ Copyright © 2023-2024
+ false
+ 1701;1702
+
+
+ true
+ rnwood-dataverse-mcp
+ Rnwood.Dataverse.Data.PowerShell.McpServer
+ 1.0.0
+ Robert Wood
+ Model Context Protocol (MCP) server for PowerShell with Dataverse module. Execute PowerShell scripts with the Dataverse Data PowerShell module pre-loaded, with configurable security controls and persistent session support.
+ https://github.com/rnwood/Rnwood.Dataverse.Data.PowerShell
+ https://github.com/rnwood/Rnwood.Dataverse.Data.PowerShell
+ MIT
+ dataverse;powershell;mcp;model-context-protocol;dynamics365;powerplatform
+ README.md
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ runtime
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Rnwood.Dataverse.Data.PowerShell.McpServer/Tools/PowerShellExecutor.cs b/Rnwood.Dataverse.Data.PowerShell.McpServer/Tools/PowerShellExecutor.cs
new file mode 100644
index 000000000..999b856e1
--- /dev/null
+++ b/Rnwood.Dataverse.Data.PowerShell.McpServer/Tools/PowerShellExecutor.cs
@@ -0,0 +1,528 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Rnwood.Dataverse.Data.PowerShell.McpServer.Tools;
+
+public class PowerShellExecutorConfig
+{
+ public string[] AllowedUrls { get; set; } = Array.Empty();
+}
+
+public class PowerShellExecutor : IDisposable
+{
+ private readonly ConcurrentDictionary _sessions = new();
+ private readonly string _modulePath;
+ private readonly PowerShellExecutorConfig _config;
+ private bool _isInitialized;
+ private readonly object _initLock = new();
+
+ public PowerShellExecutor(PowerShellExecutorConfig config)
+ {
+ _config = config;
+
+ // Find the module path - try multiple locations
+ var assemblyDir = Path.GetDirectoryName(typeof(PowerShellExecutor).Assembly.Location)!;
+
+ // Try packaged module directory first (for global tool)
+ _modulePath = Path.Combine(assemblyDir, "module");
+
+ // If not found, try development path (from bin/Debug/net8.0)
+ if (!Directory.Exists(_modulePath) || !File.Exists(Path.Combine(_modulePath, "Rnwood.Dataverse.Data.PowerShell.psd1")))
+ {
+ // From: Rnwood.Dataverse.Data.PowerShell.McpServer\bin\Debug\net8.0
+ // To: Rnwood.Dataverse.Data.PowerShell\bin\Debug\netstandard2.0
+ // Need to go up 4 levels to solution root
+ _modulePath = Path.Combine(assemblyDir, "..", "..", "..", "..", "Rnwood.Dataverse.Data.PowerShell", "bin", "Debug", "netstandard2.0");
+ _modulePath = Path.GetFullPath(_modulePath);
+ }
+
+ // If that doesn't exist, try Release build
+ if (!Directory.Exists(_modulePath) || !File.Exists(Path.Combine(_modulePath, "Rnwood.Dataverse.Data.PowerShell.psd1")))
+ {
+ _modulePath = Path.Combine(assemblyDir, "..", "..", "..", "..", "Rnwood.Dataverse.Data.PowerShell", "bin", "Release", "netstandard2.0");
+ _modulePath = Path.GetFullPath(_modulePath);
+ }
+
+ // If still not found, check environment variable
+ if (!Directory.Exists(_modulePath) || !File.Exists(Path.Combine(_modulePath, "Rnwood.Dataverse.Data.PowerShell.psd1")))
+ {
+ var envPath = Environment.GetEnvironmentVariable("DATAVERSE_MODULE_PATH");
+ if (!string.IsNullOrEmpty(envPath))
+ {
+ _modulePath = envPath;
+ }
+ }
+ }
+
+ private void EnsureInitialized()
+ {
+ if (_isInitialized) return;
+
+ lock (_initLock)
+ {
+ if (_isInitialized) return;
+
+ // Validate allowed URLs were provided
+ if (_config.AllowedUrls == null || _config.AllowedUrls.Length == 0)
+ {
+ throw new InvalidOperationException("No allowed URLs specified. Use --allowed-urls parameter to specify allowed Dataverse URLs.");
+ }
+
+ _isInitialized = true;
+ }
+ }
+
+ public string GetCmdletList()
+ {
+ EnsureInitialized();
+
+ var moduleManifestPath = Path.Combine(_modulePath, "Rnwood.Dataverse.Data.PowerShell.psd1");
+
+ if (!File.Exists(moduleManifestPath))
+ {
+ throw new InvalidOperationException($"Module manifest not found at: {moduleManifestPath}");
+ }
+
+ var script = $@"
+Import-Module '{moduleManifestPath}'
+Get-Command -Module Rnwood.Dataverse.Data.PowerShell | ForEach-Object {{
+ $help = Get-Help $_.Name -ErrorAction SilentlyContinue
+ [PSCustomObject]@{{
+ Name = $_.Name
+ Synopsis = if ($help.Synopsis) {{ $help.Synopsis.Trim() }} else {{ '' }}
+ }}
+}} | ConvertTo-Json
+";
+
+ using var runspace = RunspaceFactory.CreateRunspace();
+ runspace.Open();
+ using var ps = System.Management.Automation.PowerShell.Create();
+ ps.Runspace = runspace;
+ ps.AddScript(script);
+
+ var results = ps.Invoke();
+ if (ps.HadErrors)
+ {
+ var errors = string.Join("\n", ps.Streams.Error.Select(e => e.ToString()));
+ throw new InvalidOperationException($"Failed to get cmdlet list: {errors}");
+ }
+
+ return results.FirstOrDefault()?.ToString() ?? "[]";
+ }
+
+ public string GetCmdletHelp(string cmdletName)
+ {
+ EnsureInitialized();
+
+ var moduleManifestPath = Path.Combine(_modulePath, "Rnwood.Dataverse.Data.PowerShell.psd1");
+
+ if (!File.Exists(moduleManifestPath))
+ {
+ throw new InvalidOperationException($"Module manifest not found at: {moduleManifestPath}");
+ }
+
+ var script = $@"
+Import-Module '{moduleManifestPath}'
+$help = Get-Help '{cmdletName}' -Full -ErrorAction Stop
+$helpObj = [PSCustomObject]@{{
+ Name = $help.Name
+ Synopsis = $help.Synopsis
+ Description = ($help.Description | ForEach-Object {{ $_.Text }}) -join ""`n""
+ Syntax = ($help.Syntax.syntaxItem | ForEach-Object {{ $_.name + ' ' + (($_.parameter | ForEach-Object {{ '-' + $_.name + ' <' + $_.type.name + '>' }}) -join ' ') }}) -join ""`n""
+ Parameters = @($help.parameters.parameter | ForEach-Object {{
+ [PSCustomObject]@{{
+ Name = $_.name
+ Type = $_.type.name
+ Required = $_.required
+ Description = ($_.description | ForEach-Object {{ $_.Text }}) -join ' '
+ }}
+ }})
+ Examples = @($help.examples.example | ForEach-Object {{
+ [PSCustomObject]@{{
+ Title = $_.title
+ Code = $_.code
+ Remarks = ($_.remarks | ForEach-Object {{ $_.Text }}) -join ""`n""
+ }}
+ }})
+}}
+$helpObj | ConvertTo-Json -Depth 10
+";
+
+ using var runspace = RunspaceFactory.CreateRunspace();
+ runspace.Open();
+ using var ps = System.Management.Automation.PowerShell.Create();
+ ps.Runspace = runspace;
+ ps.AddScript(script);
+
+ var results = ps.Invoke();
+ if (ps.HadErrors)
+ {
+ var errors = string.Join("\n", ps.Streams.Error.Select(e => e.ToString()));
+ throw new InvalidOperationException($"Failed to get help for cmdlet '{cmdletName}': {errors}");
+ }
+
+ return results.FirstOrDefault()?.ToString() ?? "{}";
+ }
+
+ public string CreateSession()
+ {
+ EnsureInitialized();
+
+ var sessionId = Guid.NewGuid().ToString("N");
+ var session = new PersistentSession(sessionId, _modulePath, _config);
+
+ if (!_sessions.TryAdd(sessionId, session))
+ {
+ throw new InvalidOperationException($"Session {sessionId} already exists");
+ }
+
+ session.Initialize();
+ return sessionId;
+ }
+
+ public string RunScriptInSession(string sessionId, string script)
+ {
+ if (!_sessions.TryGetValue(sessionId, out var session))
+ {
+ throw new ArgumentException($"Session {sessionId} not found", nameof(sessionId));
+ }
+
+ return session.RunScript(script);
+ }
+
+ public ScriptOutputResult GetScriptOutput(string sessionId, string scriptExecutionId, bool onlyNew)
+ {
+ if (!_sessions.TryGetValue(sessionId, out var session))
+ {
+ throw new ArgumentException($"Session {sessionId} not found", nameof(sessionId));
+ }
+
+ return session.GetScriptOutput(scriptExecutionId, onlyNew);
+ }
+
+ public void EndSession(string sessionId)
+ {
+ if (_sessions.TryRemove(sessionId, out var session))
+ {
+ session.Dispose();
+ }
+ else
+ {
+ throw new ArgumentException($"Session {sessionId} not found", nameof(sessionId));
+ }
+ }
+
+ public void Dispose()
+ {
+ foreach (var session in _sessions.Values)
+ {
+ session.Dispose();
+ }
+ _sessions.Clear();
+ }
+}
+
+
+
+public class PersistentSession : IDisposable
+{
+ private readonly string _sessionId;
+ private readonly string _modulePath;
+ private readonly PowerShellExecutorConfig _config;
+ private Runspace? _runspace;
+ private readonly ConcurrentDictionary _scriptExecutions = new();
+ private readonly object _lock = new();
+ private bool _isDisposed;
+
+ public PersistentSession(string sessionId, string modulePath, PowerShellExecutorConfig config)
+ {
+ _sessionId = sessionId;
+ _modulePath = modulePath;
+ _config = config;
+ }
+
+ public void Initialize()
+ {
+ lock (_lock)
+ {
+ if (_runspace != null)
+ {
+ throw new InvalidOperationException("Session already initialized");
+ }
+
+ // Create initial session state - always use default to ensure module can load
+ var iss = InitialSessionState.CreateDefault();
+
+ // Always use FullLanguage mode - the module requires ability to import .ps1 files
+ // Security is enforced through allowed URL restrictions instead of language mode
+ iss.LanguageMode = PSLanguageMode.FullLanguage;
+
+ _runspace = RunspaceFactory.CreateRunspace(iss);
+ _runspace.Open();
+
+ // Import the Dataverse module
+ using (var ps = System.Management.Automation.PowerShell.Create())
+ {
+ ps.Runspace = _runspace;
+ var moduleManifestPath = Path.Combine(_modulePath, "Rnwood.Dataverse.Data.PowerShell.psd1");
+
+ if (!File.Exists(moduleManifestPath))
+ {
+ throw new InvalidOperationException($"Module manifest not found at: {moduleManifestPath}");
+ }
+
+ ps.AddCommand("Import-Module").AddParameter("Name", moduleManifestPath);
+ ps.Invoke();
+
+ if (ps.HadErrors)
+ {
+ var errors = string.Join("\n", ps.Streams.Error.Select(e => e.ToString()));
+ throw new InvalidOperationException($"Failed to import module from {moduleManifestPath}: {errors}");
+ }
+ }
+
+
+ // Set the allowed URLs as a session variable that scripts can reference
+ var allowedUrlsList = string.Join("', '", _config.AllowedUrls);
+ var firstAllowedUrl = _config.AllowedUrls.FirstOrDefault() ?? "";
+
+ using (var ps2 = System.Management.Automation.PowerShell.Create())
+ {
+ ps2.Runspace = _runspace;
+ ps2.AddScript($"$Global:AllowedDataverseUrls = @('{allowedUrlsList}')");
+ ps2.AddScript($"$Global:DefaultDataverseUrl = '{firstAllowedUrl}'");
+ ps2.Invoke();
+
+ if (ps2.HadErrors)
+ {
+ var errors = string.Join("\n", ps2.Streams.Error.Select(e => e.ToString()));
+ throw new InvalidOperationException($"Failed to initialize session variables: {errors}");
+ }
+ }
+
+ // Automatically establish Dataverse connection
+ using (var ps3 = System.Management.Automation.PowerShell.Create())
+ {
+ ps3.Runspace = _runspace;
+ ps3.AddCommand("Get-DataverseConnection")
+ .AddParameter("Interactive", true)
+ .AddParameter("SetAsDefault", true)
+ .AddParameter("Url", firstAllowedUrl);
+ ps3.Invoke();
+
+ if (ps3.HadErrors)
+ {
+ var errors = string.Join("\n", ps3.Streams.Error.Select(e => e.ToString()));
+ throw new InvalidOperationException($"Failed to establish Dataverse connection: {errors}");
+ }
+ }
+ }
+ }
+
+ public string RunScript(string script)
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException("Session has been disposed");
+ }
+
+ var executionId = Guid.NewGuid().ToString("N");
+ var execution = new ScriptExecution(executionId, script, _runspace!);
+
+ if (!_scriptExecutions.TryAdd(executionId, execution))
+ {
+ throw new InvalidOperationException($"Script execution {executionId} already exists");
+ }
+
+ execution.Start();
+ return executionId;
+ }
+
+ public ScriptOutputResult GetScriptOutput(string scriptExecutionId, bool onlyNew)
+ {
+ if (!_scriptExecutions.TryGetValue(scriptExecutionId, out var execution))
+ {
+ throw new ArgumentException($"Script execution {scriptExecutionId} not found", nameof(scriptExecutionId));
+ }
+
+ return execution.GetOutput(onlyNew);
+ }
+
+ public void Dispose()
+ {
+ lock (_lock)
+ {
+ if (_isDisposed) return;
+
+ _isDisposed = true;
+
+ foreach (var execution in _scriptExecutions.Values)
+ {
+ execution.Dispose();
+ }
+ _scriptExecutions.Clear();
+
+ _runspace?.Dispose();
+ _runspace = null;
+ }
+ }
+}
+
+public class ScriptExecution : IDisposable
+{
+ private readonly string _executionId;
+ private readonly string _script;
+ private readonly Runspace _runspace;
+ private System.Management.Automation.PowerShell? _powerShell;
+ private readonly StringBuilder _output = new();
+ private readonly StringBuilder _error = new();
+ private int _lastReadPosition;
+ private bool _isComplete;
+ private Exception? _exception;
+ private readonly object _lock = new();
+
+ public ScriptExecution(string executionId, string script, Runspace runspace)
+ {
+ _executionId = executionId;
+ _script = script;
+ _runspace = runspace;
+ }
+
+ public void Start()
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ ExecuteScript();
+ }
+ catch (Exception ex)
+ {
+ lock (_lock)
+ {
+ _exception = ex;
+ _error.AppendLine($"ERROR: {ex.Message}");
+ _isComplete = true;
+ }
+ }
+ });
+ }
+
+ private void ExecuteScript()
+ {
+ _powerShell = System.Management.Automation.PowerShell.Create();
+ _powerShell.Runspace = _runspace;
+
+ // Execute the script
+ _powerShell.AddScript(_script);
+
+ var outputCollection = new PSDataCollection();
+ outputCollection.DataAdded += (sender, e) =>
+ {
+ if (sender is PSDataCollection collection && e.Index < collection.Count)
+ {
+ lock (_lock)
+ {
+ _output.AppendLine(collection[e.Index]?.ToString() ?? "");
+ }
+ }
+ };
+
+ _powerShell.Streams.Error.DataAdded += (sender, e) =>
+ {
+ if (sender is PSDataCollection collection && e.Index < collection.Count)
+ {
+ lock (_lock)
+ {
+ _error.AppendLine($"ERROR: {collection[e.Index]}");
+ }
+ }
+ };
+
+ _powerShell.Streams.Warning.DataAdded += (sender, e) =>
+ {
+ if (sender is PSDataCollection collection && e.Index < collection.Count)
+ {
+ lock (_lock)
+ {
+ _output.AppendLine($"WARNING: {collection[e.Index]}");
+ }
+ }
+ };
+
+ _powerShell.Streams.Verbose.DataAdded += (sender, e) =>
+ {
+ if (sender is PSDataCollection collection && e.Index < collection.Count)
+ {
+ lock (_lock)
+ {
+ _output.AppendLine($"VERBOSE: {collection[e.Index]}");
+ }
+ }
+ };
+
+ try
+ {
+ _powerShell.Invoke(null, outputCollection);
+ }
+ finally
+ {
+ lock (_lock)
+ {
+ _isComplete = true;
+ }
+ }
+ }
+
+ public ScriptOutputResult GetOutput(bool onlyNew)
+ {
+ lock (_lock)
+ {
+ var fullOutput = _output.ToString() + _error.ToString();
+
+ if (onlyNew)
+ {
+ var newContent = fullOutput.Substring(Math.Min(_lastReadPosition, fullOutput.Length));
+ _lastReadPosition = fullOutput.Length;
+
+ return new ScriptOutputResult
+ {
+ SessionId = _executionId,
+ Output = newContent,
+ IsComplete = _isComplete,
+ HasError = _exception != null || _error.Length > 0
+ };
+ }
+ else
+ {
+ return new ScriptOutputResult
+ {
+ SessionId = _executionId,
+ Output = fullOutput,
+ IsComplete = _isComplete,
+ HasError = _exception != null || _error.Length > 0
+ };
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ _powerShell?.Dispose();
+ }
+}
+
+public class ScriptOutputResult
+{
+ public required string SessionId { get; init; }
+ public required string Output { get; init; }
+ public required bool IsComplete { get; init; }
+ public required bool HasError { get; init; }
+}
diff --git a/Rnwood.Dataverse.Data.PowerShell.McpServer/Tools/PowerShellTools.cs b/Rnwood.Dataverse.Data.PowerShell.McpServer/Tools/PowerShellTools.cs
new file mode 100644
index 000000000..dccd5b549
--- /dev/null
+++ b/Rnwood.Dataverse.Data.PowerShell.McpServer/Tools/PowerShellTools.cs
@@ -0,0 +1,117 @@
+using ModelContextProtocol;
+using ModelContextProtocol.Server;
+using System.ComponentModel;
+using System.Text.Json;
+
+namespace Rnwood.Dataverse.Data.PowerShell.McpServer.Tools;
+
+[McpServerToolType]
+public class PowerShellTools
+{
+ private readonly PowerShellExecutor _executor;
+
+ public PowerShellTools(PowerShellExecutor executor)
+ {
+ _executor = executor;
+ }
+
+ [McpServerTool, Description("Get a list of all available Dataverse PowerShell cmdlets with their synopsis.")]
+ public string GetCmdletList()
+ {
+ return _executor.GetCmdletList();
+ }
+
+ [McpServerTool, Description("Get detailed help information for a specific Dataverse PowerShell cmdlet.")]
+ public string GetCmdletHelp(
+ [Description("The name of the cmdlet to get help for (e.g., 'Get-DataverseRecord')")] string cmdletName)
+ {
+ if (string.IsNullOrWhiteSpace(cmdletName))
+ {
+ throw new McpException("Cmdlet name cannot be empty");
+ }
+
+ return _executor.GetCmdletHelp(cmdletName);
+ }
+
+ [McpServerTool, Description("Create a new persistent PowerShell session with the Dataverse module pre-loaded. Returns a session ID.")]
+ public string CreateSession()
+ {
+ var sessionId = _executor.CreateSession();
+ return JsonSerializer.Serialize(new
+ {
+ sessionId,
+ message = "Session created. Use RunScriptInSession to execute scripts in this session."
+ });
+ }
+
+ [McpServerTool, Description("Run a PowerShell script in an existing session. The session persists between script executions, maintaining variables and state.")]
+ public string RunScriptInSession(
+ [Description("The session ID returned from CreateSession")] string sessionId,
+ [Description("The PowerShell script to execute in the session")] string script)
+ {
+ if (string.IsNullOrWhiteSpace(sessionId))
+ {
+ throw new McpException("SessionId cannot be empty");
+ }
+
+ if (string.IsNullOrWhiteSpace(script))
+ {
+ throw new McpException("Script cannot be empty");
+ }
+
+ var scriptExecutionId = _executor.RunScriptInSession(sessionId, script);
+ return JsonSerializer.Serialize(new
+ {
+ sessionId,
+ scriptExecutionId,
+ message = "Script execution started. Use GetScriptOutput to retrieve results."
+ });
+ }
+
+ [McpServerTool, Description("Get the output from a script execution within a session.")]
+ public string GetScriptOutput(
+ [Description("The session ID")] string sessionId,
+ [Description("The script execution ID returned from RunScriptInSession")] string scriptExecutionId,
+ [Description("If true, only return new output since the last call. If false, return all output.")] bool onlyNew = false)
+ {
+ if (string.IsNullOrWhiteSpace(sessionId))
+ {
+ throw new McpException("SessionId cannot be empty");
+ }
+
+ if (string.IsNullOrWhiteSpace(scriptExecutionId))
+ {
+ throw new McpException("ScriptExecutionId cannot be empty");
+ }
+
+ var result = _executor.GetScriptOutput(sessionId, scriptExecutionId, onlyNew);
+ return JsonSerializer.Serialize(new
+ {
+ sessionId,
+ scriptExecutionId = result.SessionId,
+ result.Output,
+ result.IsComplete,
+ result.HasError,
+ message = result.IsComplete
+ ? (result.HasError ? "Script completed with errors" : "Script completed successfully")
+ : "Script is still running"
+ }, new JsonSerializerOptions { WriteIndented = true });
+ }
+
+ [McpServerTool, Description("End a PowerShell session and release all associated resources.")]
+ public string EndSession(
+ [Description("The session ID to end")] string sessionId)
+ {
+ if (string.IsNullOrWhiteSpace(sessionId))
+ {
+ throw new McpException("SessionId cannot be empty");
+ }
+
+ _executor.EndSession(sessionId);
+ return JsonSerializer.Serialize(new
+ {
+ sessionId,
+ message = "Session ended successfully."
+ });
+ }
+}
diff --git a/Rnwood.Dataverse.Data.PowerShell.sln b/Rnwood.Dataverse.Data.PowerShell.sln
index 783671b8f..d41d216c0 100644
--- a/Rnwood.Dataverse.Data.PowerShell.sln
+++ b/Rnwood.Dataverse.Data.PowerShell.sln
@@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rnwood.Dataverse.Data.Power
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rnwood.Dataverse.Data.PowerShell.XrmToolboxPluginHost", "Rnwood.Dataverse.Data.PowerShell.XrmToolboxPluginHost\Rnwood.Dataverse.Data.PowerShell.XrmToolboxPluginHost.csproj", "{4F386F2D-2162-467E-8068-D03C80F8BE1A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rnwood.Dataverse.Data.PowerShell.McpServer", "Rnwood.Dataverse.Data.PowerShell.McpServer\Rnwood.Dataverse.Data.PowerShell.McpServer.csproj", "{3815D2DC-CBEC-4ABF-9029-EFE14E765A50}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -97,6 +99,18 @@ Global
{4F386F2D-2162-467E-8068-D03C80F8BE1A}.Release|x64.Build.0 = Release|Any CPU
{4F386F2D-2162-467E-8068-D03C80F8BE1A}.Release|x86.ActiveCfg = Release|Any CPU
{4F386F2D-2162-467E-8068-D03C80F8BE1A}.Release|x86.Build.0 = Release|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Debug|x64.Build.0 = Debug|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Debug|x86.Build.0 = Debug|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Release|x64.ActiveCfg = Release|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Release|x64.Build.0 = Release|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Release|x86.ActiveCfg = Release|Any CPU
+ {3815D2DC-CBEC-4ABF-9029-EFE14E765A50}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Compare-DataverseSolutionComponents.md b/Rnwood.Dataverse.Data.PowerShell/docs/Compare-DataverseSolutionComponents.md
index 20a1a4801..12135ce58 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Compare-DataverseSolutionComponents.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Compare-DataverseSolutionComponents.md
@@ -26,13 +26,13 @@ Compare-DataverseSolutionComponents [-Connection ] -SolutionBytes
### FileToFile
```
-Compare-DataverseSolutionComponents [-SolutionFile] [-FileToFile] [-TargetSolutionFile]
+Compare-DataverseSolutionComponents [-SolutionFile] [-FileToFile] -TargetSolutionFile
[-TestIfAdditive] [-ProgressAction ] []
```
### BytesToFile
```
-Compare-DataverseSolutionComponents -SolutionBytes [-BytesToFile] [-TargetSolutionFile]
+Compare-DataverseSolutionComponents -SolutionBytes [-BytesToFile] -TargetSolutionFile
[-TestIfAdditive] [-ProgressAction ] []
```
@@ -297,7 +297,7 @@ Parameter Sets: FileToFile, BytesToFile
Aliases:
Required: True
-Position: 1
+Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Compress-DataverseSolutionFile.md b/Rnwood.Dataverse.Data.PowerShell/docs/Compress-DataverseSolutionFile.md
index 43bd476f8..bb76e8a5e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Compress-DataverseSolutionFile.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Compress-DataverseSolutionFile.md
@@ -137,6 +137,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Expand-DataverseSolutionFile.md b/Rnwood.Dataverse.Data.PowerShell/docs/Expand-DataverseSolutionFile.md
index 994450139..93e7b5989 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Expand-DataverseSolutionFile.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Expand-DataverseSolutionFile.md
@@ -160,6 +160,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Export-DataverseSolution.md b/Rnwood.Dataverse.Data.PowerShell/docs/Export-DataverseSolution.md
index c49806958..72d44e55f 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Export-DataverseSolution.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Export-DataverseSolution.md
@@ -324,7 +324,6 @@ Package type: 'Unmanaged', 'Managed', or 'Both' (default) for dual Managed and U
Type: SolutionPackageType
Parameter Sets: ToFolder
Aliases:
-Accepted values: Unmanaged, Managed, Both
Required: False
Position: Named
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModule.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModule.md
index 49f4fa7bd..b3efe86cf 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModule.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModule.md
@@ -207,10 +207,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Default Behavior:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModuleComponent.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModuleComponent.md
index 26c1eb819..c5762ee97 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModuleComponent.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAppModuleComponent.md
@@ -217,10 +217,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Component Types:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAttributeMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAttributeMetadata.md
index 31e53bed2..a29e5c6ef 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAttributeMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseAttributeMetadata.md
@@ -439,6 +439,4 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### Microsoft.Xrm.Sdk.Metadata.AttributeMetadata
## NOTES
-This cmdlet provides programmatic access to Dataverse metadata. For comprehensive documentation and examples, see the metadata concept guide at docs/core-concepts/metadata.md
-
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseComponentDependency.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseComponentDependency.md
index 1ed8af6c5..d81c87a36 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseComponentDependency.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseComponentDependency.md
@@ -215,10 +215,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.Int32
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- This cmdlet uses the RetrieveDependenciesForDeleteRequest SDK message (with -RequiredBy) or RetrieveDependentComponentsRequest SDK message (with -Dependent).
- The returned entities contain properties like dependentcomponentobjectid, dependentcomponenttype, requiredcomponentobjectid, and requiredcomponenttype.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseDynamicPluginAssembly.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseDynamicPluginAssembly.md
index 2c88c92cd..1dac2213a 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseDynamicPluginAssembly.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseDynamicPluginAssembly.md
@@ -149,9 +149,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Byte[]
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Output Properties:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityKeyMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityKeyMetadata.md
index 2f92c88b3..a5c290279 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityKeyMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityKeyMetadata.md
@@ -151,9 +151,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
## OUTPUTS
### Microsoft.Xrm.Sdk.Metadata.EntityKeyMetadata
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityMetadata.md
index 28f6fd504..dc2709e8e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEntityMetadata.md
@@ -445,6 +445,4 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### Microsoft.Xrm.Sdk.Metadata.EntityMetadata
## NOTES
-This cmdlet provides programmatic access to Dataverse metadata. For comprehensive documentation and examples, see the metadata concept guide at docs/core-concepts/metadata.md
-
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEnvironment.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEnvironment.md
index 10a77cdfa..e4c00d0c7 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEnvironment.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseEnvironment.md
@@ -269,9 +269,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### Microsoft.Xrm.Sdk.Discovery.OrganizationDetail
+
## NOTES
- This cmdlet requires an active internet connection to communicate with the Global Discovery Service.
- The authenticated user must have access to at least one Dataverse environment to receive results.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFileData.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFileData.md
index a7b6dee52..f928cd55c 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFileData.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFileData.md
@@ -212,11 +212,15 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### System.Byte[]
+
### System.IO.FileInfo
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseForm.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseForm.md
index ddde23ab6..9b2d60b68 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseForm.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseForm.md
@@ -267,9 +267,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Form Types Available:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormControl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormControl.md
index bb80f9ee2..207a302ed 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormControl.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormControl.md
@@ -252,9 +252,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Form Structure Hierarchy:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormEventHandler.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormEventHandler.md
index c80481318..bdae6d9c0 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormEventHandler.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormEventHandler.md
@@ -317,9 +317,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Event Location Types:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormLibrary.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormLibrary.md
index d4f9b8e86..baca7b7be 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormLibrary.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormLibrary.md
@@ -172,9 +172,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
Form libraries must reference valid web resources of type Script (JScript). The web resource should exist in the environment before being added to a form.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormSection.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormSection.md
index 88491fe47..6c3a7117c 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormSection.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormSection.md
@@ -163,9 +163,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Form Structure Hierarchy:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormTab.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormTab.md
index cec94ac4e..19a6de303 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormTab.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseFormTab.md
@@ -138,9 +138,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Form Structure Hierarchy:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseIconSetIcon.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseIconSetIcon.md
index 0ceb66322..063141a7c 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseIconSetIcon.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseIconSetIcon.md
@@ -137,9 +137,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
This cmdlet requires internet access to retrieve the icon list from the online repository. The icon list is retrieved fresh each time the cmdlet is run.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOptionSetMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOptionSetMetadata.md
index 14f76f18c..0082b5e86 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOptionSetMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOptionSetMetadata.md
@@ -403,6 +403,4 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### Microsoft.Xrm.Sdk.Metadata.OptionSetMetadataBase
## NOTES
-This cmdlet provides programmatic access to Dataverse metadata. For comprehensive documentation and examples, see the metadata concept guide at docs/core-concepts/metadata.md
-
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOrganizationSettings.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOrganizationSettings.md
index efd1c8b5e..06d906f79 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOrganizationSettings.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseOrganizationSettings.md
@@ -130,9 +130,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginAssembly.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginAssembly.md
index 6af20a81f..93050c909 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginAssembly.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginAssembly.md
@@ -127,9 +127,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginPackage.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginPackage.md
index 1a58a30fd..79521d0dc 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginPackage.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginPackage.md
@@ -111,9 +111,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStep.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStep.md
index 638616ed5..73a1c995e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStep.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStep.md
@@ -144,9 +144,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStepImage.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStepImage.md
index d5bc83df3..cfcf8c272 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStepImage.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginStepImage.md
@@ -144,9 +144,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginType.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginType.md
index 490a511b6..00bc038a4 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginType.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataversePluginType.md
@@ -144,9 +144,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecord.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecord.md
index 5670de040..14de94ae8 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecord.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecord.md
@@ -835,7 +835,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### System.Management.Automation.PSObject
## OUTPUTS
-### System.Collections.Generic.IEnumerable`1[[System.Management.Automation.PSObject, System.Management.Automation, Version=7.4.6.500, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]
+### System.Collections.Generic.IEnumerable`1[[System.Management.Automation.PSObject, System.Management.Automation, Version=7.5.0.500, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordAccess.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordAccess.md
index 318d4226f..1d43ed4d8 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordAccess.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseRecordAccess.md
@@ -141,10 +141,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### Microsoft.Crm.Sdk.Messages.PrincipalAccess
+
## NOTES
See https://learn.microsoft.com/en-us/dotnet/api/microsoft.crm.sdk.messages.retrievesharedprincipalsandaccessrequest?view=dataverse-sdk-latest
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemap.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemap.md
index 66761d441..7ce9fab6a 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemap.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemap.md
@@ -186,9 +186,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapInfo
+
## NOTES
This cmdlet requires an active connection to a Dataverse environment.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemapEntry.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemapEntry.md
index 25842bfd4..8fd017ec4 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemapEntry.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSitemapEntry.md
@@ -294,11 +294,15 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapInfo
+
### System.String
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapEntryInfo
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSolutionDependency.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSolutionDependency.md
index caa36dd53..bf99eb8ea 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSolutionDependency.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseSolutionDependency.md
@@ -238,10 +238,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- This cmdlet uses the RetrieveMissingDependenciesRequest SDK message (with -Missing) or RetrieveDependenciesForUninstallRequest SDK message (with -Uninstall).
- For -Missing mode: Returns entities with properties like missingcomponentid, missingcomponenttype, requiredcomponentid, and requiredcomponenttype.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseView.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseView.md
index 59fdc68f2..ab68660fa 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseView.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseView.md
@@ -244,10 +244,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Default Behavior:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseWebResource.md b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseWebResource.md
index 4166192a5..bc5515d6c 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseWebResource.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Get-DataverseWebResource.md
@@ -251,9 +251,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Import-DataverseSolution.md b/Rnwood.Dataverse.Data.PowerShell/docs/Import-DataverseSolution.md
index 06fb409e2..b5c1224f6 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Import-DataverseSolution.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Import-DataverseSolution.md
@@ -25,7 +25,7 @@ Import-DataverseSolution [-InFile] [-OverwriteUnmanagedCustomizations]
### FromFolder
```
-Import-DataverseSolution [-InFolder] [-PackageType ]
+Import-DataverseSolution -InFolder [-PackageType ]
[-OverwriteUnmanagedCustomizations] [-PublishWorkflows] [-SkipProductUpdateDependencies] [-Mode ]
[-ConnectionReferences ] [-EnvironmentVariables ] [-ConvertToManaged]
[-SkipQueueRibbonJob] [-LayerDesiredOrder ] [-AsyncRibbonProcessing]
@@ -347,7 +347,7 @@ Parameter Sets: FromFolder
Aliases:
Required: True
-Position: 0
+Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
@@ -406,7 +406,6 @@ Package type: 'Unmanaged' (default) or 'Managed'.
Type: ImportSolutionPackageType
Parameter Sets: FromFolder
Aliases:
-Accepted values: Unmanaged, Managed
Required: False
Position: Named
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSolutionUpgrade.md b/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSolutionUpgrade.md
index 003cc71c7..b9eeb0f63 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSolutionUpgrade.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSolutionUpgrade.md
@@ -263,6 +263,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSql.md b/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSql.md
index 9ac1ab675..7977fb692 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSql.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseSql.md
@@ -372,7 +372,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
-### System.String
### System.Management.Automation.PSObject
## OUTPUTS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseXrmToolbox.md b/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseXrmToolbox.md
index 9e03f3871..8c4944fa0 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseXrmToolbox.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Invoke-DataverseXrmToolbox.md
@@ -183,9 +183,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Void
+
## NOTES
**Important**: This cmdlet requires a .NET Framework 4.8 host process to run XrmToolbox plugins, as they are built for .NET Framework. The host process is automatically launched when you invoke a plugin.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModule.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModule.md
index 41c7ad0e0..dd8ea3d34 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModule.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModule.md
@@ -178,7 +178,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModuleComponent.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModuleComponent.md
index dbdbdbd30..d992c6b63 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModuleComponent.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseAppModuleComponent.md
@@ -255,7 +255,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseEntityKeyMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseEntityKeyMetadata.md
index 495a067c8..24155fc57 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseEntityKeyMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseEntityKeyMetadata.md
@@ -154,6 +154,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFileData.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFileData.md
index c19743635..0d9acf6bf 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFileData.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFileData.md
@@ -184,10 +184,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### System.Void
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseForm.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseForm.md
index cd2478faa..7d7c0fda4 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseForm.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseForm.md
@@ -240,6 +240,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormControl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormControl.md
index f92f95bf8..c93e31598 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormControl.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormControl.md
@@ -299,6 +299,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormEventHandler.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormEventHandler.md
index a33e8dce0..837f0e5fe 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormEventHandler.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormEventHandler.md
@@ -364,6 +364,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormLibrary.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormLibrary.md
index 6446d19a6..92ae871fb 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormLibrary.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormLibrary.md
@@ -179,6 +179,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormSection.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormSection.md
index a1334e02b..6c7d46a77 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormSection.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormSection.md
@@ -243,6 +243,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormTab.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormTab.md
index 8db39631f..aef6163ce 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormTab.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseFormTab.md
@@ -227,6 +227,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginAssembly.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginAssembly.md
index de992af46..66a82fc65 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginAssembly.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginAssembly.md
@@ -136,6 +136,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginPackage.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginPackage.md
index 7fc2ced83..60bfb9eab 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginPackage.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginPackage.md
@@ -128,6 +128,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStep.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStep.md
index b4536557c..a7e47e46e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStep.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStep.md
@@ -128,6 +128,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStepImage.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStepImage.md
index 979149035..ea8750ea4 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStepImage.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginStepImage.md
@@ -128,6 +128,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginType.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginType.md
index a7eaf0b69..789373481 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginType.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataversePluginType.md
@@ -128,6 +128,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseRecordAccess.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseRecordAccess.md
index bfda57ee3..4af02a0fe 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseRecordAccess.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseRecordAccess.md
@@ -200,7 +200,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemap.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemap.md
index 68ba9f3b7..8a38acaa7 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemap.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemap.md
@@ -231,7 +231,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemapEntry.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemapEntry.md
index 5b0bdbbb9..92c84f06b 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemapEntry.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSitemapEntry.md
@@ -339,9 +339,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapEntryInfo
+
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapInfo
+
### System.String
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSolutionComponent.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSolutionComponent.md
index 076a4c0c0..a743300a5 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSolutionComponent.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseSolutionComponent.md
@@ -224,7 +224,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.Int32
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseView.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseView.md
index 73adb48e9..05fc4895e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseView.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseView.md
@@ -208,7 +208,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseWebResource.md b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseWebResource.md
index 049ae25a0..c5085a6e1 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseWebResource.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Remove-DataverseWebResource.md
@@ -200,7 +200,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.Management.Automation.PSObject
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModule.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModule.md
index a80a5f583..622ef5b9c 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModule.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModule.md
@@ -419,14 +419,21 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
-### System.Nullable`1[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Int32, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
### System.Nullable`1[[Rnwood.Dataverse.Data.PowerShell.Commands.NavigationType, Rnwood.Dataverse.Data.PowerShell.Cmdlets, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
-### System.Nullable`1[[System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Boolean, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Guid
+
## NOTES
**Required Parameters:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModuleComponent.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModuleComponent.md
index e6659b4f9..412a92bc7 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModuleComponent.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppModuleComponent.md
@@ -355,13 +355,19 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
### System.Nullable`1[[Rnwood.Dataverse.Data.PowerShell.Commands.Model.AppModuleComponentType, Rnwood.Dataverse.Data.PowerShell.Cmdlets, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
+
### System.Nullable`1[[Rnwood.Dataverse.Data.PowerShell.Commands.Model.RootComponentBehavior, Rnwood.Dataverse.Data.PowerShell.Cmdlets, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
-### System.Nullable`1[[System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Boolean, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Guid
+
## NOTES
**Required Parameters for Creation:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppmoduleIconFromSet.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppmoduleIconFromSet.md
index d1976cf65..ade049569 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppmoduleIconFromSet.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAppmoduleIconFromSet.md
@@ -276,10 +276,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- This cmdlet requires internet access to download icons from the online icon set.
- The web resource is created in the format `{PublisherPrefix}_/icons/{IconSet}/{IconName}.svg`.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAttributeMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAttributeMetadata.md
index 650724868..616c9ac3f 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAttributeMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseAttributeMetadata.md
@@ -423,7 +423,6 @@ Cascade behavior for Assign: NoCascade, Cascade, Active, UserOwned, RemoveLink (
Type: String
Parameter Sets: (All)
Aliases:
-Accepted values: NoCascade, Cascade, Active, UserOwned, RemoveLink
Required: False
Position: Named
@@ -439,7 +438,6 @@ Cascade behavior for Delete: NoCascade, RemoveLink, Restrict, Cascade (Lookup on
Type: String
Parameter Sets: (All)
Aliases:
-Accepted values: NoCascade, RemoveLink, Restrict, Cascade
Required: False
Position: Named
@@ -455,7 +453,6 @@ Cascade behavior for Merge: NoCascade, Cascade (Lookup only)
Type: String
Parameter Sets: (All)
Aliases:
-Accepted values: NoCascade, Cascade
Required: False
Position: Named
@@ -471,7 +468,6 @@ Cascade behavior for Reparent: NoCascade, Cascade, Active, UserOwned, RemoveLink
Type: String
Parameter Sets: (All)
Aliases:
-Accepted values: NoCascade, Cascade, Active, UserOwned, RemoveLink
Required: False
Position: Named
@@ -487,7 +483,6 @@ Cascade behavior for Share: NoCascade, Cascade, Active, UserOwned (Lookup only)
Type: String
Parameter Sets: (All)
Aliases:
-Accepted values: NoCascade, Cascade, Active, UserOwned
Required: False
Position: Named
@@ -503,7 +498,6 @@ Cascade behavior for Unshare: NoCascade, Cascade, Active, UserOwned (Lookup only
Type: String
Parameter Sets: (All)
Aliases:
-Accepted values: NoCascade, Cascade, Active, UserOwned
Required: False
Position: Named
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseDynamicPluginAssembly.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseDynamicPluginAssembly.md
index a008bee53..97f08465e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseDynamicPluginAssembly.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseDynamicPluginAssembly.md
@@ -380,9 +380,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- Source code must contain at least one class implementing `Microsoft.Xrm.Sdk.IPlugin`, otherwise an error is thrown
- Plugin types are automatically created/removed based on classes implementing `IPlugin`
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityKeyMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityKeyMetadata.md
index a41cb2999..267eae385 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityKeyMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityKeyMetadata.md
@@ -241,9 +241,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- Alternate keys cannot be updated after creation. To modify a key, delete it first and then create a new one.
- Publishing is required for the key to become active, but can be done separately if needed.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityMetadata.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityMetadata.md
index 46be7c75c..25db380e4 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityMetadata.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseEntityMetadata.md
@@ -25,7 +25,7 @@ Set-DataverseEntityMetadata [-EntityName] [-SchemaName ] [-Disp
### ByEntityMetadata
```
-Set-DataverseEntityMetadata [-EntityMetadata] [-PassThru] [-Publish] [-SkipIconValidation]
+Set-DataverseEntityMetadata -EntityMetadata [-PassThru] [-Publish] [-SkipIconValidation]
[-Connection ] [-ProgressAction ] [-WhatIf] [-Confirm] []
```
@@ -537,7 +537,7 @@ Parameter Sets: ByEntityMetadata
Aliases:
Required: True
-Position: 0
+Position: Named
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFileData.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFileData.md
index ea78fe421..3fd723fdc 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFileData.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFileData.md
@@ -247,11 +247,15 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
### System.Byte[]
+
## OUTPUTS
### System.Void
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseForm.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseForm.md
index 377e9b72d..c3cbbe58e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseForm.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseForm.md
@@ -16999,3 +16999,207 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## NOTES
## RELATED LINKS
+
+
+```yaml
+Type: FormType
+Parameter Sets: Update, UpdateWithXml
+Aliases:
+Accepted values: Dashboard, AppointmentBook, Main, MiniCampaignBO, Preview, MobileExpress, QuickViewForm, QuickCreate, Dialog, TaskFlowForm, InteractionCentricDashboard, Card, MainInteractiveExperience, ContextualDashboard, Other, MainBackup, AppointmentBookBackup, PowerBIDashboard
+
+Required: False
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+```yaml
+Type: FormType
+Parameter Sets: Create, CreateWithXml
+Aliases:
+Accepted values: Dashboard, AppointmentBook, Main, MiniCampaignBO, Preview, MobileExpress, QuickViewForm, QuickCreate, Dialog, TaskFlowForm, InteractionCentricDashboard, Card, MainInteractiveExperience, ContextualDashboard, Other, MainBackup, AppointmentBookBackup, PowerBIDashboard
+
+Required: True
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+### -FormXmlContent
+Complete FormXml content
+
+```yaml
+Type: String
+Parameter Sets: UpdateWithXml, CreateWithXml
+Aliases: FormXml, Xml
+
+Required: True
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+### -Id
+ID of the form to update
+
+```yaml
+Type: Guid
+Parameter Sets: Update, UpdateWithXml
+Aliases: formid
+
+Required: True
+Position: Named
+Default value: None
+Accept pipeline input: True (ByPropertyName)
+Accept wildcard characters: False
+```
+
+### -IsActive
+Whether the form is active (default: true)
+
+```yaml
+Type: SwitchParameter
+Parameter Sets: (All)
+Aliases:
+
+Required: False
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+### -IsDefault
+Whether this form is the default form for the entity
+
+```yaml
+Type: SwitchParameter
+Parameter Sets: (All)
+Aliases:
+
+Required: False
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+### -Name
+Name of the form
+
+```yaml
+Type: String
+Parameter Sets: Update, UpdateWithXml
+Aliases:
+
+Required: False
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+```yaml
+Type: String
+Parameter Sets: Create, CreateWithXml
+Aliases:
+
+Required: True
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+### -PassThru
+Return the form ID after creation/update
+
+```yaml
+Type: SwitchParameter
+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
+```
+
+### -Publish
+Publish the form after creation/update
+
+```yaml
+Type: SwitchParameter
+Parameter Sets: (All)
+Aliases:
+
+Required: False
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+### -Confirm
+Prompts you for confirmation before running the cmdlet.
+
+```yaml
+Type: SwitchParameter
+Parameter Sets: (All)
+Aliases: cf
+
+Required: False
+Position: Named
+Default value: None
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
+### -WhatIf
+Shows what would happen if the cmdlet runs. The cmdlet is not run.
+
+```yaml
+Type: SwitchParameter
+Parameter Sets: (All)
+Aliases: wi
+
+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.Guid
+
+## OUTPUTS
+
+### System.Guid
+
+## NOTES
+
+## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormControl.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormControl.md
index 55aad2c23..59c28ba85 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormControl.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormControl.md
@@ -689,9 +689,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.String
+
## NOTES
**Control Types and Usage:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormEventHandler.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormEventHandler.md
index dda90a177..bfcd2af85 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormEventHandler.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormEventHandler.md
@@ -436,9 +436,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- The web resource must exist (published or unpublished) before adding a handler.
- If a handler with the same function name and library already exists, it will be updated.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormLibrary.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormLibrary.md
index aa3996e79..8a6701cf3 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormLibrary.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormLibrary.md
@@ -192,9 +192,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- The web resource must exist in the environment (published or unpublished) before adding it to a form.
- If the library already exists on the form, it will be updated with the new unique ID if provided.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormSection.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormSection.md
index 7102d094f..c0eb12fa7 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormSection.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormSection.md
@@ -465,9 +465,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.String
+
## NOTES
**Section Layout:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormTab.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormTab.md
index 6cbeb0221..fdbdefeef 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormTab.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseFormTab.md
@@ -427,9 +427,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
## OUTPUTS
### System.String
+
## NOTES
**Column Layout Management:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseOrganizationSettings.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseOrganizationSettings.md
index ac056306f..b9e23e8fe 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseOrganizationSettings.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseOrganizationSettings.md
@@ -223,9 +223,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Object
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
This cmdlet has a high confirm impact and will prompt for confirmation by default. Use -Confirm:$false to suppress the prompt.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginAssembly.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginAssembly.md
index be5a3732d..07b0de99e 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginAssembly.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginAssembly.md
@@ -292,10 +292,12 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginPackage.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginPackage.md
index b6b423055..de9b9f471 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginPackage.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginPackage.md
@@ -211,10 +211,12 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStep.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStep.md
index 13d3da38f..8a21cca44 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStep.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStep.md
@@ -370,10 +370,12 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStepImage.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStepImage.md
index 1af6e090a..f99f3d4b4 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStepImage.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginStepImage.md
@@ -235,10 +235,12 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginType.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginType.md
index 9dd3c4de1..77c67f596 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginType.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataversePluginType.md
@@ -218,10 +218,12 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecord.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecord.md
index 227968da4..f2157fd4b 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecord.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecord.md
@@ -998,7 +998,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
### System.Management.Automation.PSObject
### System.String
### System.Guid
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecordAccess.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecordAccess.md
index f753918cb..47b502203 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecordAccess.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseRecordAccess.md
@@ -251,7 +251,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### System.Object
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemap.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemap.md
index 3bd40b232..ac2df4669 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemap.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemap.md
@@ -282,10 +282,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### System.Guid
+
## NOTES
This cmdlet requires an active connection to a Dataverse environment.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemapEntry.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemapEntry.md
index d5ed92c3f..c62495d34 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemapEntry.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSitemapEntry.md
@@ -612,12 +612,17 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapEntryInfo
+
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapInfo
+
### System.String
-### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
+### System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
+
## OUTPUTS
### Rnwood.Dataverse.Data.PowerShell.Commands.SitemapEntryInfo
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSolutionComponent.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSolutionComponent.md
index 4ad68a54d..14fe1c7e0 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSolutionComponent.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseSolutionComponent.md
@@ -287,10 +287,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.Int32
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
**Important Behavior Details:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseTableIconFromSet.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseTableIconFromSet.md
index fd1ab39c3..10ddae74b 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseTableIconFromSet.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseTableIconFromSet.md
@@ -268,9 +268,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
- This cmdlet requires internet access to download icons from the online icon set.
- The web resource is created in the format `{PublisherPrefix}_/icons/{IconName}.svg`.
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseView.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseView.md
index e742fc6e9..1e4f3626c 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseView.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseView.md
@@ -588,16 +588,25 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Guid
+
### System.String
+
### System.Object[]
+
### System.Collections.Hashtable[]
+
### Rnwood.Dataverse.Data.PowerShell.Commands.DataverseLinkEntity[]
+
### System.String[]
+
### System.Management.Automation.SwitchParameter
+
### System.Nullable`1[[Rnwood.Dataverse.Data.PowerShell.Commands.QueryType, Rnwood.Dataverse.Data.PowerShell.Cmdlets, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
+
## OUTPUTS
### System.Guid
+
## NOTES
**Upsert Pattern:**
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseWebResource.md b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseWebResource.md
index 712ee213c..a286a61f8 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseWebResource.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Set-DataverseWebResource.md
@@ -408,9 +408,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.Management.Automation.PSObject
+
## OUTPUTS
### System.Management.Automation.PSObject
+
## NOTES
## RELATED LINKS
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Test-DataverseRecordAccess.md b/Rnwood.Dataverse.Data.PowerShell/docs/Test-DataverseRecordAccess.md
index 0ba65e653..f3455e236 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Test-DataverseRecordAccess.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Test-DataverseRecordAccess.md
@@ -173,10 +173,13 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### System.String
+
### System.Guid
+
## OUTPUTS
### Microsoft.Crm.Sdk.Messages.AccessRights
+
## NOTES
See https://learn.microsoft.com/en-us/dotnet/api/microsoft.crm.sdk.messages.retrieveprincipalaccessrequest?view=dataverse-sdk-latest
diff --git a/Rnwood.Dataverse.Data.PowerShell/docs/Wait-DataversePublish.md b/Rnwood.Dataverse.Data.PowerShell/docs/Wait-DataversePublish.md
index 1dca7b15f..84a65fac3 100644
--- a/Rnwood.Dataverse.Data.PowerShell/docs/Wait-DataversePublish.md
+++ b/Rnwood.Dataverse.Data.PowerShell/docs/Wait-DataversePublish.md
@@ -127,6 +127,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## INPUTS
### None
+
## OUTPUTS
### System.Object
diff --git a/e2e-tests/McpServer.Tests.ps1 b/e2e-tests/McpServer.Tests.ps1
new file mode 100644
index 000000000..200b15121
--- /dev/null
+++ b/e2e-tests/McpServer.Tests.ps1
@@ -0,0 +1,336 @@
+$ErrorActionPreference = "Stop"
+
+Describe "MCP Server" {
+
+ BeforeAll {
+
+ if ($env:TESTMODULEPATH) {
+ $source = $env:TESTMODULEPATH
+ }
+ else {
+ $source = "$PSScriptRoot/../Rnwood.Dataverse.Data.PowerShell/bin/Debug/netstandard2.0/"
+ }
+
+ $tempmodulefolder = "$([IO.Path]::GetTempPath())/$([Guid]::NewGuid())"
+ new-item -ItemType Directory $tempmodulefolder
+ copy-item -Recurse $source $tempmodulefolder/Rnwood.Dataverse.Data.PowerShell
+ $env:PSModulePath = $tempmodulefolder;
+ $env:ChildProcessPSModulePath = $tempmodulefolder
+ }
+
+ It "Can save connection, start server, and execute scripts" {
+ pwsh -noninteractive -noprofile -command {
+ $env:PSModulePath = $env:ChildProcessPSModulePath
+
+ Import-Module Rnwood.Dataverse.Data.PowerShell
+
+ try {
+ Write-Host "Step 1: Creating and saving a test connection..."
+ # Generate unique connection name for this test
+ $testConnectionName = "E2ETest-$([guid]::NewGuid().ToString('N').Substring(0, 8))"
+ Write-Host "Using connection name: $testConnectionName"
+
+ # Save a connection
+ $connection = Get-DataverseConnection -url ${env:E2ETESTS_URL} -ClientId ${env:E2ETESTS_CLIENTID} -ClientSecret ${env:E2ETESTS_CLIENTSECRET} -Name $testConnectionName -SetAsDefault
+
+ if (-not $connection) {
+ throw "Failed to create connection"
+ }
+ Write-Host "Connection saved successfully"
+
+ # Verify connection was saved
+ $savedConnection = Get-DataverseConnection -Name $testConnectionName
+ if (-not $savedConnection) {
+ throw "Connection was not saved properly"
+ }
+ Write-Host "Connection verified in saved connections"
+
+ Write-Host "Step 2: Starting MCP server..."
+ # Find the MCP server executable
+ $mcpServerPath = "$env:ChildProcessPSModulePath/Rnwood.Dataverse.Data.PowerShell/../../Rnwood.Dataverse.Data.PowerShell.McpServer/bin/Debug/net8.0/Rnwood.Dataverse.Data.PowerShell.McpServer.dll"
+ $mcpServerPath = [System.IO.Path]::GetFullPath($mcpServerPath)
+
+ if (-not (Test-Path $mcpServerPath)) {
+ throw "MCP Server not found at: $mcpServerPath"
+ }
+ Write-Host "MCP Server found at: $mcpServerPath"
+
+ # Start the MCP server process
+ $psi = New-Object System.Diagnostics.ProcessStartInfo
+ $psi.FileName = "dotnet"
+ $psi.Arguments = "$mcpServerPath --connection $testConnectionName"
+ $psi.UseShellExecute = $false
+ $psi.RedirectStandardInput = $true
+ $psi.RedirectStandardOutput = $true
+ $psi.RedirectStandardError = $true
+ $psi.CreateNoWindow = $true
+
+ $process = New-Object System.Diagnostics.Process
+ $process.StartInfo = $psi
+
+ try {
+ $process.Start() | Out-Null
+ Write-Host "MCP Server started with PID: $($process.Id)"
+
+ # Give server time to initialize
+ Start-Sleep -Seconds 3
+
+ if ($process.HasExited) {
+ $stderr = $process.StandardError.ReadToEnd()
+ throw "MCP Server exited unexpectedly. StdErr: $stderr"
+ }
+
+ Write-Host "Step 3: Testing MCP protocol communication..."
+
+ # Send initialization request
+ $initRequest = @{
+ jsonrpc = "2.0"
+ id = 1
+ method = "initialize"
+ params = @{
+ protocolVersion = "2024-11-05"
+ capabilities = @{}
+ clientInfo = @{
+ name = "test-client"
+ version = "1.0.0"
+ }
+ }
+ } | ConvertTo-Json -Depth 10 -Compress
+
+ Write-Host "Sending initialize request..."
+ $process.StandardInput.WriteLine($initRequest)
+ $process.StandardInput.Flush()
+
+ # Read response with timeout
+ $timeout = 10
+ $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
+ $initResponse = $null
+
+ while ($stopwatch.Elapsed.TotalSeconds -lt $timeout -and -not $initResponse) {
+ if (-not $process.StandardOutput.EndOfStream) {
+ $line = $process.StandardOutput.ReadLine()
+ if ($line) {
+ Write-Host "Received: $line"
+ try {
+ $initResponse = $line | ConvertFrom-Json
+ if ($initResponse.id -eq 1) {
+ break
+ }
+ } catch {
+ # Not JSON or not our response, keep reading
+ }
+ }
+ }
+ Start-Sleep -Milliseconds 100
+ }
+
+ if (-not $initResponse) {
+ throw "Did not receive initialization response within timeout"
+ }
+
+ Write-Host "Received initialization response"
+
+ # Send initialized notification
+ $initializedNotif = @{
+ jsonrpc = "2.0"
+ method = "notifications/initialized"
+ } | ConvertTo-Json -Compress
+
+ $process.StandardInput.WriteLine($initializedNotif)
+ $process.StandardInput.Flush()
+
+ Write-Host "Step 4: Creating a session..."
+ $createSessionRequest = @{
+ jsonrpc = "2.0"
+ id = 2
+ method = "tools/call"
+ params = @{
+ name = "CreateSession"
+ arguments = @{}
+ }
+ } | ConvertTo-Json -Depth 10 -Compress
+
+ $process.StandardInput.WriteLine($createSessionRequest)
+ $process.StandardInput.Flush()
+
+ # Read session creation response
+ $stopwatch.Restart()
+ $sessionResponse = $null
+
+ while ($stopwatch.Elapsed.TotalSeconds -lt $timeout -and -not $sessionResponse) {
+ if (-not $process.StandardOutput.EndOfStream) {
+ $line = $process.StandardOutput.ReadLine()
+ if ($line) {
+ Write-Host "Received: $line"
+ try {
+ $response = $line | ConvertFrom-Json
+ if ($response.id -eq 2) {
+ $sessionResponse = $response
+ break
+ }
+ } catch {
+ # Not our response, keep reading
+ }
+ }
+ }
+ Start-Sleep -Milliseconds 100
+ }
+
+ if (-not $sessionResponse -or -not $sessionResponse.result) {
+ throw "Failed to create session"
+ }
+
+ $sessionId = ($sessionResponse.result.content[0].text | ConvertFrom-Json).sessionId
+ Write-Host "Session created with ID: $sessionId"
+
+ Write-Host "Step 5: Running a script in the session..."
+ $runScriptRequest = @{
+ jsonrpc = "2.0"
+ id = 3
+ method = "tools/call"
+ params = @{
+ name = "RunScriptInSession"
+ arguments = @{
+ sessionId = $sessionId
+ script = 'Get-DataverseWhoAmI | ConvertTo-Json'
+ }
+ }
+ } | ConvertTo-Json -Depth 10 -Compress
+
+ $process.StandardInput.WriteLine($runScriptRequest)
+ $process.StandardInput.Flush()
+
+ # Read script execution response
+ $stopwatch.Restart()
+ $scriptResponse = $null
+
+ while ($stopwatch.Elapsed.TotalSeconds -lt $timeout -and -not $scriptResponse) {
+ if (-not $process.StandardOutput.EndOfStream) {
+ $line = $process.StandardOutput.ReadLine()
+ if ($line) {
+ Write-Host "Received: $line"
+ try {
+ $response = $line | ConvertFrom-Json
+ if ($response.id -eq 3) {
+ $scriptResponse = $response
+ break
+ }
+ } catch {
+ # Not our response, keep reading
+ }
+ }
+ }
+ Start-Sleep -Milliseconds 100
+ }
+
+ if (-not $scriptResponse -or -not $scriptResponse.result) {
+ throw "Failed to run script"
+ }
+
+ $scriptExecutionId = ($scriptResponse.result.content[0].text | ConvertFrom-Json).scriptExecutionId
+ Write-Host "Script execution started with ID: $scriptExecutionId"
+
+ Write-Host "Step 6: Getting script output..."
+ # Wait a bit for script to complete
+ Start-Sleep -Seconds 2
+
+ $getOutputRequest = @{
+ jsonrpc = "2.0"
+ id = 4
+ method = "tools/call"
+ params = @{
+ name = "GetScriptOutput"
+ arguments = @{
+ sessionId = $sessionId
+ scriptExecutionId = $scriptExecutionId
+ onlyNew = $false
+ }
+ }
+ } | ConvertTo-Json -Depth 10 -Compress
+
+ $process.StandardInput.WriteLine($getOutputRequest)
+ $process.StandardInput.Flush()
+
+ # Read output response
+ $stopwatch.Restart()
+ $outputResponse = $null
+
+ while ($stopwatch.Elapsed.TotalSeconds -lt $timeout -and -not $outputResponse) {
+ if (-not $process.StandardOutput.EndOfStream) {
+ $line = $process.StandardOutput.ReadLine()
+ if ($line) {
+ Write-Host "Received: $line"
+ try {
+ $response = $line | ConvertFrom-Json
+ if ($response.id -eq 4) {
+ $outputResponse = $response
+ break
+ }
+ } catch {
+ # Not our response, keep reading
+ }
+ }
+ }
+ Start-Sleep -Milliseconds 100
+ }
+
+ if (-not $outputResponse -or -not $outputResponse.result) {
+ throw "Failed to get script output"
+ }
+
+ $outputResult = $outputResponse.result.content[0].text | ConvertFrom-Json
+ Write-Host "Script output received. IsComplete: $($outputResult.isComplete)"
+ Write-Host "Output: $($outputResult.output)"
+
+ # Verify output contains expected data (UserId from WhoAmI)
+ if ($outputResult.output -notmatch '"UserId"') {
+ throw "Script output does not contain expected WhoAmI data"
+ }
+
+ Write-Host "Step 7: Ending session..."
+ $endSessionRequest = @{
+ jsonrpc = "2.0"
+ id = 5
+ method = "tools/call"
+ params = @{
+ name = "EndSession"
+ arguments = @{
+ sessionId = $sessionId
+ }
+ }
+ } | ConvertTo-Json -Depth 10 -Compress
+
+ $process.StandardInput.WriteLine($endSessionRequest)
+ $process.StandardInput.Flush()
+
+ Write-Host "SUCCESS: MCP Server test completed successfully"
+
+ } finally {
+ # Clean up: stop the MCP server process
+ if (-not $process.HasExited) {
+ Write-Host "Stopping MCP Server process..."
+ $process.Kill()
+ $process.WaitForExit(5000)
+ }
+ $process.Dispose()
+
+ # Clean up: remove test connection
+ try {
+ Write-Host "Cleaning up test connection..."
+ # Connection cleanup - the cmdlet doesn't have a delete method, so we'll just note it
+ Write-Host "Test connection will remain: $testConnectionName (cleanup would require manual removal)"
+ } catch {
+ Write-Host "Warning: Failed to cleanup connection: $_"
+ }
+ }
+
+ } catch {
+ throw "Failed: " + ($_ | Format-Table -force * | Out-String)
+ }
+ }
+
+ if ($LASTEXITCODE -ne 0) {
+ throw "Failed"
+ }
+ }
+}
diff --git a/e2e-tests/Module.Tests.ps1 b/e2e-tests/Module.Tests.ps1
index 54b216b5e..ec1709d4d 100644
--- a/e2e-tests/Module.Tests.ps1
+++ b/e2e-tests/Module.Tests.ps1
@@ -527,3 +527,4 @@ Describe "Module" -Skip {
}
}
}
+
diff --git a/example-mcp-consumer/.vscode/mcp.json b/example-mcp-consumer/.vscode/mcp.json
new file mode 100644
index 000000000..a7bb92ec5
--- /dev/null
+++ b/example-mcp-consumer/.vscode/mcp.json
@@ -0,0 +1,8 @@
+{
+ "servers": {
+ "dataverse-rnwood-powershell": {
+ "command": "dotnet",
+ "args": [ "run", "--project", "..\\Rnwood.Dataverse.Data.PowerShell.McpServer\\Rnwood.Dataverse.Data.PowerShell.McpServer.csproj", "-u", "https://org94a83884.crm11.dynamics.com/"]
+ }
+ }
+}
diff --git a/example-mcp-consumer/AGENTS.md b/example-mcp-consumer/AGENTS.md
new file mode 100644
index 000000000..229f003ca
--- /dev/null
+++ b/example-mcp-consumer/AGENTS.md
@@ -0,0 +1,5 @@
+You are an expert Microsoft Dataverse administrator.
+
+Your job is to help the user write scripts to complete tasks in the user's connected Dataverse environment.
+
+Use the tools available in the 'dataverse-rnwood-powershell' to complete the tasks.
\ No newline at end of file
diff --git a/test-mcp-server.sh b/test-mcp-server.sh
new file mode 100755
index 000000000..9e3023950
--- /dev/null
+++ b/test-mcp-server.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Simple test script to verify MCP server starts and responds
+
+cd "$(dirname "$0")"
+
+echo "Building MCP Server..."
+dotnet build Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj -c Debug > /dev/null 2>&1
+
+if [ $? -ne 0 ]; then
+ echo "❌ Build failed"
+ exit 1
+fi
+
+echo "✅ Build succeeded"
+
+echo ""
+echo "Starting MCP Server..."
+echo "The server will listen on stdin/stdout for MCP protocol messages."
+echo ""
+echo "To test manually, you can send MCP initialize request:"
+echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
+echo ""
+echo "Expected response should include tools: StartScript and GetScriptOutput"
+echo ""
+echo "Press Ctrl+C to stop the server"
+echo ""
+
+# Run the server
+dotnet run --project Rnwood.Dataverse.Data.PowerShell.McpServer/Rnwood.Dataverse.Data.PowerShell.McpServer.csproj