param(
[Parameter(Mandatory=$true)]
[string]$Text,
[int]$DelaySeconds = 5,
[switch]$EnterAfter,
[string]$AppTitle, # optional: exact window title to focus
[ValidateSet('SendInput','Paste','Auto')]
[string]$Method = 'Auto'
)
# --- Win32 helpers: SetForegroundWindow + SendInput (raw Unicode) ---
Add-Type -TypeDefinition @"
using System;
using System.Text;
using System.Runtime.InteropServices;
public static class WinApi {
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError=true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError=true)]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[StructLayout(LayoutKind.Sequential)]
struct INPUT { public uint type; public InputUnion U; }
[StructLayout(LayoutKind.Explicit)]
struct InputUnion {
[FieldOffset(0)] public KEYBDINPUT ki;
[FieldOffset(0)] public MOUSEINPUT mi;
[FieldOffset(0)] public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; }
struct MOUSEINPUT { public int dx,dy; public uint mouseData,dwFlags,time; public IntPtr dwExtraInfo; }
struct HARDWAREINPUT { public uint uMsg,wParamL,wParamH; }
[DllImport("user32.dll", SetLastError=true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
const uint INPUT_KEYBOARD=1, KEYEVENTF_UNICODE=0x0004, KEYEVENTF_KEYUP=0x0002;
const ushort VK_CONTROL=0x11, VK_V=0x56, VK_RETURN=0x0D;
static void SendUnicodeChar(char c){
INPUT down=new INPUT(); down.type=INPUT_KEYBOARD; down.U.ki.wScan=c; down.U.ki.dwFlags=KEYEVENTF_UNICODE;
INPUT up=new INPUT(); up.type=INPUT_KEYBOARD; up.U.ki.wScan=c; up.U.ki.dwFlags=KEYEVENTF_UNICODE|KEYEVENTF_KEYUP;
INPUT[] arr=new INPUT[]{down,up};
SendInput((uint)arr.Length, arr, System.Runtime.InteropServices.Marshal.SizeOf(typeof(INPUT)));
}
static void SendVk(ushort vk, bool up){
INPUT i=new INPUT(); i.type=INPUT_KEYBOARD; i.U.ki.wVk=vk; i.U.ki.dwFlags=up?KEYEVENTF_KEYUP:0;
SendInput(1, new INPUT[]{ i }, System.Runtime.InteropServices.Marshal.SizeOf(typeof(INPUT)));
}
public static void TypeString(string s){
foreach(char c in s) SendUnicodeChar(c);
}
public static void PressEnter(){
SendVk(VK_RETURN, false); SendVk(VK_RETURN, true);
}
public static void Paste(){
SendVk(VK_CONTROL,false); SendVk(VK_V,false); SendVk(VK_V,true); SendVk(VK_CONTROL,true);
}
public static bool FocusExactTitle(string title){
IntPtr h = FindWindow(null, title);
if (h==IntPtr.Zero) return false;
ShowWindow(h, 5); // SW_SHOW
return SetForegroundWindow(h);
}
}
"@
# --- Optionally focus a specific window (exact title) ---
if ($AppTitle) {
$focused = [WinApi]::FocusExactTitle($AppTitle)
if (-not $focused) { Write-Host "⚠️ Window titled '$AppTitle' not found. Continuing without focusing."; }
}
Write-Host "⏳ You have $DelaySeconds second(s) to click/focus the target box..."
Start-Sleep -Seconds $DelaySeconds
# --- Choose method ---
if ($Method -eq 'Auto') {
# If the text is very long or contains lots of SendKeys-problem chars, paste is safer.
if ($Text.Length -gt 200 -or $Text -match '[\{\}\+\%\^\~\(\)]') { $Method='Paste' } else { $Method='SendInput' }
}
switch ($Method) {
'SendInput' {
[WinApi]::TypeString($Text)
if ($EnterAfter) { [WinApi]::PressEnter() }
}
'Paste' {
# Clipboard paste avoids any special-char interpretation entirely
Set-Clipboard -Value $Text
[WinApi]::Paste()
if ($EnterAfter) { [WinApi]::PressEnter() }
}
}
Save as Type-Text.ps1, then run:
.\Type-Text.ps1 -Text ‘MyP@ss;word123’ -DelaySeconds 5 -EnterAfter
$ws = New-Object -ComObject WScript.Shell
Start-Sleep 5
$ws.SendKeys("}}}}") # results in: }}