[PowerShell Script] PowerDbg v6.0 – Using PowerShell to Control WinDbg

Last October the latest version of the PowerDbg tool was released, version 6.0. This release has major changes. For example, it is now easier to write scripts or otherwise just hack around the debugger, and includes the PowerDbgConsole, a bootstrapper designed to make setting up an interactive PowerDbg debugging session a one-liner. In addition, this new version is faster, easier to use, and has full 64 bit support.


For those new to PowerDbg, with this tool you can easily create PowerShell scripts to automate a WinDbg/CDB debugging session. You can use PowerDbg for Kernel Mode or User Mode, Post-Mortem Debugging or Live Debugging, either for native or managed code.


PowerShell has several advantages over the WinDbg Scripting Language, like:


      Increased ease in creating scripts

      Leverage in the .NET Framework

      Debugging and tracing features

      Code reuse through functions and cmdlets

      Easier maintenance

      Increased ease in building large scripts

      Ease in formatting and displaying important information



PowerDbg is hosted in the CodePlex website and there you can find all the information you need about the new PowerDbg, so I’m just reusing the information from CodePlex here.




Download PowerDbg.



In order to use PowerDbg you will need:

*      PowerShell 2

      This comes ‘out of the box’ with Windows 7 and Windows 2008 R2 (though it may not be enabled by default). For other versions of Windows it can be obtained by installing the Windows Management Framework Core Package

*     A recent version of the Debugging Tools for Windows.
Most of the testing has been done against the version that comes with the
Windows SDK 7.1 and the previous stand-alone version (x86 / x64).

You’ll also need to configure PowerShell to allow scripting, which is disabled by default. Typically you’d relax the execution policy to allow unsigned scripts to run from the local machine (only) [1]:

Set-ExecutionPolicy RemoteSigned

If UAC is enabled you’ll need to do this from a PowerShell prompt ‘run as administrator’.

If you’re running 64 bit Windows and plan on doing any 32 bit debugging, you’ll also need to do this in the 32 bit PowerShell console (Windows PowerShell (x86) in your Start menu).



After downloading, extract the PowerDbg.zip to a temporary directory somewhere, and use the Install_PowerDbg.ps1 script to install it: just right click on it and select ‘Run With PowerShell’.

Alternatively, you can manually drop the PowerDbg.psm1 module file into your PowerShell module directory, ensuring it gets placed in a ‘PowerDbg’ subfolder.


Establishing a PowerDbg Session


To use PowerDbg you must first establish a ‘session’. This establishes PowerDbg’s internal connection between a local debugger and either a memory dump, live process, or remote debugger.

Sessions are established using the New-DbgSession cmdlet and can be instantiated in one of four ways:

– attaching to a running process by name (-process)
– launching a process under the debugger (-command)
– opening a memory dump in the debugger (-dump)
– connecting to an existing debugger configured as a server (-remote)

Additionally, PowerDbg can be instructed to auto-load SOS (if possible), using the -sos parameter. This can only be performed if the process in question has already loaded the CLR, and so is not applicable to the -command method.


The PowerDbg ‘unhandled exception’ demo can be run under the debugger as follows (note the quotes which allow us to pass an argument to the process being launched):

PS > New-DbgSession -command ‘.\blah\ManagedScenarios.exe UnhandledExceptionScenario’

PS > Send-DbgGo

(1104.730): CLR exception – code e0434f4d (first chance)

(1104.730): CLR exception – code e0434f4d (!!! second chance !!!)


