PowerShell Anti-Idle Mouse Script

PowerShell Anti-Idle Mouse Script

Summary

A simple way to keep your system “active” with minimal side effects.

Add-Type @"
using System;
using System.Runtime.InteropServices;

public static class NativeInput
{
    [StructLayout(LayoutKind.Sequential)]
    public struct INPUT
    {
        public uint type;
        public InputUnion U;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct InputUnion
    {
        [FieldOffset(0)]
        public MOUSEINPUT mi;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MOUSEINPUT
    {
        public int dx;
        public int dy;
        public uint mouseData;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    [DllImport("user32.dll", SetLastError = true)]
    public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out POINT lpPoint);

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;
    }

    public const uint INPUT_MOUSE = 0;
    public const uint MOUSEEVENTF_MOVE = 0x0001;
}
"@

function Send-RelativeMouseMove {
    param(
        [int]$Dx,
        [int]$Dy
    )

    $input = New-Object NativeInput+INPUT
    $input.type = [NativeInput]::INPUT_MOUSE
    $input.U.mi.dx = $Dx
    $input.U.mi.dy = $Dy
    $input.U.mi.mouseData = 0
    $input.U.mi.dwFlags = [NativeInput]::MOUSEEVENTF_MOVE
    $input.U.mi.time = 0
    $input.U.mi.dwExtraInfo = [IntPtr]::Zero

    $arr = [NativeInput+INPUT[]]::new(1)
    $arr[0] = $input

    $sent = [NativeInput]::SendInput(
        1,
        $arr,
        [System.Runtime.InteropServices.Marshal]::SizeOf([type][NativeInput+INPUT])
    )

    if ($sent -eq 0) {
        $err = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
        Write-Warning "SendInput failed. Win32Error=$err"
    }
}

function Get-CursorPosition {
    $p = New-Object NativeInput+POINT
    [NativeInput]::GetCursorPos([ref]$p) | Out-Null
    return $p
}

$lastPos = Get-CursorPosition
$idleSeconds = 0

while ($true) {
    Start-Sleep -Seconds 1

    $currentPos = Get-CursorPosition

    if ($currentPos.X -eq $lastPos.X -and $currentPos.Y -eq $lastPos.Y) {
        $idleSeconds++
    }
    else {
        $idleSeconds = 0
        $lastPos = $currentPos
        continue
    }

    $lastPos = $currentPos

    if ($idleSeconds -ge 10) {
        $dx = Get-Random -Minimum -1 -Maximum 2
        $dy = Get-Random -Minimum -1 -Maximum 2

        if ($dx -eq 0 -and $dy -eq 0) {
            $dx = 1
        }

        Send-RelativeMouseMove -Dx $dx -Dy $dy

        Start-Sleep -Milliseconds 150

        Send-RelativeMouseMove -Dx (-$dx) -Dy (-$dy)

        $idleSeconds = 0
    }
}

Overview

This script keeps your system from going idle by simulating small, real mouse movements using the Windows SendInput API.

How It Works

  • Checks mouse position every second
  • If no movement for 10 seconds:
    • Moves the cursor slightly (±1 pixel)
    • Moves it back immediately
  • Uses SendInput, so the system treats it as real user input

Notes

  • Movement is minimal and usually unnoticeable
  • No keyboard input is used
  • May not work against all idle detection methods