4

I'm using Windows PowerShell and it is configured using doskey macros. I have a file named Macros.doskey.

105=code E:\static5\105 135=code E:\static5\135 static5=code E:\static5 

How can I get the command corresponding to alias name ?

For example, when I type 105 in PowerShell it will execute the command code E:\static5\105

Now I want to know how to get the command from the alias name.

5
  • 1
    this doskey /macros will list out the current set of doskey macros. you can parse the resulting text fairly easily. [grin] Commented Mar 10, 2019 at 18:09
  • @Lee_Dailey that looks promising. How cool would it be if Get-Command and/or Get-Alias could be extended to list those?! Commented Mar 10, 2019 at 18:10
  • @briantist - i would not do it that way. i prefer to leave the builtin stuff unchanged. however, it is fairly easy to write a wrapper for those if desired. i would make a function that called doskey with a filter to match against a parameter value. [grin] Commented Mar 10, 2019 at 18:17
  • @Lee_Dailey, doskey /macros command list out the complete set of doskey macros. How can I show only one command? Commented Mar 10, 2019 at 18:18
  • @SanjayRaz - use something like doskey /macros | Where-Object {$_ -match $Var} in a custom function. use the basic function template from the ISE to make it really easy. [grin] Commented Mar 10, 2019 at 18:30

3 Answers 3

3
  • doskey is a utility primarily designed to work with cmd.exe, not PowerShell.

    • PowerShell has better functionality built in, in the form of aliases and functions, and in Windows 10 you must even deactivate PowerShell's own command-line editing to even get doskey to work (see below).
  • If you still want to use doskey in PowerShell, there are two prerequisites:

    • The PSReadLine module - which handles command-line editing since Windows 10 by default - must not be loaded, as it takes precedence over doskey definitions[1]; that is, you may need to unload it explicitly with Remove-Module PSReadLine, but that means that you'll lose all of its benefits.

    • You must invoke any doskey.exe macro definitions with /exename=powershell.exe (Windows PowerShell) or /exename=pwsh.exe (PowerShell Core) for them to be usable from PowerShell.

      • Note that it is then doskey that expands a macro name typed by the user, which means that PowerShell only sees the expanded command and therefore has no knowledge of macro names. Therefore, trying to inspect doskey macros with
        Get-Command won't work; inspect the output from doskey /macros instead, as in Lee Dailey's answer.

      • Additionally, doskey also resolves macros when soliciting arbitrary user input via Read-Host[1], which is undesired.


To summarize the reasons for not using doskey in PowerShell:

  • It cannot be used with the PSReadLine module, which by default handles command-line editing since Windows 10 and provides invaluable functionality.

  • doskey macro expansion invariably also occurs when scripts solicit arbitrary user input via Read-Host, which is undesired.


Therefore, I suggest you abandon doskey in favor of PowerShell functions, and add them to your $PROFILE file so that they're available in every session:

  • While you can define functions named for numbers such as 105in PowerShell, you'll have to invoke them with & so as to disambiguate from actual numbers, e.g., & 105.

  • Therefore, I suggest refactoring your approach to define a single function named, say, c, that takes an optional argument to identify which file(s) to open:

function c { pushd E:/static5; code $(if ($Args) { $Args } else { '.' }); popd } 

Your original doskey macros then map onto this function as follows:

  • 105 -> c 105
  • 135 -> c 135
  • static5 -> c

Note that this not only allows you to pass an arbitrary file name (of a file located in E:/static5/) to function c, but even multiple ones; e.g., c 105 135 would open both files for editing.

To inspect the definition of function c later, you can simply call $function:c or, more verbosely, (Get-Command c).Definition.


[1] As PetSerAl notes: "doskey performs translations on the console input buffer. [...]. It does not work if the console is not in line input mode, thus it is not compatible with PSReadline, although Read-Host will be affected.
https://i.sstatic.net/HpYzq.png"

Sign up to request clarification or add additional context in comments.

Comments

1

I've never used doskey with PowerShell, so I'm not sure how they appear. My best guess is that PowerShell sees them as commands of type "Application" which usually means external executables.

To start, check what PowerShell sees:

Get-Command 105 | Format-List * # or gcm 105 | fl * 

From there, you might see just some exe like doskey.exe or maybe you'll see additional info too.

If it's just listed as an executable then I'm not sure you'll be able to get the info out of doskey.

PowerShell has its own versions of aliases which would have let you do full discovery, but PowerShell aliases can't take parameters, they just alias one command to another.

You could simulate doskey functionality in PowerShell by writing functions instead:

function static5 { code.exe 'E:\static5' } 

4 Comments

Thank you for the quick reply. Your solution works when I use functions to simulate doskey functionalities but in my case, PowerShell give me some error like this Get-Command : The term '105' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:1 + Get-Command 105 | Format-List *
@SanjayRaz that's very interesting, I don't know how the command could work in PowerShell while not being discoverable through Get-Command. Unfortunately I can't really take the time right now to do a doskey setup and investigate, but maybe someone else will be able to take that on. If possible I recommend moving on from doskey.
doskey do translation of console input buffer. PowerShell never see original line. It does not work if console is not in line input mode, thus it is not compatible with PSReadline, although Read-Host will be affected. i.sstatic.net/HpYzq.png
@briantist: PetSerAl's comment implies that you'll never be able to inspect doskey macros with Get-Command, because doskey macros, if they're actually in effect (they won't be with PSReadLine loaded, except when you use Read-Host, which is where you don't want them), get expanded before PowerShell ever sees the already expanded command.
1

this will do the job fairly well. [grin] note that it just gives the text matching the macro. i did not test with multiline macros, nor do i know if that is even possible.

if you want the result to be just the macro instead of the full line, you can add a | ForEach-Object {$_.Split('=')[1]} to get the part after the =.

@" 404=echo '404' 666=echo '666' dwd=echo 'Doo Wa Diddy' "@ | Set-Content "$env:TEMP\Doskey-Macros.txt" -Force doskey /macrofile=c:\temp\doskey-macros.txt function DKA ($Macro) { doskey /macros | Where-Object { $_ -match $Macro } } 

testing & output ...

dka -Macro dwd dwd=echo 'Doo Wa Diddy' dka -Macro adg # nothing at all since there was no match dka 404 404=echo '404' 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.