When using LanSend on Windows computers with standard (non-administrator) user accounts, you may encounter permission errors when attempting to send messages. This typically happens because the underlying Windows messaging APIs require elevated privileges by default. This guide will show you how to grant the necessary permissions to standard users without compromising system security.
Problem Description
LanSend uses Windows system functions to broadcast messages across the network. By default, these functions require administrator privileges, which means:
Messages send successfully when logged in as Administrator
Standard users receive permission errors when attempting to send messages
Error messages appear indicating insufficient privileges
This is particularly problematic in environments like computer labs, schools, or offices where users shouldn't have full administrative access.
Understanding the Solution
Windows Terminal Services uses a specific permission model separate from standard file system permissions. The "Message" permission controls whether users can send messages to other user sessions. This PowerShell method allows you to programmatically grant these permissions without navigating through multiple GUI interfaces.
Prerequisites
Before implementing this solution, ensure you have:
Administrator access to the target computer
PowerShell with administrative privileges
Basic understanding of Windows user groups
PowerShell note: These commands use
Get-WmiObject, which ships with Windows PowerShell 5.1 (built into Windows 10, 11, and Windows Server). PowerShell 7 removedGet-WmiObject; there, useGet-CimInstanceandInvoke-CimMethodagainst the sameRoot\CIMv2\TerminalServicesnamespace.
Step-by-Step Instructions
Step 1: Create a Security Group for LanSend Users
First, we need to create a dedicated security group that will contain all users who need message sending capabilities.
For Local Computer:
# Open PowerShell as Administrator
# Create a local group for message users
New-LocalGroup -Name "LanSendUsers" -Description "Users allowed to send messages via LanSend"
# Add specific users to the group
Add-LocalGroupMember -Group "LanSendUsers" -Member "User1", "User2", "User3"
# Or add existing groups
Add-LocalGroupMember -Group "LanSendUsers" -Member "Users"
For Domain Environment:
# Run on a Domain Controller or computer with RSAT
# Create a domain security group
New-ADGroup -Name "LanSendUsers" -GroupCategory Security -GroupScope Global -Description "Users allowed to send messages via LanSend"
# Add users to the group
Add-ADGroupMember -Identity "LanSendUsers" -Members "User1", "User2", "User3"
# Or add existing groups
Add-ADGroupMember -Identity "LanSendUsers" -Members "Domain Users"
Step 2: Add the Group as Terminal Services User
Now we'll add the created group to Terminal Services with appropriate permissions. This step grants the group basic access to Terminal Services functionality.
# Get the computer name
$computerName = $env:COMPUTERNAME
# Construct the group name (for local groups)
$groupAccount = "$computerName\LanSendUsers"
# For domain groups, use:
# $groupAccount = "DOMAIN\LanSendUsers"
# Register the group on the terminal with minimal Guest access (0).
# Guest grants Logon only; Step 3 adds the Message permission on top.
try {
$tsPermissions = Get-WmiObject -Namespace "root/cimv2/terminalservices" -Class "Win32_TSPermissionsSetting"
$result = $tsPermissions.AddAccount($groupAccount, 0)
if ($result.ReturnValue -eq 0) {
Write-Host "Successfully added $groupAccount to Terminal Services" -ForegroundColor Green
} else {
Write-Host "Failed to add account. Return code: $($result.ReturnValue)" -ForegroundColor Red
}
} catch {
Write-Host "Error adding Terminal Services account: $_" -ForegroundColor Red
}
Understanding the Parameters:
AddAccount registers the account on the terminal at one of three preset permission levels (the second parameter):
0= Guest access: Logon only.1= User access: Logon, Query Information, Send Message, and Connect.2= Full access: every Remote Desktop Services permission.
We pass 0 to register the group with the least access, then grant only the Message permission in the next step. If you prefer Microsoft's standard user preset, pass 1 - it already includes Send Message, and you can skip Step 3.
Step 3: Grant Message Permissions to the Group
This is the crucial step that specifically grants the "Message" permission, allowing users to send messages to other sessions.
# Grant message permissions to the group
try {
# Get all Terminal Services accounts
$tsAccounts = Get-WmiObject -Namespace "Root\CIMv2\TerminalServices" -Class Win32_TSAccount
# Find our specific group account
$targetAccount = $tsAccounts | Where-Object {$_.AccountName -eq $groupAccount}
if ($targetAccount) {
# Grant permissions (7 = Message permission, 1 = Allow)
$result = $targetAccount.ModifyPermissions(7, 1)
if ($result.ReturnValue -eq 0) {
Write-Host "Successfully granted Message permissions to $groupAccount" -ForegroundColor Green
} else {
Write-Host "Failed to modify permissions. Return code: $($result.ReturnValue)" -ForegroundColor Red
}
} else {
Write-Host "Account $groupAccount not found in Terminal Services" -ForegroundColor Yellow
}
} catch {
Write-Host "Error modifying permissions: $_" -ForegroundColor Red
}
Understanding Permission Codes: The first parameter of ModifyPermissions() is the Remote Desktop Services permission to set:
0= Query Information1= Set Information2= Logoff3= Virtual Channel4= Remote Control (shadow)5= Logon6= Reset7= Message (required for LanSend)8= Connect9= Disconnect
The second parameter:
1= Allow0= Deny
Complete Script
Here's a complete PowerShell script that combines all steps:
# LanSend Terminal Services Permission Configuration Script
# Run as Administrator
param(
[Parameter(Mandatory=$false)]
[string]$GroupName = "LanSendUsers",
[Parameter(Mandatory=$false)]
[switch]$DomainGroup
)
Write-Host "=== LanSend Terminal Services Permission Configuration ===" -ForegroundColor Cyan
# Step 1: Create the security group
Write-Host "`nStep 1: Creating security group..." -ForegroundColor Yellow
if ($DomainGroup) {
# Domain group creation
try {
New-ADGroup -Name $GroupName -GroupCategory Security -GroupScope Global -Description "Users allowed to send messages via LanSend"
Write-Host "Domain group '$GroupName' created successfully" -ForegroundColor Green
} catch {
if ($_.Exception.Message -like "*already exists*") {
Write-Host "Group '$GroupName' already exists" -ForegroundColor Yellow
} else {
Write-Host "Error creating domain group: $_" -ForegroundColor Red
exit 1
}
}
$groupAccount = "$env:USERDOMAIN\$GroupName"
} else {
# Local group creation
try {
New-LocalGroup -Name $GroupName -Description "Users allowed to send messages via LanSend"
Write-Host "Local group '$GroupName' created successfully" -ForegroundColor Green
} catch {
if ($_.Exception.Message -like "*already exists*") {
Write-Host "Group '$GroupName' already exists" -ForegroundColor Yellow
} else {
Write-Host "Error creating local group: $_" -ForegroundColor Red
exit 1
}
}
$groupAccount = "$env:COMPUTERNAME\$GroupName"
}
# Step 2: Add group to Terminal Services
Write-Host "`nStep 2: Adding group to Terminal Services..." -ForegroundColor Yellow
try {
$tsPermissions = Get-WmiObject -Namespace "root/cimv2/terminalservices" -Class "Win32_TSPermissionsSetting"
$result = $tsPermissions.AddAccount($groupAccount, 0)
if ($result.ReturnValue -eq 0) {
Write-Host "Successfully added $groupAccount to Terminal Services" -ForegroundColor Green
} elseif ($result.ReturnValue -eq 1) {
Write-Host "Account already exists in Terminal Services" -ForegroundColor Yellow
} else {
Write-Host "Failed to add account. Return code: $($result.ReturnValue)" -ForegroundColor Red
}
} catch {
Write-Host "Error adding Terminal Services account: $_" -ForegroundColor Red
exit 1
}
# Step 3: Grant Message permissions
Write-Host "`nStep 3: Granting Message permissions..." -ForegroundColor Yellow
try {
# Small delay to ensure the account is properly registered
Start-Sleep -Seconds 2
$tsAccounts = Get-WmiObject -Namespace "Root\CIMv2\TerminalServices" -Class Win32_TSAccount
$targetAccount = $tsAccounts | Where-Object {$_.AccountName -eq $groupAccount}
if ($targetAccount) {
# Grant Message (7); Query Information (0) is optional and lets the account enumerate sessions
$permissions = @(
@{Code=7; Name="Message"},
@{Code=0; Name="Query Information"}
)
foreach ($perm in $permissions) {
$result = $targetAccount.ModifyPermissions($perm.Code, 1)
if ($result.ReturnValue -eq 0) {
Write-Host " Granted $($perm.Name) permission" -ForegroundColor Green
} else {
Write-Host " Failed to grant $($perm.Name) permission" -ForegroundColor Red
}
}
Write-Host "`nConfiguration completed successfully!" -ForegroundColor Green
Write-Host "Users in the '$GroupName' group can now send messages via LanSend" -ForegroundColor Cyan
} else {
Write-Host "Account $groupAccount not found in Terminal Services" -ForegroundColor Red
exit 1
}
} catch {
Write-Host "Error modifying permissions: $_" -ForegroundColor Red
exit 1
}
# Display next steps
Write-Host "`n=== Next Steps ===" -ForegroundColor Cyan
Write-Host "1. Add users to the '$GroupName' group"
Write-Host "2. Have users log out and log back in"
Write-Host "3. Test LanSend message functionality"
Step 4: Add Users to the Group
After running the script, add users who need LanSend access to the created group:
# For local groups
Add-LocalGroupMember -Group "LanSendUsers" -Member "Username1", "Username2"
# For domain groups
Add-ADGroupMember -Identity "LanSendUsers" -Members "Username1", "Username2"
Step 5: Verify the Configuration
To verify that permissions were applied correctly:
# Check Terminal Services accounts and permissions
$tsAccounts = Get-WmiObject -Namespace "Root\CIMv2\TerminalServices" -Class Win32_TSAccount
$tsAccounts | Where-Object {$_.AccountName -like "*LanSend*"} | Format-List *
# Check group membership
Get-LocalGroupMember -Group "LanSendUsers"
# Or for domain:
Get-ADGroupMember -Identity "LanSendUsers"
Deployment Options
Option 1: Manual Execution
Run the script manually on each computer where LanSend is installed:
Save the script as Configure-LanSendPermissions.ps1
Open PowerShell as Administrator
Run: .\Configure-LanSendPermissions.ps1
Option 2: Group Policy Startup Script
Deploy via Group Policy for domain computers:
Save the script to a network share accessible by all computers
In Group Policy Management, create a new GPO
Navigate to: Computer Configuration → Policies → Windows Settings → Scripts → Startup
Add the PowerShell script
Link the GPO to the appropriate OU
Option 3: Remote Execution
Use PowerShell remoting for multiple computers:
$computers = "PC1", "PC2", "PC3"
$scriptContent = Get-Content "Configure-LanSendPermissions.ps1" -Raw
foreach ($computer in $computers) {
Invoke-Command -ComputerName $computer -ScriptBlock {
param($script)
Invoke-Expression $script
} -ArgumentList $scriptContent
}
Troubleshooting
Common Issues and Solutions
Issue: "Access Denied" when running the script
Solution: Ensure you're running PowerShell as Administrator. Right-click PowerShell and select "Run as Administrator"
Issue: WMI commands fail with "Invalid namespace"
Solution: Verify Terminal Services is installed:
Get-WmiObject -Namespace "root/cimv2" -List | Where-Object {$_.Name -like "*TS*"}
Issue: Users still can't send messages after configuration
Solution: Users must log out and log back in for group membership changes to take effect
Issue: Script succeeds but permissions don't persist
Solution: Check if Group Policy is overriding local settings:
gpresult /h report.html
Security Considerations
Only add users who genuinely need message-sending capabilities to the LanSendUsers group
Regularly audit group membership:
Get-LocalGroupMember -Group "LanSendUsers" | Export-Csv "LanSendUsers_Audit.csv"
Consider implementing PowerShell script logging for accountability
Test the script in a non-production environment first
Conclusion
This PowerShell-based approach provides a reliable, scriptable method for configuring Terminal Services Message permissions for LanSend. It's particularly useful for:
Automating deployment across multiple computers
Situations where GUI tools are unavailable
Creating consistent, repeatable configurations
Integration with existing automation workflows
The script can be easily modified to suit your specific environment and integrated into your existing deployment processes. Remember to follow the principle of least privilege and only grant permissions to users who require them for their work.
