Skip to content

Instantly share code, notes, and snippets.

@wrouesnel
Last active March 6, 2025 10:08
Show Gist options
  • Save wrouesnel/b0785c7724cb15bd924046056fe9faa5 to your computer and use it in GitHub Desktop.
Save wrouesnel/b0785c7724cb15bd924046056fe9faa5 to your computer and use it in GitHub Desktop.
Clipboard Typer in Powershell - Types the contents of the clipboard into the targeted window
Add-Type -AssemblyName System.Windows.Forms
Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Text;
public class APIFuncs {
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowText(IntPtr hwnd,StringBuilder lpString, int cch);
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd,out Int32 lpdwProcessId);
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern Int32 GetWindowTextLength(IntPtr hWnd);
[DllImport("User32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint uMsg, int wParam, string lParam);
[DllImport("user32.dll", SetLastError = true, CharSet=CharSet.Auto)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true, CharSet=CharSet.Auto)]
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
[DllImport("user32.dll", SetLastError = true, CharSet=CharSet.Auto)]
public static extern void SetActiveWindow(IntPtr hwnd);
}
"@
# Define constants
$WM_KEYDOWN = 0x0100
$WM_KEYUP = 0x0101
$WM_CHAR = 0x0102
# If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224).
$KEYEVENTF_EXTENDEDKEY = 0x0001
# If specified, the key is being released. If not specified, the key is being depressed.
$KEYEVENTF_KEYUP = 0x0002
$VK_TAB = 0x09
$VK_SHIFT = 0x10
$VK_RETURN = 0x0D
$virtualKeyCodes = New-Object System.Collections.Hashtable
$virtualKeyCodes['1'] = @(0x31)
$virtualKeyCodes['2'] = @(0x32)
$virtualKeyCodes['3'] = @(0x33)
$virtualKeyCodes['4'] = @(0x34)
$virtualKeyCodes['5'] = @(0x35)
$virtualKeyCodes['6'] = @(0x36)
$virtualKeyCodes['7'] = @(0x37)
$virtualKeyCodes['8'] = @(0x38)
$virtualKeyCodes['9'] = @(0x39)
$virtualKeyCodes['0'] = @(0x30)
$virtualKeyCodes['!'] = @($VK_SHIFT, 0x31)
$virtualKeyCodes['@'] = @($VK_SHIFT, 0x32)
$virtualKeyCodes['#'] = @($VK_SHIFT, 0x33)
$virtualKeyCodes['$'] = @($VK_SHIFT, 0x34)
$virtualKeyCodes['%'] = @($VK_SHIFT, 0x35)
$virtualKeyCodes['^'] = @($VK_SHIFT, 0x36)
$virtualKeyCodes['&'] = @($VK_SHIFT, 0x37)
$virtualKeyCodes['*'] = @($VK_SHIFT, 0x38)
$virtualKeyCodes['('] = @($VK_SHIFT, 0x39)
$virtualKeyCodes[')'] = @($VK_SHIFT, 0x30)
$virtualKeyCodes['a'] = @(0x41)
$virtualKeyCodes['b'] = @(0x42)
$virtualKeyCodes['c'] = @(0x43)
$virtualKeyCodes['d'] = @(0x44)
$virtualKeyCodes['e'] = @(0x45)
$virtualKeyCodes['f'] = @(0x46)
$virtualKeyCodes['g'] = @(0x47)
$virtualKeyCodes['h'] = @(0x48)
$virtualKeyCodes['i'] = @(0x49)
$virtualKeyCodes['j'] = @(0x4A)
$virtualKeyCodes['k'] = @(0x4B)
$virtualKeyCodes['l'] = @(0x4C)
$virtualKeyCodes['m'] = @(0x4D)
$virtualKeyCodes['n'] = @(0x4E)
$virtualKeyCodes['o'] = @(0x4F)
$virtualKeyCodes['p'] = @(0x50)
$virtualKeyCodes['q'] = @(0x51)
$virtualKeyCodes['r'] = @(0x52)
$virtualKeyCodes['s'] = @(0x53)
$virtualKeyCodes['t'] = @(0x54)
$virtualKeyCodes['u'] = @(0x55)
$virtualKeyCodes['v'] = @(0x56)
$virtualKeyCodes['w'] = @(0x57)
$virtualKeyCodes['x'] = @(0x58)
$virtualKeyCodes['y'] = @(0x59)
$virtualKeyCodes['z'] = @(0x5A)
$virtualKeyCodes['A'] = @($VK_SHIFT,0x41)
$virtualKeyCodes['B'] = @($VK_SHIFT,0x42)
$virtualKeyCodes['C'] = @($VK_SHIFT,0x43)
$virtualKeyCodes['D'] = @($VK_SHIFT,0x44)
$virtualKeyCodes['E'] = @($VK_SHIFT,0x45)
$virtualKeyCodes['F'] = @($VK_SHIFT,0x46)
$virtualKeyCodes['G'] = @($VK_SHIFT,0x47)
$virtualKeyCodes['H'] = @($VK_SHIFT,0x48)
$virtualKeyCodes['I'] = @($VK_SHIFT,0x49)
$virtualKeyCodes['J'] = @($VK_SHIFT,0x4A)
$virtualKeyCodes['K'] = @($VK_SHIFT,0x4B)
$virtualKeyCodes['L'] = @($VK_SHIFT,0x4C)
$virtualKeyCodes['M'] = @($VK_SHIFT,0x4D)
$virtualKeyCodes['N'] = @($VK_SHIFT,0x4E)
$virtualKeyCodes['O'] = @($VK_SHIFT,0x4F)
$virtualKeyCodes['P'] = @($VK_SHIFT,0x50)
$virtualKeyCodes['Q'] = @($VK_SHIFT,0x51)
$virtualKeyCodes['R'] = @($VK_SHIFT,0x52)
$virtualKeyCodes['S'] = @($VK_SHIFT,0x53)
$virtualKeyCodes['T'] = @($VK_SHIFT,0x54)
$virtualKeyCodes['U'] = @($VK_SHIFT,0x55)
$virtualKeyCodes['V'] = @($VK_SHIFT,0x56)
$virtualKeyCodes['W'] = @($VK_SHIFT,0x57)
$virtualKeyCodes['X'] = @($VK_SHIFT,0x58)
$virtualKeyCodes['Y'] = @($VK_SHIFT,0x59)
$virtualKeyCodes['Z'] = @($VK_SHIFT,0x5A)
$virtualKeyCodes['-'] = @(0xBD)
$virtualKeyCodes['_'] = @($VK_SHIFT, 0xBD)
$virtualKeyCodes['='] = @(0xBB)
$virtualKeyCodes['+'] = @($VK_SHIFT, 0xBB)
$virtualKeyCodes["'"] = @(0xDE)
$virtualKeyCodes['"'] = @($VK_SHIFT, 0xDE)
$virtualKeyCodes[','] = @(0xBC)
$virtualKeyCodes['<'] = @($VK_SHIFT, 0xBC)
$virtualKeyCodes['.'] = @(0xBE)
$virtualKeyCodes['>'] = @($VK_SHIFT, 0xBE)
$virtualKeyCodes['/'] = @(0xBF)
$virtualKeyCodes['?'] = @($VK_SHIFT, 0xBF)
$virtualKeyCodes[';'] = @(0xBA)
$virtualKeyCodes[':'] = @($VK_SHIFT, 0xBA)
$virtualKeyCodes['['] = @(0xDB)
$virtualKeyCodes['{'] = @($VK_SHIFT, 0xDB)
$virtualKeyCodes[']'] = @(0xDD)
$virtualKeyCodes['}'] = @($VK_SHIFT,0xDD)
$virtualKeyCodes['\'] = @(0xDC)
$virtualKeyCodes['|'] = @($VK_SHIFT, 0xDC)
$virtualKeyCodes['`'] = @(0xC0)
$virtualKeyCodes['~'] = @($VK_SHIFT, 0xC0)
$virtualKeyCodes[' '] = @(0x20)
$virtualKeyCodes["`t"] = @(0x09)
$virtualKeyCodes["`n"] = @(0x0D)
# Function to send a specific key
function Send-Key($windowHandle, $keyChar) {
# Check if we have a virtual key code for this character
if ($virtualKeyCodes.ContainsKey($keyChar)) {
$vKey = $virtualKeyCodes[$keyChar].Clone()
#Write-Host "Sending key '$keyChar' (virtual key code: $vKey) to the window $windowHandle..."
foreach ($keyCode in $vKey) {
#Write-Host "Press: $keyCode"
[APIFuncs]::keybd_event($keyCode, 0, 0, [UIntPtr]::new(0)) | Out-Null
Start-Sleep 0.1
}
[Array]::Reverse($vKey)
foreach ($keyCode in $vKey) {
#Write-Host "Release: $keyCode"
[APIFuncs]::keybd_event($keyCode, 0, $KEYEVENTF_KEYUP, [UIntPtr]::new(0)) | Out-Null
Start-Sleep 0.1
}
return $true
}
else {
Write-Host "No virtual key code defined for character '$keyChar'"
return $false
}
}
# Get the current foreground window which should be the powershell script.
$initialForegroundWindow = [APIFuncs]::GetForegroundWindow()
$nextForegroundWindow = $initialForegroundWindow
while (($nextForegroundWindow -eq $initialForegroundWindow) -or ($nextForegroundWindow -eq 0)) {
$nextForegroundWindow = [APIFuncs]::GetForegroundWindow()
Start-Sleep 0.1
}
$text = Get-Clipboard -Raw
# Ensure we stick to the active window
while ([APIFuncs]::GetForegroundWindow() -ne $nextForegroundWindow) {
[APIFuncs]::SetActiveWindow($nextForegroundWindow) | Out-Null
}
# This sleep is necessary because at least in Notepad when the window is selected it's not actually
# ready to receive input. I have no idea how to fix this since we're already bashing keys into the system.
Start-Sleep 1
foreach ($char in [char[]]$text) {
Send-Key $nextForegroundWindow $char.ToString() | Out-Null
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment