Add new PowerShell project

This commit is contained in:
christian
2025-10-20 20:52:31 +02:00
parent 535a4e010c
commit 1114fa041d
15 changed files with 432 additions and 2 deletions
@@ -0,0 +1,47 @@
using System.Management.Automation;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet(VerbsCommunications.Connect, "MqttSession")]
[OutputType(typeof(MqttClientConnectResult))]
public class ConnectMqttSessionCmdlet : PSCmdlet
{
[Parameter]
public SwitchParameter CleanSession { get; set; } = true;
[Parameter]
public string? ClientId { get; set; } = Guid.NewGuid().ToString();
[Parameter(Mandatory = true)]
public required new string Host { get; set; }
[Parameter]
public string? Password { get; set; }
[Parameter]
public int Port { get; set; } = 1883;
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
[Parameter]
public string? Username { get; set; }
[Parameter]
public SwitchParameter UseTls { get; set; }
protected override void ProcessRecord()
{
var clientOptionsBuilder = new MqttClientOptionsBuilder();
clientOptionsBuilder.WithTcpServer(Host, Port);
if (Username != null)
{
clientOptionsBuilder.WithCredentials(Username, Password);
}
var response = Session.Client.ConnectAsync(clientOptionsBuilder.Build()).GetAwaiter().GetResult();
WriteObject(response);
}
}
@@ -0,0 +1,31 @@
using System.Management.Automation;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet(VerbsCommunications.Disconnect, "MqttSession")]
public class DisconnectMqttSessionCmdlet : PSCmdlet
{
[Parameter]
public MqttClientDisconnectOptionsReason Reason { get; set; } = MqttClientDisconnectOptionsReason.NormalDisconnection;
[Parameter]
public string? ReasonString { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
[Parameter]
public uint SessionExpiryInterval { get; set; }
protected override void ProcessRecord()
{
if (Session.Client.IsConnected)
{
var options = new MqttClientDisconnectOptionsBuilder().WithSessionExpiryInterval(SessionExpiryInterval).WithReason(Reason).WithReasonString(ReasonString).Build();
Session.Client.DisconnectAsync(options).GetAwaiter().GetResult();
}
WriteObject("Disconnected.");
}
}
@@ -0,0 +1,13 @@
using System.Management.Automation;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet(VerbsCommon.New, "MqttSession")]
[OutputType(typeof(MqttSession))]
public class NewMqttSessionCmdlet : PSCmdlet
{
protected override void ProcessRecord()
{
WriteObject(new MqttSession());
}
}
@@ -0,0 +1,40 @@
using System.Management.Automation;
using System.Text;
using MQTTnet.Protocol;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet(VerbsData.Publish, "MqttMessage")]
public class PublishMqttMessageCmdlet : PSCmdlet
{
[Parameter(Mandatory = true)]
public string? Payload { get; set; }
[Parameter]
public int QoS { get; set; } = 0;
[Parameter]
public SwitchParameter Retain { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
[Parameter(Mandatory = true)]
public required string Topic { get; set; }
protected override void ProcessRecord()
{
// if (Session == null || !Session.IsConnected)
// throw new InvalidOperationException("Session not connected.");
var msg = new MqttApplicationMessageBuilder().WithTopic(Topic)
.WithPayload(Encoding.UTF8.GetBytes(Payload ?? string.Empty))
.WithQualityOfServiceLevel((MqttQualityOfServiceLevel)QoS)
.WithRetainFlag(Retain)
.Build();
var response = Session.Client.PublishAsync(msg).GetAwaiter().GetResult();
WriteObject(response);
}
}
@@ -0,0 +1,74 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Management.Automation;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet(VerbsCommunications.Receive, "MqttMessage")]
[OutputType(typeof(MqttMessage))]
public class ReceiveMqttMessageCmdlet : PSCmdlet
{
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
[Parameter]
[ValidateRange(0, int.MaxValue)]
public int TimeoutSeconds { get; set; } = 0;
protected override void ProcessRecord()
{
var tcs = new TaskCompletionSource<MqttMessage>();
EventHandler<MqttMessage>? handler = null;
CancellationTokenSource? cts = null;
try
{
handler = (s, e) =>
{
if (!tcs.Task.IsCompleted)
{
tcs.TrySetResult(e);
}
};
Session.MessageReceived += handler;
// Optionaler Timeout
if (TimeoutSeconds > 0)
{
cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(TimeoutSeconds));
cts.Token.Register(() =>
{
if (!tcs.Task.IsCompleted)
{
tcs.TrySetCanceled();
}
});
}
WriteVerbose("Waiting for next MQTT message...");
try
{
var message = tcs.Task.GetAwaiter().GetResult();
WriteObject(message);
}
catch (TaskCanceledException)
{
WriteWarning($"Timeout after {TimeoutSeconds} seconds — no message received.");
}
}
finally
{
if (handler != null)
{
Session.MessageReceived -= handler;
}
cts?.Dispose();
}
}
}
@@ -0,0 +1,26 @@
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet(VerbsLifecycle.Register, "MqttMessageHandler")]
public class RegisterMqttMessageHandlerCmdlet : PSCmdlet
{
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
[Parameter(Mandatory = true)]
public ScriptBlock? Action { get; set; }
protected override void ProcessRecord()
{
EventHandler<MqttMessage> handler = (s, e) =>
{
//throw new NotImplementedException();
//InvokeCommand.InvokeScript(Action, false, PipelineResultTypes.Output, null, new object[] { e.Topic, e.Payload });
};
Session.MessageReceived += handler;
WriteObject($"Handler registered for MQTT messages on session.");
}
}
@@ -0,0 +1,16 @@
using System.Management.Automation;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet(VerbsCommon.Remove, "MqttSession")]
public class RemoveMqttSessionCmdlet : PSCmdlet
{
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
protected override void ProcessRecord()
{
Session.Dispose();
WriteObject("Session removed.");
}
}
@@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Management.Automation;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet("Subscribe", "MqttTopic")]
[OutputType(typeof(MqttClientSubscribeResult))]
public class SubscribeMqttTopicCmdlet : PSCmdlet
{
[Parameter]
public int QoS { get; set; } = 0;
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
[Parameter(Mandatory = true)]
public required string Topic { get; set; }
protected override void ProcessRecord()
{
var topicFilter = new MqttTopicFilterBuilder().WithTopic(Topic).Build();
var response = Session.Client.SubscribeAsync(topicFilter).GetAwaiter().GetResult();
WriteObject(response);
}
}
@@ -0,0 +1,21 @@
using System.Management.Automation;
namespace MQTTnet.PowerShell.Cmdlets;
[Cmdlet("Unsubscribe", "MqttTopic")]
[OutputType(typeof(MqttClientUnsubscribeResult))]
public class UnsubscribeMqttTopicCmdlet : PSCmdlet
{
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public required MqttSession Session { get; set; }
[Parameter(Mandatory = true)]
public required string Topic { get; set; }
protected override void ProcessRecord()
{
var response = Session.Client.UnsubscribeAsync(Topic).GetAwaiter().GetResult();
WriteObject(response);
}
}