You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写PowerShell脚本实现MS Server 2012 R2的RDP会话影子监控

Alright, let's build out the PowerShell script you need to manage and monitor RDP sessions on your Windows Server 2012 R2 x64. I'll break this into the three key functions you specified, with explanations and error handling to make it robust for your partner company's remote work needs.

1. Check All Current RDP Sessions

First, to get a clear overview of all active (and disconnected) sessions on the server, we can use the built-in quser command (or query user—they're interchangeable). This gives us structured details like username, session ID, state, and logon time.

Here's a PowerShell snippet to run this and format the output into easy-to-read objects:

# Retrieve and parse all current sessions
$allSessions = quser | ForEach-Object {
    if ($_ -match "^([>]*\s*\w+)\s+(\d+)\s+(\w+)\s+(\S+\s+\S+)\s*(.*)$") {
        [PSCustomObject]@{
            Username = $matches[1].Trim()
            SessionID = $matches[2]
            State = $matches[3]
            LogonTime = $matches[4]
            AdditionalInfo = $matches[5].Trim()
        }
    }
}

# Display formatted session data
$allSessions | Format-Table Username, SessionID, State, LogonTime -AutoSize

This turns the raw text output of quser into structured PowerShell objects, making it simpler to read and use for subsequent tasks.

2. Find RDP Session ID by Username

Next, we need a function that takes a target username and returns their corresponding session ID(s). We'll add error handling to account for cases where the user isn't logged in, or has multiple active sessions.

function Get-RdpSessionId {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$TargetUsername
    )

    # Filter sessions for the target user
    $userSessions = quser | Where-Object { $_ -match "^([>]*\s*$TargetUsername)\s+(\d+)" }

    if (-not $userSessions) {
        Write-Error "No active or disconnected sessions found for user '$TargetUsername'"
        return $null
    }

    # Extract session IDs from matching results
    $sessionIds = $userSessions | ForEach-Object {
        if ($_ -match "\s+(\d+)\s+") { $matches[1] }
    }

    if ($sessionIds.Count -gt 1) {
        Write-Warning "User '$TargetUsername' has multiple sessions. Returning all IDs: $($sessionIds -join ', ')"
    }

    return $sessionIds
}

# Example usage:
# $targetSessionId = Get-RdpSessionId -TargetUsername "partnerSupportUser"

This function validates the user's presence, handles multiple sessions, and returns the ID(s) you need to proceed with monitoring.

3. Shadow (Monitor) the RDP Session

Once you have the session ID, you can use the shadow command via mstsc.exe to connect to the session and monitor the user's activity. Important note: you need local administrator privileges to run this, and you may need to adjust server settings to allow remote control.

Here's a function to handle the shadow connection with error checking:

function Start-RdpSessionMonitoring {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$SessionId,
        [bool]$PromptUser = $true  # Set to $false to skip prompting the remote user (check policies first!)
    )

    # Validate the session ID exists
    $sessionExists = quser | Where-Object { $_ -match "\s+$SessionId\s+" }
    if (-not $sessionExists) {
        Write-Error "Session ID '$SessionId' does not exist on the server"
        return
    }

    # Build shadow command arguments
    $shadowArgs = if ($PromptUser) {
        "/shadow:$SessionId"
    } else {
        "/shadow:$SessionId /v:1 /control"  # /control lets you take over if needed
    }

    # Launch the shadow session
    try {
        Write-Host "Connecting to session ID $SessionId..."
        Start-Process -FilePath "mstsc.exe" -ArgumentList $shadowArgs -NoNewWindow -Wait
    }
    catch {
        Write-Error "Failed to start monitoring session: $_"
    }
}

# Example usage (after retrieving the session ID):
# Start-RdpSessionMonitoring -SessionId $targetSessionId
  • The /v:1 flag disables prompting the remote user—only use this if your company policies and partner agreement allow it.
  • The /control flag adds the ability to take over the session (optional, adjust based on your monitoring needs).
Complete Script with Workflow

Putting it all together, here's the full script with comments and an example workflow to follow:

<#
.SYNOPSIS
Manages and monitors RDP sessions on Windows Server 2012 R2 x64 for partner company access.
.DESCRIPTION
Includes functions to check all sessions, find a user's session ID, and monitor the session via shadowing.
#>

# 1. Retrieve all current RDP sessions
function Get-AllRdpSessions {
    $allSessions = quser | ForEach-Object {
        if ($_ -match "^([>]*\s*\w+)\s+(\d+)\s+(\w+)\s+(\S+\s+\S+)\s*(.*)$") {
            [PSCustomObject]@{
                Username = $matches[1].Trim()
                SessionID = $matches[2]
                State = $matches[3]
                LogonTime = $matches[4]
                AdditionalInfo = $matches[5].Trim()
            }
        }
    }
    return $allSessions
}

# 2. Get session ID by target username
function Get-RdpSessionId {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$TargetUsername
    )

    $userSessions = quser | Where-Object { $_ -match "^([>]*\s*$TargetUsername)\s+(\d+)" }

    if (-not $userSessions) {
        Write-Error "No sessions found for user '$TargetUsername'"
        return $null
    }

    $sessionIds = $userSessions | ForEach-Object {
        if ($_ -match "\s+(\d+)\s+") { $matches[1] }
    }

    if ($sessionIds.Count -gt 1) {
        Write-Warning "Multiple sessions found for $TargetUsername : $($sessionIds -join ', ')"
    }

    return $sessionIds
}

# 3. Start monitoring a specific RDP session
function Start-RdpSessionMonitoring {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$SessionId,
        [bool]$PromptUser = $true
    )

    $sessionExists = quser | Where-Object { $_ -match "\s+$SessionId\s+" }
    if (-not $sessionExists) {
        Write-Error "Session ID $SessionId does not exist"
        return
    }

    $shadowArgs = if ($PromptUser) { "/shadow:$SessionId" } else { "/shadow:$SessionId /v:1 /control" }

    try {
        Write-Host "Initiating monitor for session $SessionId..."
        Start-Process mstsc.exe -ArgumentList $shadowArgs -NoNewWindow -Wait
    }
    catch {
        Write-Error "Error starting monitor: $_"
    }
}

# ------------------------------
# Example Workflow (uncomment to use)
# ------------------------------
# # Step 1: View all active sessions
# Write-Host "=== Current RDP Sessions ==="
# Get-AllRdpSessions | Format-Table -AutoSize
#
# # Step 2: Get session ID for your partner user
# $targetUser = "partnerSupportUser"
# $sessionId = Get-RdpSessionId -TargetUsername $targetUser
#
# # Step 3: Start monitoring if session exists
# if ($sessionId) {
#     Start-RdpSessionMonitoring -SessionId $sessionId -PromptUser $true
# }
Critical Notes
  • Permissions: Run this script with local administrator privileges on the Server 2012 R2 machine—otherwise, shadowing and session queries will fail.
  • Compliance: Ensure you have explicit written permission from the partner company (and align with internal policies) before monitoring their sessions. Transparency is essential to maintain trust.
  • Server Settings: If you want to disable the user prompt for shadowing, adjust the Remote Desktop Session Host settings (via Group Policy or local server config) to allow remote control without user consent.

内容的提问来源于stack exchange,提问作者user9715250

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:27:25