The estimated reading time 3 minutes
UPDATE 11/09/2019: If you like this script as module or EXE see my new post
In RDServer (Remote Desktop) environmets (also know with the legacy name terminalservices) you need to notify all active users, because there is a maintenace or anything else. I searched a while to find a thin solution for that, but did not find any proper solution. So I decided to write a short powershell script to do this task.
With Windows Server 2012 a new cmdlet was introduced
https://docs.microsoft.com/en-us/powershell/module/remotedesktop/send-rdusermessage?view=win10-ps
Send-RDUserMessage
The goal:
Link to my github repository:
https://github.com/blog-it-koehler-com/rdsmessenger
You can use this cmdlet after importing on the server where you want so send the notification. This message is also displayed in remoteapps so it can be used in mixed environments with desktop and remoteapps. (WIN2012/R2, WIN2016 and WIN2019 include this module by default).
NOTE: how to find the RD-Broker? If you don’t know which server is the broker, please open your ServerManager and connect all server which are part of the collection (ServerManager tells you which one is missing)
After importing all server in ServerManager you can see the configuration and also the broker
As mentioned there is one cmdlet which generates the message for one user. The heart of my script are these few lines:
Import-Module RemoteDesktop $broker = "FQDN of the Broker" $userids = Get-RDUserSession -ConnectionBroker "$broker" | sort Username foreach($uid in $userids){ $id = (($uid).UnifiedSessionID) Send-RDUserMessage -HostServer $($uid.HostServer) -UnifiedSessionID $id -MessageTitle "messagetitel" -MessageBody "text in your messagebox" }
With the following script you see some output when you execute the script.
Import-Module RemoteDesktop #fill message $msgtitel = Read-Host "Type message titel" $msg = Read-Host "Type message..." $broker = Read-Host "Type FQDN of rd broker server" #getting all user ids $userids = Get-RDUserSession -ConnectionBroker "$broker" | Sort-Object Username $sessions = ($userids | Select-Object UserName,UnifiedSessionId)|Out-String Write-host "Getting all active sessions on rd broker $broker" -ForegroundColor Yellow Write-host "$sessions" -ForegroundColor Yellow #send message to all user ids foreach($uid in $userids){ $id = (($uid).UnifiedSessionID) $user = (($uid).UserName) Send-RDUserMessage -HostServer $($uid.HostServer) -UnifiedSessionID $id -MessageTitle "$msgtitel" -MessageBody "$msg" Write-Host "Sending message to user: $user with titel: $msgtitel" -ForegroundColor Green } pause
here my script in action.
After this short introduction, see some tips to handle my ps script from github with parameters:
EXAMPLE 1 simple execution:
EXAMPLE 2 execution with parameters
.\rdmessenger.ps1 -rdbroker rds02.demo01.it-koehler.com -messagetitel “admin message” -message “message to display” -Verbose
EXAMPLE 3 execution with parameter -rdsessionhost
.\rdmessenger.ps1 -rdbroker rds02.demo01.it-koehler.com -messagetitel “admin message” -message “message to display” -rdsessionhost rds02.demo01.it-koehler.com
Features of this script:
- checks modules required
- imports modules required
- waiting 10 seconds before notification is send to all users
- see what it does with verbose command
Also have a look at my comments inside script if you want to know what it does.
If you have any further questions please leave me a message. If you like the tool click on helpful. Have fun sending messages to your users.
[…] RDS/Terminalserver message/notification to all active users […]
[…] RDS/Terminalserver message/notification to all active users […]
hi admin delete me please 🙂 was trying to format the code correctly but does not work
I’ve made my own version which reads the collection names from the registry and send messages to all users in all collections. The variable “$collections” can also be replaced with the collection name and it will be only sent there.
#Send MSG to all RDS-User in every Collections | GM – 02.07.2021 #Tspecial thanks to Daniel M.!! Import-Module RemoteDesktop $Collections = Get-ChildItem -Path “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\CentralPublishedResources\PublishedFarms” | Select -ExpandProperty PSChildName foreach($colName in $Collections){ $broker = “rds-broker.kmfv.local” # FQDN of the broker srv $title = “insert title here” # a title for the message $body = “hello user, the cake is a lie” # message text $userids = Get-RDUserSession -ConnectionBroker $broker -CollectionName $colName | sort Username foreach($uid in $userids){ $id = (($uid).UnifiedSessionID) Send-RDUserMessage -HostServer (($uid).Hostserver) -UnifiedSessionID $id -MessageTitle “$title” -MessageBody “$body” write-host (($uid).CollectionName) ” | ” “the User” (($uid).Username) “in” (($uid).Hostserver) “has received the message!” } }
Need to add the line
$HostId = (($uid).HostServer)
and it turns out the following
Import-Module RemoteDesktop
#fill message
$msgtitel = Read-Host “Введите тему сообщения”
$msg = Read-Host “Введите текст сообщения”
$broker = “srv-rdbr02.uvzl.msk”
#getting all user ids
$userids = Get-RDUserSession -ConnectionBroker “$broker” | Sort-Object Username
$sessions = ($userids | Select-Object UserName,UnifiedSessionId)|Out-String
Write-host “Getting all active sessions on rd broker $broker” -ForegroundColor Yellow
Write-host “$sessions” -ForegroundColor Yellow
#send message to all user ids
foreach($uid in $userids){
$id = (($uid).UnifiedSessionID)
$user = (($uid).UserName)
$HostId = (($uid).HostServer)
Send-RDUserMessage -HostServer $HostId -UnifiedSessionID $id -MessageTitle “$msgtitel” -MessageBody “$msg”
Write-Host “Sending message to user: $user with titel: $msgtitel” -ForegroundColor Green
}
pause
I’m trying first execution
which is getting failed with
Send-RDUserMessage : Failed to send message. Specified session does not exist.
At line:6 char:14
+ … Send-RDUserMessage -HostServer $broker -UnifiedSessionID …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Send-RDUserMessage
Hi Sanjeev,
can you please specify which RDS Hosts (Version) and where do you execute the script? Seems the script is getting false Session IDs (maybe people who are disconnected or something like that).
Best regards.
I am getting this same error on RDSH 2016 Servers.
I am running from my Remote Client Computer. It seems to grab my username but fails with the following:
ERROR: Send-RDUserMessage : Failed to send message. Specified session does not exist.
rdsmessenger.ps1 (179, 13): ERROR: At Line: 179 char: 13
ERROR: + Send-RDUserMessage -HostServer $broker -UnifiedSessionID …
ERROR: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ERROR: + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
ERROR: + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Send-RDUserMessage
ERROR:
Hi Brett,
I think it is an issue with the session ids. I have to check if the session is already disconnected but still available. I’ll check that and update the script.
Greetings.
Send-RDUserMessage need the HostServer not the ConnectionBroker to work.
Instead of
Send-RDUserMessage -HostServer $broker -UnifiedSessionID $id -MessageTitle “messagetitel” -MessageBody “text in your messagebox”
you could use
Send-RDUserMessage -HostServer $($uid.HostServer) -UnifiedSessionID $id -MessageTitle “messagetitel” -MessageBody “text in your messagebox”
I guess in your lab you have all roles installed on the same machine. That’s why it works for you with “$broker”.
(I know this block post ist more than a year old. 🙂
Hi Sebastian,
thanks for your comment. It’s completly true and already corrected in the article.
Best regards
[…] desktop messaging for all connected users. So here is my first module for Remotedesktop Messaging. https://blog.it-koehler.com/en/Archive/2511If you liked it you may also want to have this cmdlet permanently on your rdserver for notifying […]