Search code examples
powershellforeachremote-desktopinvoke-commandmsg

Send pop up message to specific RDP users who have not logged off


I am using the function Get-LoggedOnUser from Microsoft Technet Script Center Repository: Get-LoggedOnUser

I'm am invoking the "msg" Command (net send) on my RDP server to send a pop up message to any user who has not logged out overnight.

I don't want to broadcast the message to all users on the server; just send a notification to any individual users who have been logged in since before midnight the previous night.
I want the message to show their username and logon time and remind them to log out.

$yesterday = [DateTime]::Today.ToString('M/d/yyyy HH:mm ') 

$NotLoggedOut = Get-LoggedOnUser -ComputerName COMPUTERNAME | Where-Object {$_.LogonTime -lt $yesterday} 

$Script={param($Command, $Users, $ComputerName, $LogonTime); Write-Host $Command;  &cmd /c "$Command"}

$Command = Foreach($User in $NotLoggedOut){write-host "Dear " $User.username "the system shows that you have been logged on since " $User.LogonTime "REMINDER: You MUST Log off at the end of everyday"}

Invoke-Command -ComputerName COMPUTERNAME -ScriptBlock $Script -ArgumentList $Command

$NotLoggedOut shows three users who should receive the msg

UserName    ComputerName     SessionName  Id State  IdleTime  LogonTime              Error
--------    ------------    ------------  -- -----  --------  ------------           -----
User01       COMPUTERNAME    rdp-tcp#0     1  Active 5        7/30/2015 9:39 AM      
User02       COMPUTERNAME    rdp-tcp#9     2  Active 10       7/30/2015 8:46 AM     
User03       COMPUTERNAME    rdp-tcp#2     2  Active          7/30/2015 8:46 AM 

User01 gets the message.

But I can't get it to send the message to each user in the foreach loop. Only User01.


Solution

  • I Think it is the way you send the arguments which is not right. What you should be doing is: The $script should be all the script necessary to send the message for all the users. The -argumentlist you should send the $NotLoggedOut variable. Inside the script part that an be acesses as $Args[0].UserName (for the first user and so on).

    Try it out. I have rewritten your code below, and that works well. Notice i have commented out the call to Get-LoggedOnUser and instead use some static test data.

    $midnight = [DateTime]::Today
    
    $NotLoggedOut = @(@{UserName = "Jower";ComputerName = "JOWERWIN81";LogonTime= [DateTime]::Now.AddDays(-2)}, @{UserName = "Jower";ComputerName = "JOWERWIN81";LogonTime= [DateTime]::Now.AddDays(-1)}) | Where-Object {$_.LogonTime -lt $midnight}  #Get-LoggedOnUser -ComputerName COMPUTERNAME | Where-Object {$_.LogonTime -lt $midnight} 
    
    $Script={
        Foreach($User in $Args)
        {
            $mess = ("Dear " +  $User.username + " the system shows that you have been logged on since " + $User.LogonTime + " REMINDER: You MUST Log off at the end of everyday")
            write-host $mess
            & {msg $args.Username /SERVER:($args.ComputerName) $args.Message} -ArgumentList @{UserName = $User.UserName;Message=$mess}
        }
    }
    
    Invoke-Command -ScriptBlock $Script -ArgumentList $NotLoggedOut