Function Send-Message {
    <#
    .SYNOPSIS
        Sends a pop-up message to one or more remote computers using msg.exe.

    .DESCRIPTION
        Uses the Windows msg.exe utility to display a message on the screen of
        one or more remote computers. Requires the target computer to be online
        and reachable.

    .PARAMETER ComputerName
        The name(s) of the target computer(s). Accepts an array or comma-separated
        string.

    .PARAMETER Message
        The message text to send to the target(s).

    .PARAMETER Duration
        The number of seconds to display the message. Defaults to 0 (requires
        user to dismiss). Use 0 for persistent messages.

    .PARAMETER SessionName
        The session name on the target computer. Defaults to "*" (all sessions).

    .EXAMPLE
        Send-Message -ComputerName 'PTFMW-123456789' -Message 'Maintenance in 5 minutes'
        Sends a message to all sessions on the specified computer.

    .EXAMPLE
        Send-Message -ComputerName 'COMP1', 'COMP2' -Message 'Rebooting now' -Duration 60
        Sends a 60-second timeout message to two computers.
    #>
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string[]]$ComputerName,

        [Parameter(Mandatory=$true, Position=1)]
        [string]$Message,

        [Parameter(Position=2)]
        [int]$Duration = 0,

        [Parameter(Position=3)]
        [string]$SessionName = "*"
    )

    Begin {
        $msgExe = "C:\Windows\System32\msg.exe"
        if (-not (Test-Path $msgExe)) {
            Write-Error "msg.exe not found at '$msgExe'. This function requires a Windows system."
            return
        }
        $i = 1
        $total = $ComputerName.Count
    }

    Process {
        foreach ($computer in $ComputerName) {
            $percentComplete = ($i / $total) * 100
            Show-ProgressBar -Activity "Sending message to $computer" -PercentComplete $percentComplete

            if ($pscmdlet.ShouldProcess($computer, "Send message: $Message")) {
                try {
                    $arguments = "/Server:$computer $SessionName /Time:$Duration $Message"
                    Write-Verbose "Executing: $msgExe $arguments"

                    Start-Process -FilePath $msgExe `
                        -ArgumentList $arguments `
                        -NoNewWindow `
                        -Wait `
                        -ErrorAction Stop

                    Write-Verbose "Message sent to $computer"
                }
                catch {
                    Write-Warning "Could not send message to '$computer'. Computer may be offline or unreachable. Error: $($_.Exception.Message)"
                }
            }
            $i++
        }
    }

    End {
        Show-ProgressBar -Activity "Operation Complete" -PercentComplete 100
    }
}
