RDS/Terminalserver message/notification to all active users

The estimated reading time 3 minutes

RDSMessenger.ps1

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.

Was this article helpful?
YesNo
0 0 votes
Article Rating
Subscribe
Notify of
guest
12 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
trackback
2 years ago

[…] RDS/Terminalserver message/notification to all active users […]

trackback
2 years ago

[…] RDS/Terminalserver message/notification to all active users […]

Gianluca
3 years ago

hi admin delete me please 🙂 was trying to format the code correctly but does not work

Last edited 3 years ago by Gianluca
Gianluca
3 years ago

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!” } }

Last edited 3 years ago by Gianluca
Dmitry Topchiev
Dmitry Topchiev
3 years ago

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

Sanjeev
Sanjeev
4 years ago

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

Brett Slaght
Brett Slaght
Reply to  A.K.
4 years ago

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:

Sebastian
Sebastian
Reply to  A.K.
2 years ago

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. 🙂

Last edited 2 years ago by Sebastian
trackback
5 years ago

[…] 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 […]