Change the order of Windows shell command history retrieval

One of the things that drive me crazy in command line under MS-Windows is the order in which the Windows shell (both the standard one and PowerShell) retrieve commands from history when you use the up and down arrow keys.

The standard way I've grown to like, as it is done in basically all other shells in the world, is that the last command is put into the history stack, and then pressing up will retrieve the last command I ran, "up" again will retrieve the one from before that, and so on. If you choose a command from history and submit it again, the command is copied to the top of the stack and if you press up on the next prompt you can see that last command and then the command previous to last. If after browsing the history you press "down" past the most recent command in the history stack, you will be returned to your empty prompt (or whatever you had there before you started browsing history).

In Windows shell, it works weirdly different: if you have 3 commands in the history - for example lets call them "A", "B" and "C" - and you use the up arrow key to select command "B" and execute it again, and then use the up arrow key again on the next prompt, the shell will display "B". But this is not the last command you executed (though "B" was indeed copied to the history stack again) as if you press "up" again you will be shown "A" and not "C". If you browse down (to later entries) you will see "B" again, followed by "C" then followed by "B" again which was the last command entered - but you also can't go any further: there's no going back to an empty prompt except deleting whatever you have on the line or pressing CTRL-C.

My question - is there some setting that one can set to change this behavior?

I'm aware of the option of just getting bash or something like that and using it on Windows, but due to external constraints (as in - that's what I need to write my scripts in), I have to work in PowerShell or another Windows shell that can invoke PowerShell scripts.


There is a different way to control the history stack, it is not what you wanted but it is a different option you should check out.

In Properties (or Default) when you right click the top left corner there is an option "Discard Old Duplicates" tick it and the stack will change its behavior.

in your example performing "A", "B", "C". and then twice up to perform "B", the stack will look: "B","C","A" (first up will be "B")


Also, don't forget F7. This pops up a DOS-style menu showing command history (ESC to make it go away). The 'last' command either entered, or selected with up-arrow will be shown, so you immediately will see where you are in the up/down arrow context.

Apparently this is from something called DOSKEY, a poorly documented utility. For example, besides up, down, and then enter to execute the command, I have found that a right or left arrow key will put it at the prompt without executing (so you can edit it). PgUp/PgDn/Home/End will navigate through the list in the obvious way, and I just discovered (haven't seen it documented anywhere) that if you press the first letter of a command it will cycle through commands starting with that letter (so type a command like ze fun start now! to jump to that point in history easily by pressing z in teh F7).

Perhaps though, if one foresees the reliving much of history, may tis better to

doskey /history > editme.bat

than suffer the slings and arrows, and copy/paste from said record (or have thine minions fashion it into a script).

There's a couple other command prompt tricks in Joel Spolsky's article probably aren't widely known. I didn't know about the wildcard expansion, so you can use tab-completion by typing the last characters of a name, or the middle.

I find the windows prompt quaint, but consider it dead end, and only learn such trivia when it seems that it will reduce my interactiion with it. Given the opportunity I believe it is better to install cygwin to get a more expression shell and less annoying environment, and skills and scripts that you'll be able to use elsewhere.