Remote Desktop: Enable concurrent interactive and remote sessions #

(without hack workarounds) via RDP shadowing.

Warning: Do not proceed without fully understanding the steps involved and how to secure your network.

1. On Windows 10 Professional ("server")

  1. System Properties (sysdm.cpl) → Remote

  2. Enable "Allow remote connections to this computer" → OK

  3. Group Policy Editor (gpedit.msc) → Local Computer Policy → Computer Configuration → Administrative Templates → Windows Components → Remote Desktop Services → Remote Desktop Session Host → Connections

  4. Double click "Set rules for remote control of Remote Desktop Services user sessions" → select "Enabled" → set "Options:" to "Full Control without user's permission" → OK

  5. Windows Defender Firewall with Advanced Security (wf.msc) → check "File and Printer Sharing (SMB-In)" and "Remote Desktop - Shadow (TCP-In)" are enabled for LAN connections (see Restrict Windows Remote Desktop connections to LAN only)

2. On Windows 11 Home ("client")

  1. If the local and remote credentials differ, store the remote username and password in Windows Credential Manager:

    cmdkey /add:<hostname|IP> /user:<remote_user> /pass:<remote_pass>

2a. Manual method

  1. Retrieve the remote user's session ID (will generally be "1" or "2" on single-user systems):

    qwinsta /server:<hostname|IP>

  2. Connect:

    mstsc.exe /shadow:<sessionID> /v:<hostname|IP> /noconsentprompt /control

2b. Automatic method

  1. Modify and save this batch file, then run it to automatically retrieve the user session ID and establish a connection:

    @echo off
    setlocal enabledelayedexpansion
    
    :: Set your remote username and hostname or IP address
    set remote_user=<USERNAME>
    set remote_host=<HOSTNAME|IP>
    
    :: Get the session ID for the specified username where the session state is Active
    for /f "tokens=2,3,4" %%a in ('qwinsta /server:%remote_host% ^| findstr /R "^ %remote_user%"') do (
        if "%%c"=="Active" (
            set session_id=%%b
        )
    )
    
    :: If an active session ID was found for the specified user, connect automatically
    if defined session_id (
        start "" mstsc /v:%remote_host% /shadow:%session_id% /control /noConsentPrompt
    ) else (
        echo No active session found for user "%remote_user%".
    )
    
    exit

3. Notes

4. Further reading

/windows | Sep 04, 2024

Restrict TightVNC connections to LAN only #

  1. TightVNC Service Configuration → Access Control

  2. Click Add… → set "First matching" and "Last matching IP" values to cover desired LAN range (e.g., 192.168.0.1 and 192.168.0.254) → set "Action" to Allow → click OK

  3. Click Add… → set "First matching" to 0.0.0.0 and "Last matching IP" to 255.255.255.255 → set "Action" to Deny → click OK

  4. Click Apply

  5. Optionally adjust local and remote IP address scope for TightVNC's default inbound rule in Windows Defender Firewall with Advanced Security; see Restrict Windows Remote Desktop connections to LAN only.

/windows | Aug 31, 2024

Restrict Windows Remote Desktop connections to LAN only #

  1. Open Windows Defender Firewall with Advanced Security (Win+R → wf.msc → Enter)

  2. Click "Inbound Rules" under "Windows Defender Firewall with Advanced Security on Local Computer"

  3. For each Remote Desktop entry, double click to open Properties then select the "Scope" tab

  4. Under "Remote IP address" select "These IP addresses:"

  5. Click Add…

  6. Select "Predefined set of computers", choose "Local subnet", then click OK twice

Thanks to @void_in for the pointer.

/windows | Aug 31, 2024

Burning ISO images to CD or DVD on a Mac in 2024 #

Although disc burning was removed from Disk Utility in OS X 10.11 El Capitan, two native methods and a venerable open-source app still work even in macOS Sonoma:

/mac | Aug 30, 2024

Separate vocal & instrumental tracks #

with Demucs, an open source "state-of-the-art music source separation model, currently capable of separating drums, bass, and vocals from the rest of the accompaniment."

  1. Install: pip3 install demucs soundfile

  2. Run: /path/to/demucs --two-stems=vocals --out=/path/to/output_dir/ /path/to/audio.flac

  3. Listen: Find vocals.wav & no_vocals.wav inside output_dir/audio/.

Notes

/mac | Aug 28, 2024

Installing exFAT for FUSE on Apple silicon #

My meager guide to mounting exFAT partitions with unsupported cluster sizes in macOS clearly needed a dollop of detail. The following steps were tested in macOS 14.6.1 with macFUSE 4.8.0 and exFAT 1.4.0:

1. Enable kernel extensions

(Though required as of Sonoma, Sequoia's FSKit (which implements a file system in user space) may render this unnecessary. In the meantime, Apple warns: "Kexts are no longer recommended for macOS. Kexts risk the integrity and reliability of the operating system. Users should prefer solutions that don’t require extending the kernel and use system extensions instead.")

  1. Start up in macOS Recovery

  2. Click Options → Continue Utilities → Startup Security Utility → Security Policy...

  3. Change from "Full Security" to "Reduced Security" → enable "Allow user management of kernel extensions from identified developers" → click OK → enter password → click OK → Restart

2. Install macFUSE

  1. Download and run the PKG installer (Universal binary that supports macOS 10.9 through 14(!))

  2. When "System Extension Blocked" appears, click "Open System Settings"

  3. Click "Allow" under "System software from developer 'Benjamin Fleischer' was blocked from loading." → enter password twice when prompted → click "Restart"

3. Install Homebrew

  1. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

4. Install autoconf, automake, & pkg-config

  1. brew install autoconf automake pkg-config

5. Download and compile exFAT for FUSE

  1. git clone https://github.com/relan/exfat.git && cd exfat && autoreconf --install && ./configure && make

  2. While installing to /usr/local/sbin/ is possible via sudo make install, running from the fuse subdirectory after compiling is fine, e.g., sudo ./fuse/mount.exfat-fuse /dev/disk2s2 ~/mnt

6. Removal

  1. exFAT for FUSE: If you opted to install in step 5.2, run sudo make uninstall from the exfat directory. Otherwise, simply delete the exfat directory created in step 5.1.

  2. Homebrew:

    1. Uninstall packages installed via brew: brew list | xargs brew uninstall --force

    2. Clean up any remaining files: brew cleanup --prune=all

    3. Uninstall Homebrew: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"

    4. If you ran (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/yourusername/.zprofile and eval "$(/opt/homebrew/bin/brew shellenv)" as instructed after the Homebrew installation completed, you may also want to remove eval "$(/opt/homebrew/bin/brew shellenv)" from ~/.zprofile or simply delete ~/.zprofile altogether if there are no other lines in it.

  3. macFUSE: Run /Extras/Uninstaller.app from the mounted DMG.

  4. Security Settings: Repeat steps 1.1 & 1.2, then switch "Reduced Security" back to "Full Security".

Notes

/mac | Aug 10, 2024

Windows freeware for annotating PDFs without watermark nags #

Windows lacks an equivalent to macOS's Preview app, but these free tools can handle simple PDF markup tasks:

Microsoft Edge

Mozilla Firefox (H/T: éric)

Foxit PDF Reader

Okular

/windows | Jul 10, 2024

New keyboard App Shortcuts for Messages not working in Sonoma #

Spent far too long trying to troubleshoot a new App Shortcut for Messages with commands like defaults find NSUserKeyEquivalents and mucking about with files such as com.apple.MobileSMS and .GlobalPreferences.plist before stumbling onto App Keyboard Shortcuts Don't Work in Sonoma. Newly-added App Shortcuts in Sonoma do not work for Messages.app; other tested apps (Calendar, Contacts, Dictionary) appear unaffected.

As jamesfromhaymarket points out, one workaround is to set the desired keyboard shortcut for All Applications instead of just Messages; assigning "Delete Conversation…" (press Opt+; for the ellipsis) to Cmd+D this way was successful.

/mac | Jun 23, 2024

Pause & highlight players in sports reels #

  1. Launch ActivePresenter 9 (free for trial and non-commercial use; watermark-free output)

  2. Click Open → select desired video

  3. Click on the time axis to reveal the playhead then drag it to the desired location

  4. Click the "Insert Time" icon on the timeline toolbar → enter desired duration (default is 2000 ms) → OK

  5. Click the Insert tab → Spotlight → use the crosshairs cursor in the video player to highlight the desired athlete

  6. Adjust the spotlight in the timeline by clicking and dragging its box or outer edges

  7. Optionally slow down or speed up frames:

    1. Define a range by clicking and dragging the green start marker and/or orange end marker on either side of the playhead
    2. Click the "Change Playback Speed" icon in the timeline toolbar
    3. Enter desired playback speed percentage (default is 200) → OK
    4. Double click anywhere on the time axis to clear the selection

ActivePresenter video timeline toolbar
Click to enlarge

Related

Sources

/misc | Jun 15, 2024

Batch concatenate MP4 videos with fade in/out transitions #

  1. Install MoviePy (pip3 install moviepy) and ffmpeg

  2. Edit Python script below, adjusting fade_duration and input_folder as desired, then save (e.g., combine_videos.py):

    import os
    from moviepy.editor import VideoFileClip, concatenate_videoclips
    
    def add_fade_effects(clips, duration=2):
        faded_clips = []
        for i, clip in enumerate(clips):
            if i != 0:
                clip = clip.set_start(clips[i-1].end)
                clip = clip.crossfadein(duration)
            clip = clip.fadein(duration).fadeout(duration)  # Apply fade-in and fade-out to each clip
            faded_clips.append(clip)
        return faded_clips
    
    def combine_videos_with_fades(input_folder, output_file, fade_duration=0.5):
        video_files = [os.path.join(input_folder, f) for f in sorted(os.listdir(input_folder)) if f.endswith('.mp4')]
        video_clips = [VideoFileClip(video) for video in video_files]
        video_clips = add_fade_effects(video_clips, fade_duration)
        final_clip = concatenate_videoclips(video_clips, method="compose")
        final_clip.write_videofile(output_file, codec="libx264")
    
    if __name__ == "__main__":
        input_folder = "/path/to/mp4s"  # Replace with the path to your folder containing MP4 files
        output_file = "combined_video_with_fades.mp4"
        combine_videos_with_fades(input_folder, output_file)
  3. Run python3 combine_videos.py

/nix | Jun 15, 2024


Subscribe or visit the archives.