97

I'm trying to set up a Windows PowerShell alias to run MinGW's g++ executable with certain parameters. However, these parameters need to come after the file name and other arguments. I don't want to go through the hassle of trying to set up a function and all of that. Is there a way to simply say something like:

alias mybuild="g++ {args} -lib1 -lib2 ..."

or something along those lines? I am not all that familiar with PowerShell, and I'm having a difficult time finding a solution. Anyone?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ken Bellows
  • 6,711
  • 13
  • 50
  • 78

6 Answers6

149

You want to use a function, not an alias, as Roman mentioned. Something like this:

function mybuild { g++ $args -lib1 -lib2 ... }

To try this out, here's a simple example:

PS> function docmd { cmd /c $args there }
PS> docmd echo hello
hello there
PS> 

You might also want to put this in your profile in order to have it available whenever you run PowerShell. The name of your profile file is contained in $profile.

Mark
  • 11,257
  • 11
  • 61
  • 97
  • 5
    a little improvement to get an better accessible for commands is to use New-Alias to map an Alias to the new function. `Function SCP-Filetransfer { cmd /c pscp.exe -i ~\.ssh\id_rsa.ppk $args } New-Alias -Force pscp SCP-Filetransfer` – Tobias Hochgürtel Mar 11 '16 at 23:19
  • 5
    The downside of this is no parameter completion is available on the function – Jack Ukleja Sep 25 '17 at 13:06
5

There is not such a way built-in. IMHO, a wrapper function is the best way to go so far. But I know that some workarounds were invented, for example:

https://web.archive.org/web/20120213013609/http://huddledmasses.org/powershell-power-user-tips-bash-style-alias-command

Roman Kuzmin
  • 40,627
  • 11
  • 95
  • 117
  • 9
    A bash alias really is more closely synonymous with a PowerShell function or cmdlet. An alias in PowerShell is really just used for shortening an existing function/cmdlet - such as the alias `rm` for Remove-Item. – Goyuix Nov 12 '10 at 16:57
  • 1
    the issue with functions is their ungodly overhead in Powershell. – bkr Jun 07 '19 at 20:33
4

To build an function, store it as an alias, and persist the whole thing in your profile for later, use:

$g=[guid]::NewGuid();
echo "function G$g { COMMANDS }; New-Alias -Force ALIAS G$g">>$profile

where you have replaced ALIAS with the alias you want and COMMANDS with the command or string of commands to execute.

Of course, instead of doing that you can (and should!) make an alias for the above by:

echo 'function myAlias {
    $g=[guid]::NewGuid();
    $alias = $args[0]; $commands = $args[1]
    echo "function G$g { $commands }; New-Alias -Force $alias G$g">>$profile
}; New-Alias alias myAlias'>>$profile

Just in case your brain got turned inside out from all the recursion (aliasing of aliases, etc.), after pasting the second code block to your PowerShell (and restarting PowerShell), a simple example of using it is:

alias myEcho 'echo $args[0]'

or without args:

alias myLs 'ls D:\MyFolder'

Iff you don't have a profile yet

The above method will fail if you don't have a profile yet! In that case, use New-Item -type file -path $profile -force from this answer.

NH.
  • 2,240
  • 2
  • 23
  • 37
  • 1
    Using this (and all other _alias via function_ approaches) fails when it comes to piping input into the aliased command. Test case: `ps | grep` where `grep` is an alias that works fine. Where `grep` is a function, the above hangs indefinitely. Is there a workaround for this? – ehiller Oct 24 '17 at 15:09
  • @ehiller, I'm not able to duplicate your issue, but my functions were designed to be used with arguments, not pipelines. – NH. Oct 24 '17 at 15:55
  • I like the basic idea of your approach, but the implementation is unnecessarily complex: there is no need to create a PowerShell alias at all, via an aux. function -just _define a function directly_, with the desired "alias" name. – mklement0 Apr 16 '19 at 20:27
  • @mklement0 isn't that what ehiller's complaint was about above? – NH. Apr 18 '19 at 15:55
  • No, ehiller's complaint is about lack of pipeline support, which is an unrelated problem - and not necessarily one that needs to be solved in the context of the question at hand. Your solution inspired [this answer](https://stackoverflow.com/a/55708770/45375) - please note the comments - and I've tried to show in [this answer](https://stackoverflow.com/a/55707452/45375) how to do it the PowerShell-idiomatic way. – mklement0 Apr 18 '19 at 16:03
  • Why make everything so difficult and convulated? – Roslan Amir Sep 30 '22 at 07:41
4

This is a sample function that will do different things based on how it was called:

Function Do-Something {
[CmdletBinding()] 
[Alias('DOIT')]
Param(
    [string] $option1,
    [string] $option2,
    [int] $option3)
#$MyInvocation|select *|FL
If ($MyInvocation.InvocationName -eq 'DOIT'){write-host "You told me to do it...so i did!" -ForegroundColor Yellow}
Else {Write-Host "you were boring and said do something..." -ForegroundColor Green}
}
dferenc
  • 7,918
  • 12
  • 41
  • 49
Josh
  • 41
  • 1
2

Creating a 'filter' is also an option, a lighter alternative to functions. (archive)

It processes each element in the pipeline, assigning it the $_ automatic variable. So, for instance:

filter test { Write-Warning "$args $_" }
'foo','bar' | test 'This is'

returns:

WARNING: This is foo
WARNING: This is bar
Vopel
  • 662
  • 6
  • 11
2

A few years ago I created a PowerShell module that does this. It is on the gallery and it is open source.

I was looking for the same experience. This is how to use it:

Add-Alias ls 'ls -force'
Add-Alias add 'git add'

Gallery: https://www.powershellgallery.com/packages/posh-alias/

Github: https://github.com/giggio/posh-alias

Giovanni Bassi
  • 739
  • 6
  • 18