private static IEnumerable<int> GetSessionIDs(IntPtr server)
        {
            // Buffer which contains the SessionInfo structs
            IntPtr buffer = IntPtr.Zero;

            // Count of structs in this buffer
            int count = 0;

            // Retrieve all sessions
            try
            {
                if (!Wtsapi32.WtsEnumerateSessions(server, 0, 1, ref buffer, ref count))
                    throw new Win32Exception("Cannot enumerate wts sessions.");

                // Set start of memory location to buffer beginning
                IntPtr currentIndex = buffer;

                // Iterate over all sessions
                for (int i = 0; i < count; i++)
                {
                    var sessionInfo = (Wtsapi32.WtsSessionInfo?) Marshal.PtrToStructure(currentIndex, typeof(Wtsapi32.WtsSessionInfo));
                    if (sessionInfo == null)
                        throw new Win32Exception(
                            "Cannot not marshal session info structure.");
                    currentIndex += Marshal.SizeOf(typeof(Wtsapi32.WtsSessionInfo));
                    yield return sessionInfo.Value.SessionId;
                }
            }
            finally
            {
                // Free memory buffer
                Wtsapi32.WtsFreeMemory(buffer);
            }
        }
        private static string? GetUsername(IntPtr server, int sessionId)
        {
            IntPtr buffer = IntPtr.Zero;

            try
            {
                // Check is method returns success
                if (!Wtsapi32.WtsQuerySessionInformation(server, sessionId, Wtsapi32.WtsInfoClass.WtsUserName, out buffer,
                    out uint _))
                    return null;

                return Marshal.PtrToStringAnsi(buffer)?.ToUpper().Trim();
            }
            finally
            {
                Wtsapi32.WtsFreeMemory(buffer);
            }
        }