000007fe`fdedaa7d 4881c4c8000000  add     rsp,0C8h

PS >

Since the debugger immediately breaks into the launched process, we have to use
Send-DbgGo to allow the process to continue on (and subsequently fail). When creating a session to a memory dump or a remote debugger already halted at the point of interest, this would be unnecessary.

Once a PowerDbg session exists, you can interact with it using any of the Get-Dbg* cmdlets, or by using Invoke-DbgCommand to send commands directly.


*     Each PowerShell window running PowerDbg can only support one such session at a time.

*     The session is automatically terminated when the PowerDbg module is unloaded (Remove-Module PowerDbg).

*     The debugger is attached invasively, and so the debuggee will terminate when the session is ended.


Some Commands

Session Management


Establishes a PowerDbg session with the debugger


Terminates the current PowerDbg session


Loads a debugger extension into the active session


Executes an arbitrary command against the debugger



Expands the contents of a managed array


Locates objects on the managed heap by type or MT


Enumerates Dictionary<T,T> collections


Enumerates List<T> collections


Views the contents of a reference-type object


Views the contents of a value-type object

Process State


Lists managed threads


Views the COM apartment state associated with each thread


Lists modules loaded into the process


Views the kernel and user time associated with each thread



Sorts all threads by CPU (User Mode) and writes in red all threads which are using third-party components, an easy way to isolate threads consuming high CPU.



Launches a debugger without creating a PowerDbg session


Takes an immediate full minidump of a given process


The new PowerDbg is the effort of a great team of people from different companies and different parts of the world. Particularly for me it’s always exciting to work with people from all over the world.

With that said, I want to thank everybody who worked in this project, especially:


I want to thank Lee Holmes (SDE from the PowerShell team) for all his support and valuable tips since the first versions of PowerDbg.


I also want to thank Augusto Pedroza (SDE from the Windows 8 FileSystem team) for using PowerShell in real Microsoft scenarios and for giving valuable feedback on how to improve the tool. (Obrigado Augusto! J)


Finally, I want to send a very special thanks to Piers Williams, who not only contributed with awesome ideas but added hundreds of lines of code to PowerDbg, worked on the documentation, and turned the PowerDbg project into one in which others can easily contribute.


We are looking for developers to join the PowerDbg project. If you’re interested, use the CodePlex site and join us!


Comments (7)

  1. FlySky says:

    Heya Roberto,

    I am starting to play around a bit more with WinDBG scripting. Are there any books on WinDBG scripting. I am messing with a script on which I want to read from EIP but it has to continue executing commands unless eip holds the value I am looking for

    It goes like this:

    r $t2 = by(eip) –> here it reads the byte value in eip


    .if $t2 = 50


    When 50 do this code




    When not 50 do this code.


    This works only ones. Is there anyway to keep it executing unless it's 50??

    Myabe you can point me to some books to read about.

    best regards,


  2. rafarah says:

    Hi FlySky,

    Two mistakes with the code above:

    1- Like C/C++ to compare you must use two "=" signs.

    2- If you are comparing a decimal number you must specify that.


    0:000> r @$t2 = by(@eip)

    0:000> r @$t2


    So our $t2 has 0xC3 stored in it.

    0xC3 = 0n195 😉

    Comparing 0n50 against 0n195:

    0:000> .if (0n50 == @$t2) { .echo Same value } .else { .echo Wrong value }

    Wrong value

    Comparing 0n195 against 0n195:

    0:000> .if (0n195 == @$t2) { .echo Same value } .else { .echo Wrong value }

    Same value

    Comparing 0xC3 against 0n195:

    0:000> .if (0xC3 == @$t2) { .echo Same value } .else { .echo Wrong value }

    Same value

    Comparing 195 (assumed to be Hexa by default and not Decimal) against 0n195:

    0:000> .if (195 == @$t2) { .echo Same value } .else { .echo Wrong value }

    Wrong value

    Got it? 🙂


  3. FlySky says:

    Thanks for the explanation, this indeed makes sense 😉 Gonna experiment on it, also bought me the book about Powershell, gonna read and learn that aswell.

    You know of any books specificially explaining WinDBG scripting?

    Thanks for your help so far much appreciated, keep up this excellent blog.

  4. rafarah says:

    Thanks! 🙂

    If you go to the Books section of my blog there are many debugging books listed there. Dmitry Vostokov and myself are finishing a book based on the Special Commands section of this blog that talks about WinDbg scripts. http://www.amazon.com/…/ref=sr_1_1

    Also, you may want to read this blog article:



  5. FlySky says:

    Thanks for the good suggestions Roberto.

    If I use the following :

    r $t3 = (@eip)

    # ffd0 @$t3

    It will find the instruction Call eax,. Is it possible to read the result into a psuedo register and do another search?,

    it's printing the resulting address into the command window , I would like to read it in a pseudo register.

    r $t4 = # ffd0 @$t3

    keeps erroring with character errors:


  6. Rudra says:

    Hi Roberto,

                 I normally use windbg to debug dump. Your tool sounds interesting. Beside writing scripts and formatting display how it is different  from normal windbg. Can you please provide your inputs.


  7. rafarah says:

    Hi Rudra,

    WinDbg scripts and PowerDbg are just a way to automate the debugging session via scripts. With PowerDbg you use PowerShell. http://powerdbg.codeplex.com/

    Source Code for PowerDbg: powerdbg.codeplex.com/…/79996

    There other tools which do that too and have a nice interface are:

    Debug Analyzer – http://debuganalyzer.net/

    Debug Diag – http://www.microsoft.com/…/details.aspx