PowerShell'de yerleşik MQTT cmdlet'leri yok, ama bir Windows betiğinden broker ile konuşmanın iki güvenilir yolu var: mosquitto_pub / mosquitto_sub programlarını çağırıp çıktılarını bir pipeline gibi işlemek ya da MQTTnet .NET kütüphanesini doğrudan PowerShell 7'ye yüklemek. İlki tek satırlık komutlar, health check'ler ve zamanlanmış görevler için idealdir; ikincisi tek bir .ps1 dosyasından kalıcı bir bağlantı ve tam kontrol sağlar.
Bu rehber ikisini de ele alıyor; neredeyse herkesin düştüğü iki tuzak da dahil: JSON payload'larından kaybolan tırnaklar ve "no Runspace available" hatasıyla çöken event handler'lar. Tüm örnekler broker.connectmq.com kullanıyor; mesajların gelişini görmek için online MQTT istemcisini açık tutun.
Hangi yaklaşım?
| mosquitto istemcileri | PowerShell 7 içinde MQTTnet | |
|---|---|---|
| Kurulum | Mosquitto Windows kurulumu | NuGet'ten tek bir DLL |
| Windows PowerShell 5.1'de çalışır | Evet | Önerilmez |
| Kalıcı bağlantı | Hayır (her çağrıda bir süreç) | Evet |
| Mesaj alma | stdout'u satır satır okuma | Kuyruk + polling döngüsü |
| En uygun olduğu yer | Alarmlar, health check'ler, hızlı testler | Uzun süre çalışan betikler, araçlar, entegrasyon kodu |
MQTTnet etrafında bir sayfadan fazla PowerShell yazmaya başladıysanız, küçük bir C# konsol uygulaması genellikle daha iyi bir araçtır — bkz. MQTTnet ile C#'ta MQTT.
Seçenek 1: mosquitto_pub ve mosquitto_sub
Windows kurulum dosyasını mosquitto.org'dan indirin. Broker'ı (servisi atlayabilirsiniz) ve komut satırı istemcilerini C:\Program Files\mosquitto klasörüne kurar. Bu klasörü PATH'e ekleyin ve bağlantıyı test edin:
@@CODE1@@
$LASTEXITCODE başarıda 0, bağlantı veya kimlik doğrulama başarısız olduğunda sıfırdan farklıdır; bir betiğin ihtiyaç duyduğu da bu kadardır. TcpTestSucceeded değeri False ise sorun MQTT'de değil ağdadır — portun açık olup olmadığını ve Windows güvenlik duvarını kontrol edin. Aynı makinede bir broker çalıştırmak istiyorsanız Windows'ta MQTT broker yazısı servis kurulumunu anlatıyor.
Tırnakları kaybetmeden JSON gönderme
Bu, PowerShell'e özgü en yaygın MQTT hatasıdır. Windows PowerShell 5.1 ve PowerShell 7.0–7.2'de, argümanlar yerel bir .exe'ye geçirilirken içteki çift tırnaklar silinir; subscriber geçerli JSON yerine {device:pc-01} alır. PowerShell 7.3 argüman geçirmeyi düzeltti, ama sağlam çözüm her yerde çalışır: nesneyi ConvertTo-Json ile oluşturun ve mesajı standart girdiden okuyan mosquitto_pub -s komutuna pipe ile verin.
@@CODE2@@
PowerShell, yerel bir programa pipe ile veri gönderirken sona bir satır sonu ekler; JSON ayrıştırıcıları bunu yok sayar. Her girdi satırını ayrı bir mesaj olarak göndermek için -s yerine -l kullanın.
Gelen mesajları pipeline içinde işleme
mosquitto_sub -v her satıra topic payload yazar ve PowerShell her satırı bir pipeline nesnesine dönüştürür:
@@CODE3@@
Tam olarak bir mesaj bekleyen bir kontrol için -C 1 -W 10 ekleyin: mosquitto_sub ilk mesajdan sonra veya on saniye sonra çıkar; zaman aşımında çıkış kodu sıfırdan farklıdır. Diğer seçenekler mosquitto_pub ve mosquitto_sub örnekleri yazısında.
Seçenek 2: PowerShell 7 içinde MQTTnet
MQTTnet, en yaygın kullanılan .NET MQTT kütüphanesidir. PowerShell 7 modern .NET üzerinde çalıştığı için DLL'i doğrudan yükleyebilir. NuGet'ten bir 4.x paketi indirin ve netstandard2.0 derlemesini çıkarın:
@@CODE4@@
Bağlanma ve publish doğrudan PowerShell'den çalışır. Async metotlar task döndürür; beklemek için .GetAwaiter().GetResult() çağırın (bu ayrıca AggregateException yerine asıl hatayı gösterir):
@@CODE5@@
Satır başında noktayla metot zincirleme PowerShell 7 gerektirir. Başarısız bir giriş Connecting with MQTT server failed (BadUserNameOrPassword). veya (NotAuthorized) gibi bir exception fırlatır; MQTT reason code aracı her değeri açıklar.
Runspace hatası olmadan mesaj alma
Akla gelen ilk yöntem — $client.add_ApplicationMessageReceivedAsync({ ... }) — er ya da geç şu hatayla başarısız olur:
There is no Runspace available to run scripts in this thread.
MQTTnet olayı bir .NET thread pool thread'inde tetikler ve bir PowerShell script block'u yalnızca runspace'i olan bir thread'de çalışabilir. Temiz çözüm, her mesajı thread-safe bir kuyruğa koyan birkaç satır C#'tır; PowerShell döngünüz mesajları kendi thread'inde alır.
@@CODE6@@
500 ms'lik zaman aşımı döngünün Ctrl+C'ye yanıt vermesini sağlar; finally bloğu ise broker'ın Last Will tetiklememesi için temiz bir DISCONNECT gönderir. Add-Type bir türü oturum başına yalnızca bir kez tanımlayabilir; betiği aynı konsolda iki kez çalıştırmak Cannot add type. The type name 'MqttInbox' already exists. hatası verir — yeni bir pwsh oturumu açın veya çağrıyı if (-not ('MqttInbox' -as [type])) ile koruyun.
Online istemciden testmqtt/ps/hello topic'ine publish edin; satır bir saniye içinde görünmelidir.
PowerShell dinleyicinize mesaj gönderin
TLS
8883 portuna geçin ve seçenek builder'ında TLS'i etkinleştirin. MQTTnet broker sertifikasını Windows sertifika deposuna göre doğrular; bu yüzden açık sertifikalı bir broker için başka bir şeye gerek yoktur:
@@CODE7@@
Zamanlanmış bir heartbeat
Parçaları birleştirelim: makine durumunu publish eden bir betik ve onu beş dakikada bir çalıştıran zamanlanmış bir görev.
@@CODE8@@
@@CODE9@@
--cafile, broker'ınızın sertifikasını imzalayan CA'yı içeren bir PEM dosyasını gösterir. Hatalar bir log dosyasına yazılır ve sıfırdan farklı çıkış kodu Görev Zamanlayıcı'da görevin "Son Çalıştırma Sonucu" olarak görünür. Yukarıdaki görev, oturumunuz açıkken sizin kullanıcınızla çalışır — gözetimsiz sunucular için görevi bir servis hesabıyla kaydedin ve kimlik bilgilerini o hesabın ortam değişkenlerinde veya SecretManagement modülüyle saklayın. Her makinenin raporunu görmek için testmqtt/ps/+/status topic'ine abone olun.
Sorun giderme
| Hata | Neden | Çözüm |
|---|---|---|
mosquitto_pub : The term 'mosquitto_pub' is not recognized | Kurulum klasörü PATH'te değil | C:\Program Files\mosquitto klasörünü PATH'e ekleyin |
Error: Connection refused | Yanlış port ya da broker bağlantıyı reddetti | Test-NetConnection -Port; port ile TLS'i kontrol edin |
Unable to find type [MQTTnet.MqttFactory] | DLL yüklenmemiş veya farklı namespace'lere sahip bir 5.x DLL'i | Önce Add-Type -Path çalıştırın; bir 4.x paketi kullanın |
Connecting with MQTT server failed (BadUserNameOrPassword). | Yanlış kimlik bilgileri veya boş ortam değişkenleri | $env:MQTT_USER değerini yazdırın; yazım hatası arayın |
There is no Runspace available to run scripts in this thread. | MQTTnet event handler'ı olarak kullanılan script block | Yukarıdaki C# kuyruğunu kullanın |
| JSON tırnaksız geliyor | PS 5.1 / 7.0–7.2'de yerel argüman geçirme | Pipe ile mosquitto_pub -s komutuna verin |
Kaprislerini öğrendiğinizde PowerShell gayet iyi bir MQTT istemcisidir: JSON'u stdin üzerinden gönderin, $LASTEXITCODE'u kontrol edin ve MQTTnet olaylarını bir kuyruğun .NET tarafında tutun. Aynı otomasyonun Linux karşılığı için Bash betiklerinde MQTT yazısına bakın.
Sıkça sorulan sorular
PowerShell ek yazılım olmadan MQTT mesajı gönderebilir mi?
Yerleşik olarak hayır — PowerShell'de MQTT cmdlet'leri yoktur. İki pratik seçenek var: Mosquitto Windows kurulumuyla gelen mosquitto_pub ve mosquitto_sub programları ya da MQTTnet .NET kütüphanesini Add-Type ile PowerShell 7'ye yüklemek.
Neden "There is no Runspace available to run scripts in this thread" hatası alıyorum?
Bir MQTTnet olayına PowerShell script block'u bağladınız. MQTTnet olayları, PowerShell runspace'i olmayan .NET thread pool thread'lerinde tetikler; bu yüzden script block çalışamaz. Mesajları küçük bir C# yardımcısında kuyruğa alın ve kuyruğu PowerShell döngünüzden okuyun.
PowerShell'de mosquitto_pub JSON'umu neden tırnaksız alıyor?
Windows PowerShell 5.1 ile PowerShell 7.0–7.2, yerel programlara argüman geçirirken içteki çift tırnakları siler. PowerShell 7.3 veya üzerine yükseltin ya da JSON'u standart girdiden okunması için pipe ile mosquitto_pub -s komutuna verin.


