nordicmike
Goto Top

RDP Farbtiefe auslesen

Moin zusammen,

RDP Server 2016, verschiedene RDP Clients von Linux bis Windows 11.

Man kann an den Clients die gewünschte Farbtiefe einstellen,
man kann auch am Server die Farbtiefe limitieren.

Ich möchte die aktuell erreichte Farbtiefe auslesen.

Der XFreeRDP unter Linux zeigt es per stdout bereits an:
[INFO] [com.freerdp.gdi] - Remote framebuffer format PIXEL_FORMAT_RGB16

Nur, wie kann man ermitteln mit welcher Farbtiefe sich der Windows Client angemeldet hat? (mstsc.exe)

Danke euch and keep rockin'

Der Mike

Content-ID: 4892241674

Url: https://administrator.de/contentid/4892241674

Printed on: October 4, 2024 at 04:10 o'clock

mbehrens
mbehrens Dec 08, 2022 at 11:31:20 (UTC)
Goto Top
Zitat von @NordicMike:

RDP Server 2016, verschiedene RDP Clients von Linux bis Windows 11.

Man kann an den Clients die gewünschte Farbtiefe einstellen,
man kann auch am Server die Farbtiefe limitieren.

Ich möchte die aktuell erreichte Farbtiefe auslesen.

Man könnte mal mit der Funktion GetDeviceCaps experimentieren.
4863114660
Solution 4863114660 Dec 09, 2022 updated at 10:08:49 (UTC)
Goto Top
Ist bei einem RDS Server schon mit an Bord
Get-RDUserSession -ConnectionBroker xyz.domain.tld | Select Username,ResolutionWidth,ResolutionHeight,ColorDepth
NordicMike
NordicMike Dec 09, 2022 at 09:52:57 (UTC)
Goto Top
Danke mbehrens, das erfordert jedoch ein zusätzliches Programm (C) und alle Abhängigkeiten z.B. net Framework. Das liesst man nicht einch mal so aus, wenn man es braucht.

Danke schlepper, leider kommt diese Meldung, obwohl ich mehrere User auf dem RD Session Host befinden:
Get-RDUserSession : Die Remotedesktopdienste-Bereitstellung ist auf "rdp1.xxxxx.de" nicht vorhanden.  
4863114660
Solution 4863114660 Dec 09, 2022 updated at 10:10:25 (UTC)
Goto Top
Zitat von @NordicMike:
Danke schlepper, leider kommt diese Meldung, obwohl ich mehrere User auf dem RD Session Host befinden:
Get-RDUserSession : Die Remotedesktopdienste-Bereitstellung ist auf "rdp1.xxxxx.de" nicht vorhanden.  
Ist normal wenn du es nicht direkt auf dem CB ausführst musst du den -ConnectionBroker Parameter mit seinem FQDN mit angeben... face-wink
Get-RDUserSession -ConnectionBroker xyz.domain.tld | Select Username,ResolutionWidth,ResolutionHeight,ColorDepth
Ach ja und die Werte die ColorDepth annehmen kann sind hier Dokumentiert:
https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/ns-wtsapi32 ...
1 = 4 bits per pixel.
2 = 8 bits per pixel.
4 = 16 bits per pixel.
8 = A 3-byte RGB values for a maximum of 2^24 colors.
16 = 15 bits per pixel.
24 = 24 bits per pixel.
32 = 32 bits per pixel.
NordicMike
NordicMike Dec 12, 2022 updated at 05:18:57 (UTC)
Goto Top
Danke erstmal. Ich arbeite jedoch ohne ConnectionBroker. Dieser hat mir die Verbindungen einfach wild durcheinander geworfen. Leute, die sich auf dem rdp1 verbinden wollten, landeten auf dem rdp2 und umgekehrt. Auf den RDP Servern sind jedoch unterschiedliche Programme installiert und lizenziert.
4863114660
4863114660 Dec 12, 2022 updated at 06:48:25 (UTC)
Goto Top
Dieser hat mir die Verbindungen einfach wild durcheinander geworfen.
Da hätten auch zwei oder mehr Collections gereicht die auf die jeweiligen Sessionhosts verweisen, dann passiert das auch nicht ...
colinardo
Solution colinardo Dec 12, 2022 updated at 09:03:59 (UTC)
Goto Top
Servus,
mit einem bisl C# in der Powershell z.B. so
Add-Type '  
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Net;

namespace WTS {
    public static class Sessions {
        public enum WTS_CONNECTSTATE_CLASS {
            WTSActive,
            WTSConnected,
            WTSConnectQuery,
            WTSShadow,
            WTSDisconnected,
            WTSIdle,
            WTSListen,
            WTSReset,
            WTSDown,
            WTSInit
        }
        public enum WTS_INFO_CLASS
        {
             WTSInitialProgram,
             WTSApplicationName,
             WTSWorkingDirectory,
             WTSOEMId,
             WTSSessionId,
             WTSUserName,
             WTSWinStationName,
             WTSDomainName,
             WTSConnectState,
             WTSClientBuildNumber,
             WTSClientName,
             WTSClientDirectory,
             WTSClientProductId,
             WTSClientHardwareId,
             WTSClientAddress,
             WTSClientDisplay,
             WTSClientProtocolType,
             WTSIdleTime,
             WTSLogonTime,
             WTSIncomingBytes,
             WTSOutgoingBytes,
             WTSIncomingFrames,
             WTSOutgoingFrames,
             WTSClientInfo,
             WTSSessionInfo
        }
        
