Displaying return value of a cmdlet that uses C# fails

Hey, I’m maybe trying to put together something unconventional and if there is better ways to do this i’m very keen to know.

So, I already got a working cmdlet that has some C# code to access a websocketsharp dll, with it i’m sending a command to a remote websocket server and it is returning the value to the output stream.

I want to incorporate this functionality intoa UD Dashboard that I just started tinkering with but I’m facing issues with Add-Type not working properly in the context of the dashboard.

function Send-Cmd
	Param (
		[Parameter(Mandatory = $True)]
        [Parameter(Mandatory = $True)]
		Add-Type -Path ".\websocket-sharp.dll"
		Add-Type -Path ".\Newtonsoft.Json.dll"
	catch [System.Reflection.ReflectionTypeLoadException]
   Write-Host "Message: $($_.Exception.Message)"
   Write-Host "StackTrace: $($_.Exception.StackTrace)"
   Write-Host "LoaderExceptions: $($_.Exception.LoaderExceptions)"

	$CurrentlyLoadedAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies()
    $AssembiesFullInfo = $CurrentlyLoadedAssemblies | Where-Object {
        $_.GetName().Name -eq "Microsoft.CSharp" -or
        $_.GetName().Name -eq "mscorlib" -or
        $_.GetName().Name -eq "System" -or
        $_.GetName().Name -eq "System.Collections" -or
        $_.GetName().Name -eq "System.Core" -or
        $_.GetName().Name -eq "System.IO" -or
        $_.GetName().Name -eq "System.Linq" -or
        $_.GetName().Name -eq "System.Runtime" -or
        $_.GetName().Name -eq "System.Runtime.Extensions" -or
        $_.GetName().Name -eq "System.Runtime.InteropServices" -or
        $_.GetName().Name -eq "System.Threading" -or
        $_.GetName().Name -eq "websocket-sharp" -or
		$_.GetName().Name -eq "Newtonsoft.Json"
    $AssembiesFullInfo = $AssembiesFullInfo | Where-Object {$_.IsDynamic -eq $False}
    $ReferencedAssemblies = $AssembiesFullInfo.FullName | Sort-Object | Get-Unique

	$usingStatementsAsString = @"
    using Microsoft.CSharp;
    using System.Collections.Generic;
    using System.Collections;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Runtime;
    using System.Threading;
    using System;
    using WebSocketSharp;
	using System.Net.WebSockets;
	using Newtonsoft.Json;

	$TypeDefinition = @"

namespace MyCore.Utils
    public class WebSocketClient
        public static string StartWSSession(string url, string cmd)
            string reply = null;
            using (var ws = new WebSocketSharp.WebSocket(url))
                int received = 0;

                // Set the WebSocket events.
                ws.OnOpen += (sender, e) =>
                    Response jsonmsg = new Response();
                    jsonmsg.Identifier = 2000;
                    jsonmsg.Message = cmd;
                    jsonmsg.Name = "PowershellWS";
                    string output = JsonConvert.SerializeObject(jsonmsg);

                ws.OnMessage += (sender, e) => {
                    Response response = JsonConvert.DeserializeObject<Response>(e.Data);
                    if (response.Identifier == 2000) {
                        reply = response.Message;
                        received ++;
                ws.OnError += (sender, e) =>

                ws.OnClose += (sender, e) =>

                // Connect to the server.

                while (received < 1){Thread.Sleep(1);}
            return reply;

    internal class Response
        [JsonProperty(PropertyName = "Identifier")]
        public int Identifier { get; set; }

        [JsonProperty(PropertyName = "Message")]
        public string Message { get; set; }

        [JsonProperty(PropertyName = "Name")]
        public string Name { get; set; }
	Add-Type -ReferencedAssemblies $ReferencedAssemblies -TypeDefinition $TypeDefinition
	return [MyCore.Utils.WebsocketClient]::StartWSSession($WSEndpointUrl,$Command)


$WS = New-UDEndpointInitialization -Function @("Send-Cmd")   

$Dashboard = New-UDDashboard -Title "Testing" -Content {
    New-UDCard -Title "Title" -Endpoint {Send-Cmd -WSEndpointUrl ws://websocket-server.com -Command hello}
} -EndpointInitialization $WS
Start-UDDashboard -Dashboard $Dashboard -Port 10001

The error message is:

ExecutionService Error executing endpoint 54401398-459e-475f-8f72-94ea871b0be6. c:\Users\<username>\AppData\Local\Temp\babnz2ck.0.cs(69) : The type Newtonsoft.Json.JsonPropertyAttribute exists in both c:\Users\<username>\.vscode\extensions\ms-vscode.powershell-2019.5.0\modules\PowerShellEditorServices\bin\Desktop\Newtonsoft.Json.dll and c:\Users\<username>\.vscode\extensions\ms-vscode.powershell-2019.5.0\modules\PSScriptAnalyzer\1.18.0\Newtonsoft.Json.dll

Hello @hugil it’s amazing to see what uses people have for dashboards. I am replying to this as no-one else has :upside_down_face: I’m not the best person to answer this question either, but I see you are dot sourcing to the .dll files so I am assuming these files are in the same location as the dashboard? Have you tried specifying a full path to .dll files?


It look like when you run the function in VSCode, Newtonsoft.Json.dll is already loaded. This presumably won’t be a problem in your production environment. I would try adding a check.

If ( -not [type]::GetType( 'Newtonsoft.Json.JsonPropertyAttribute' ) )
    { Add-Type -Path ".\Newtonsoft.Json.dll" }

Tim Curwick