Skip to content

Instantly share code, notes, and snippets.

@777genius
Last active October 1, 2025 13:59
Show Gist options
  • Select an option

  • Save 777genius/8ca0a71b1fe23805159a7505814ffd33 to your computer and use it in GitHub Desktop.

Select an option

Save 777genius/8ca0a71b1fe23805159a7505814ffd33 to your computer and use it in GitHub Desktop.
param(
[int]$MouseJitterPx = 12,
[int]$ClickTestCount = 1,
[switch]$SkipNotepad
)
function Try-Run {
param([string]$Name, [scriptblock]$Code)
$ok = $true; $out = ""
try { $val = & $Code; if ($null -ne $val) { $out = ($val | Out-String) } }
catch { $ok = $false; $out = ($_ | Out-String) }
[pscustomobject]@{ name = $Name; ok = $ok; output = ($out -replace '\s+$','') }
}
$report = [ordered]@{}
function Add-Section { param([string]$k, $v) $script:report[$k] = $v }
# 1) System
Add-Section "System" @(
(Try-Run "OS" { [System.Environment]::OSVersion | Format-List * })
(Try-Run "Machine" { "MachineName=$([Environment]::MachineName); User=$([Environment]::UserName)" })
(Try-Run "Bitness" { "Is64BitOS=$([Environment]::Is64BitOperatingSystem); Is64BitProcess=$([Environment]::Is64BitProcess)" })
(Try-Run "EnvArch" { "PROCESSOR_ARCHITECTURE=$env:PROCESSOR_ARCHITECTURE; PROCESSOR_ARCHITEW6432=$env:PROCESSOR_ARCHITEW6432; SystemRoot=$env:SystemRoot; WINDIR=$env:WINDIR" })
)
# 2) PowerShell
Add-Section "PowerShell" @(
(Try-Run "PSVersionTable" { $PSVersionTable | Format-List * })
(Try-Run "ExecutionPolicy" { Get-ExecutionPolicy -List | Format-Table -Auto | Out-String })
(Try-Run "IsAdmin" { [bool]([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) })
)
# 3) Shell paths
$sysRoot = $env:SystemRoot; if (-not $sysRoot) { $sysRoot = $env:WINDIR }
Add-Section "ShellPaths" @(
(Try-Run "Get-Command pwsh,powershell" { Get-Command pwsh,powershell -ErrorAction SilentlyContinue | Select-Object Name,Path,Version | Format-Table -Auto | Out-String })
(Try-Run "TypicalPaths" {
$paths = @(
"C:\Program Files\PowerShell\7\pwsh.exe",
"C:\Program Files\PowerShell\7-preview\pwsh.exe",
(Join-Path $sysRoot "System32\WindowsPowerShell\v1.0\powershell.exe"),
(Join-Path $sysRoot "Sysnative\WindowsPowerShell\v1.0\powershell.exe"),
(Join-Path $sysRoot "SysWOW64\WindowsPowerShell\v1.0\powershell.exe")
)
$paths | ForEach-Object { "{0} = {1}" -f $_, (Test-Path $_) }
})
)
# 4) APIs
Add-Section "APIs" @(
(Try-Run "cscript" { Get-Command cscript -ErrorAction SilentlyContinue | Select-Object Path | Format-Table -Auto | Out-String })
(Try-Run "COM_WScriptShell" { $ws = New-Object -ComObject WScript.Shell; "OK: $($ws -ne $null)" })
(Try-Run "LoadForms" { Add-Type -AssemblyName System.Windows.Forms; "OK" })
(Try-Run "LoadDrawing" { Add-Type -AssemblyName System.Drawing; "OK" })
)
# 5) Key tests (SendKeys)
Add-Section "KeyTests_SendKeys" @(
(Try-Run "SendKeys_Hello123" {
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait("Hello123"); "OK (sent Hello123)"
})
)
# 6) VBScript key test
Add-Section "KeyTests_VBScript" @(
(Try-Run "VBScript_SendKeys" {
$tmp = Join-Path $env:TEMP "sendkeys_diag.vbs"
@'
Set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Sleep 200
WshShell.SendKeys "Hello via VBS"
'@ | Out-File -FilePath $tmp -Encoding ASCII -Force
try { & cscript //nologo $tmp | Out-Null; "OK (VBS ran)" } finally { Remove-Item $tmp -Force -ErrorAction SilentlyContinue }
})
)
# 7) SendInput (UNICODE) - 'A'
Add-Section "KeyTests_SendInput" @(
(Try-Run "SendInput_A" {
$code = @"
using System;
using System.Runtime.InteropServices;
public static class Kbd {
[StructLayout(LayoutKind.Sequential)] public struct INPUT { public int type; public INPUTUNION U; }
[StructLayout(LayoutKind.Explicit)] public struct INPUTUNION { [FieldOffset(0)] public KEYBDINPUT ki; }
[StructLayout(LayoutKind.Sequential)] public struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; }
[DllImport("user32.dll")] public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
public const int INPUT_KEYBOARD = 1;
public const uint KEYEVENTF_UNICODE = 0x0004;
public const uint KEYEVENTF_KEYUP = 0x0002;
public static void SendUnicode(ushort ch) {
INPUT down = new INPUT(); down.type = INPUT_KEYBOARD; down.U.ki.wScan = ch; down.U.ki.wVk = 0; down.U.ki.dwFlags = KEYEVENTF_UNICODE;
INPUT up = new INPUT(); up.type = INPUT_KEYBOARD; up.U.ki.wScan = ch; up.U.ki.wVk = 0; up.U.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, ref down, Marshal.SizeOf(down));
SendInput(1, ref up, Marshal.SizeOf(up));
}
}
"@
if (-not ('Kbd' -as [type])) { Add-Type -TypeDefinition $code -Language CSharp -IgnoreWarnings }
[Kbd]::SendUnicode(0x0041)
"OK (sent 'A')"
})
)
# 8) Notepad test (PID)
if (-not $SkipNotepad) {
Add-Section "NotepadTest" @(
(Try-Run "StartNotepad" { $p = Start-Process notepad -PassThru; Start-Sleep -Milliseconds 500; "PID=$($p.Id)"; $script:npid = $p.Id })
(Try-Run "COM_ActivateAndType" {
$ws = New-Object -ComObject WScript.Shell
$ok = $ws.AppActivate([int]$script:npid)
Start-Sleep -Milliseconds 200
if ($ok) { $ws.SendKeys("Hello via COM"); "OK (COM sent by PID)" } else { "WARN: AppActivate failed" }
})
(Try-Run "StopNotepad" {
Get-Process -Id $script:npid -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
"Stopped"
})
)
}
# 9) Mouse tests
Add-Section "MouseTests" @(
(Try-Run "JitterMove" {
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$p=[System.Windows.Forms.Cursor]::Position
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($p.X+$MouseJitterPx,$p.Y)
Start-Sleep -Milliseconds 50
[System.Windows.Forms.Cursor]::Position = $p
"OK (moved +$MouseJitterPx px and back)"
})
(Try-Run "ClickCenter" {
if ($ClickTestCount -le 0) { return "Skipped" }
$sig = @"
using System;
using System.Runtime.InteropServices;
public static class Clicker{
[DllImport("user32.dll")] public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, IntPtr dwExtraInfo);
public const uint LEFTDOWN=0x0002; public const uint LEFTUP=0x0004;
}
"@
Add-Type -TypeDefinition $sig -Language CSharp -IgnoreWarnings | Out-Null
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$b=[System.Windows.Forms.Screen]::PrimaryScreen.Bounds
$cx=[int]($b.X + ($b.Width/2)); $cy=[int]($b.Y + ($b.Height/2))
$prev=[System.Windows.Forms.Cursor]::Position
for($i=0;$i -lt $ClickTestCount;$i++){
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($cx,$cy)
[Clicker]::mouse_event([Clicker]::LEFTDOWN,0,0,0,[IntPtr]::Zero)
Start-Sleep -Milliseconds 10
[Clicker]::mouse_event([Clicker]::LEFTUP,0,0,0,[IntPtr]::Zero)
Start-Sleep -Milliseconds 100
}
[System.Windows.Forms.Cursor]::Position = $prev
"OK (clicked $ClickTestCount x at center)"
})
)
"`n==== TEXT SUMMARY ===="
$report.Keys | ForEach-Object {
"`n>>> $_"
$section = $report[$_]
foreach ($item in $section) {
"[{0}] ok={1}`n{2}" -f $item.name, $item.ok, $item.output
}
}
"`n==== JSON (copy this to share) ===="
$report | ConvertTo-Json -Depth 6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment