Public/Invoke-RemoteDesktopSession.ps1

<#
.SYNOPSIS
    Connects to a remote desktop session on specified computers, with options for control and shadowing.
 
.DESCRIPTION
    This function initiates a remote desktop connection (MSTSC) to the specified computers.
    It supports options to control or shadow existing sessions, and can span the session across monitors.
 
.PARAMETER ComputerName
    A list of computer names to which the remote desktop connection will be established.
 
.PARAMETER Control
    If specified, allows the remote session to interact with the active session without prompt.
 
.PARAMETER Shadow
    If specified, shadows the active session on the remote computer.
 
.PARAMETER Span
    If specified, the remote desktop session will span across multiple monitors if available.
 
.EXAMPLE
    PS> Invoke-RemoteDesktopSession -ComputerName "Server01", "Server02" -Control
 
    This example connects to "Server01" and "Server02" with control permissions to interact with the active session.
 
.EXAMPLE
    PS> Invoke-RemoteDesktopSession -ComputerName "Server01" -Shadow
 
    This example shadows the active session on "Server01".
 
.OUTPUTS
    String
    Outputs the status of the connection attempt or any error information.
 
.NOTES
    Requires Citrix PowerShell SDK and appropriate administrative credentials.
#>


Function Invoke-RemoteDesktopSession {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)]
        [Alias('Name','CN')]
        [string[]]$ComputerName,

        [Alias('C')]
        [switch]$Control,

        [Alias('S')]
        [switch]$Shadow,

        [Alias('SP')]
        [switch]$Span
    )

    Begin {
        [string]$MstscArguments = ''
        if ($Control) {
            $MstscArguments += ' /NoConsentPrompt /Control'
        }
        if ($Shadow) {
            $MstscArguments += ' /NoConsentPrompt'
        }
        if ($Span) {
            $MstscArguments += ' /span'
        }
    }

    Process {
        foreach ($Computer in $ComputerName) {
            Write-Host "$(Get-Date) - Working on $Computer - Getting sessions ..."
            try {
                Write-Host "$(Get-Date) - Please Wait...(May take a few minutes)"
                $ConsoleSessionID = ((qwinsta /server:$computer | ForEach-Object { ($_.trim() -replace "\s+", ",") } | ConvertFrom-Csv) | Where-Object SessionName -EQ "console").ID
                $userStatus = (Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Computer).UserName

                if ($userStatus) {
                    $ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
                    $ProcessInfo.FileName = "mstsc.exe"
                    $ProcessInfo.Arguments = "$MstscArguments /v:$Computer /Shadow:$ConsoleSessionID"
                    $ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Normal
                    $Process = New-Object System.Diagnostics.Process
                    $Process.StartInfo = $ProcessInfo
                    [void]$Process.Start()
                    "{0} is Shadowing the user {1} on {2}" -f $env:USERNAME, $userStatus, $Computer
                } else {
                    "No active sessions on $Computer"
                }
            } catch {
                "Shadowing the session failed on $Computer : $_"
            }
        }
    }
}