        [StructLayout(LayoutKind.Sequential)]
        private struct WTS_CLIENT_ADDRESS
        {
            public uint AddressFamily;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public byte Address;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct WTS_SESSION_INFO_1 {
            public Int32 ExecEnvId;
            public WTS_CONNECTSTATE_CLASS State;
            public Int32 SessionId;
            [MarshalAs(UnmanagedType.LPStr)]
            public String pSessionName;
            [MarshalAs(UnmanagedType.LPStr)]
            public String pHostName;
            [MarshalAs(UnmanagedType.LPStr)]
            public String pUserName;
            [MarshalAs(UnmanagedType.LPStr)]
            public String pDomainName;
            [MarshalAs(UnmanagedType.LPStr)]
            public String pFarmName;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WTS_CLIENT_DISPLAY {
            public int HorizontalResolution;
            public int VerticalResolution;
            public int ColorDepth;
        }

        [DllImport("wtsapi32.dll", SetLastError = true)]  
        static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);

        [DllImport("wtsapi32.dll")]  
        static extern void WTSCloseServer(IntPtr hServer);

        [DllImport("Wtsapi32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]  
        static extern int WTSEnumerateSessionsEx(IntPtr hServer, ref int pLevel, int Filter, ref IntPtr ppSessionInfo, ref int pCount);

        [DllImport("wtsapi32.dll", SetLastError = true)]  
        static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr ppBuffer, out int pBytesReturned);

        [DllImport("wtsapi32.dll")]  
        static extern void WTSFreeMemory(IntPtr pMemory);

        public class TerminalSession {
            public int SessionId;
            public WTS_CONNECTSTATE_CLASS SessionState;
            public string Host;
            public string SessionName;
            public string UserName;
            public object RemoteHost;
            public string DomainName;
            public string FarmName;
            public int ClientHorizontalResolution;
            public int ClientVerticalResolution;
            public string ClientColorDepth;
        }

        public static List<TerminalSession> GetTSSessions(string Server = "") {  
            IntPtr server = IntPtr.Zero;
            List<TerminalSession> result = new List<TerminalSession>();
            if (Server != "") {  
                server = WTSOpenServer(Server);
            }
            try {

                IntPtr ppSessionInfo = IntPtr.Zero;
                Int32 count = 0;
                Int32 pLevel = 1;
                Int32 retval = WTSEnumerateSessionsEx(server, ref pLevel, 0, ref ppSessionInfo, ref count);
                Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO_1));
                Int64 current = (Int64)ppSessionInfo;
                IntPtr buffer;
                int strLen;
                Hashtable colordepths = new Hashtable() {{ 1, "4bit"},{ 2, "8bit"},{ 4, "16bit"},{ 8, "24bit"},{ 16, "15bit"},{ 24, "24bit"},{ 32, "32bit"}};  

                if (retval != 0) {
                    for (int i = 0; i < count; i++) {
                        WTS_SESSION_INFO_1 si = (WTS_SESSION_INFO_1)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO_1));
                        current += dataSize;
                        
                        // get remote host information
                        object remotehost = null;
                        if (WTSQuerySessionInformation(server,si.SessionId ,WTS_INFO_CLASS.WTSClientAddress, out buffer, out strLen) && strLen > 1){
                            WTS_CLIENT_ADDRESS c_address  = (WTS_CLIENT_ADDRESS)Marshal.PtrToStructure(buffer, typeof(WTS_CLIENT_ADDRESS));
                            if (c_address.AddressFamily == 2 && c_address.Address[2] != 0){
                                // AF_INET (IPv4 address)
                                remotehost = new IPAddress(new byte {c_address.Address[2],c_address.Address[3],c_address.Address[4],c_address.Address[5]});
                            } else if (c_address.AddressFamily == 23){
                                // AF_INET6 (IPv6 address)
                                byte bv6 = new byte[16];
                                Array.Copy(c_address.Address,2,bv6,0,16);
                                remotehost = new IPAddress(bv6);
                            } else {
                                remotehost = new IPAddress(new byte {0,0,0,0});
                            }
                            WTSFreeMemory(buffer);
                        }
                        // get remote display information
                        WTS_CLIENT_DISPLAY oClientDisplay = new WTS_CLIENT_DISPLAY();
                        if (WTSQuerySessionInformation(server,si.SessionId ,WTS_INFO_CLASS.WTSClientDisplay, out buffer, out strLen) && strLen > 1){
                            oClientDisplay = (WTS_CLIENT_DISPLAY)Marshal.PtrToStructure(buffer, oClientDisplay.GetType());
                            WTSFreeMemory(buffer);
                        }

                        result.Add(new TerminalSession() {
                            SessionId = si.SessionId,
                            SessionState = si.State,
                            SessionName = si.pSessionName,
                            Host = Server,
                            RemoteHost = remotehost,
                            UserName = si.pUserName,
                            DomainName = si.pDomainName,
                            FarmName = si.pFarmName,
                            ClientHorizontalResolution = oClientDisplay.HorizontalResolution, 
                            ClientVerticalResolution = oClientDisplay.VerticalResolution,
                            ClientColorDepth = (string)colordepths[oClientDisplay.ColorDepth]
                        });
                    }

                    WTSFreeMemory(ppSessionInfo);
                }
            }catch(Exception ex) {
                throw new Exception(ex.Message);
            } finally {
                WTSCloseServer(server);
            }
            return result;
        }
    }
}
'  
[WTS.Sessions]::GetTSSessions('localhost')  
Grüße Uwe