1

First, I'm in PowerShell and I've entered the doskey /exename=powershell.exe option.

Second, I did something that I now realize doesn't quite work:

doskey envpath=$env:Path -split ';' 

The goal was to have it print the path environment variable (whatever it is at the time I later enter envpath). However, it seems to have evaluated $env:Path while defining the macro, so the macro now appears to be all the paths in my path environment variable followed by '-split ;'. So that's a problem, but only listed here for context. I'll figure that out separately. The purpose of this question (one question per post) is the following:

I was following this and getting something weird...

If I now enter doskey /macros:all I get:


    "envpath=C:\WINDOWS\system32;C:\WINDOWS;<etc>;" -split ;

Please note the quotes.

Now, if, per the above-linked other answer, I enter doskey envpath=something (literally) then doskey /macros:all returns:


    "envpath=C:\WINDOWS\system32;C:\WINDOWS;<etc>;" -split ;
    envpath=something

(which is expected except for the quoted part).

And when I do doskey envpath= it clears/deletes that macro, and doskey /macros:all, returns the first result again.

So my question: What is this entry in the quotes and how do I get rid of that please?

Hopefully I've explained that clearly enough. If confused please feel free to ask for clarification. Thanks in advance for help!

mklement0
  • 382,024
  • 64
  • 607
  • 775
DavidT
  • 655
  • 7
  • 19
  • there's no reason to use doskey when PowerShell already has the excellent PSReadLine (counter part of the wonderful bash [readline](https://www.gnu.org/software/bash/manual/html_node/Readline-Interaction.html)). PowerShell also has profiles, functions, aliases similar to bash so it can do everything `doskey` can and far more – phuclv Jun 27 '22 at 00:23
  • @phuclv So before now, I'd never heard of PSReadLine. I guess I should look into that. Might take some time, while a quick and dirty solution for now will suffice. But noted to look into it. Thanks for the tip! – DavidT Jun 27 '22 at 16:12
  • @DavidT, both the answer here and the one to your follow-up question advise against using `doskey.exe` in PowerShell, and provide a brief rationale as well as links to detailed information. The answer here shows how to make `doskey.exe` work nonetheless, if you so choose - at the expense of losing much of PowerShell's own, rich command-line editing experience, provided by the `PSReadLine` module, which is incompatible with `doskey.exe`. The linked answer shows you the arguably preferable PowerShell-idiomatic alternative to `doskey.exe`. Do you have any further questions? – mklement0 Jun 28 '22 at 02:53

1 Answers1

0

As noted in the answer to your related question,

  • it's best to avoid use of doskey.exe in PowerShell, because getting it to work requires forgoing PowerShell's own, rich command-line editing experience, by unloading the PSReadLine module first (Remove-Module PSReadLine) - see this answer for background information.

  • the better alternative is to define a PowerShell function and add it to your $PROFILE file, as shown in the linked answer.


If you want to use doskey.exe nonetheless, define your macro as follows (for PowerShell (Core) 7+, replace powershell.exe with pwsh.exe):

doskey /exename=powershell.exe envpath = `$env:Path -split "';'"
  • The tokens that make up the PowerShell command must be passed as individual arguments to doskey.exe, and be sure to follow the = with a space.

    • If you accidentally pass the PowerShell command as a single, quoted argument, doskey.exe stores enclosing "..." as part of the macro and includes these quotes when it expands the macro.

    • If you additionally also include the macro name in that single, quoted argument, you not only get a virtually unusable macro,[1] you also cannot remove it in-session (neither individually, with doskey /exename=powershell.exe envpath=, nor as part of clearing all macros with Alt-F10) - you must start a new PowerShell session to get rid of it.

      • Note that the macro name is also included if you attempt partial quoting in PowerShell, e.g., doskey envpath="`$env:Path -split ','" is effectively the same as doskey "envpath=`$env:Path -split ','", due to how PowerShell rebuilds the command line behind the scenes (see below).
  • To avoid instant expansion of $env:Path, the $ character is preceded by PowerShell's escape character, the so-called backtick (`).

  • To preserve the '...'-quoting around ;, outer "..." quoting is used.

    • This is necessary, because PowerShell rebuilds the command line behind the scenes when it invokes external programs, which involves translating '...' quoting into "..." quoting if necessary; that is, irrespective of what quoting was originally used on the PowerShell side, an argument is enclosed in "..." if it contains spaces and used unquoted otherwise; thus, ';' by itself would turn into just ; on the behind-the-scenes command line; an originally partially quoted argument that contains spaces ends up being double-quoted as a whole.

[1] In a macro definition that doskey /macros or doskey /macros:all lists as "envpath=C:\WINDOWS\system32;C:\WINDOWS;<etc>;" -split ;, the macro name is "envpath verbatim, i.e. including the opening ". The - then unbalanced - closing " is retained in the text to expanded to.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Very helpful. Thanks. I'll try that shortly, but also want to add, do you have any idea what that quoted string returned by `doskey /macros:all` is and how to get rid of it? – DavidT Jun 26 '22 at 19:34
  • @DavidT, it is implied by my update, but to spell it out: `doskey` macro definitions aren't _persistent_, so simply launching a new shell session wipes the slate clean. To make definitions persistent in PowerShell, you'd have to add `doskey` call(s) to the `$PROFILE` file; in `cmd.exe` you'd use the registry, as described in this [SU answer](https://superuser.com/a/1134468/139307). – mklement0 Jun 26 '22 at 22:54