How can I write a PowerShell alias with arguments in the middle?
Asked Answered
D

7

104

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?

Desecrate answered 12/11, 2010 at 15:49 Comment(0)
L
160

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.

Longsome answered 12/11, 2010 at 16:54 Comment(3)
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-FiletransferAmplitude
The downside of this is no parameter completion is available on the functionClient
You can use the Alias attribute inside your function instead of creating a New-Alias for the function: function MyFunction {[Alias('mf')] param($Param) Write-Output $Param}Rusell
M
6

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

Medeiros answered 2/6, 2023 at 4:43 Comment(1)
What is the difference to the built in New-Alias? New-Alias ll 'dir'?Backspace
P
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

Prussia answered 12/11, 2010 at 16:35 Comment(2)
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.Transcription
the issue with functions is their ungodly overhead in Powershell.Sclerous
H
5

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.

Harkness answered 22/9, 2017 at 20:3 Comment(6)
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?Water
@ehiller, I'm not able to duplicate your issue, but my functions were designed to be used with arguments, not pipelines.Harkness
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.Mcwilliams
@Mcwilliams isn't that what ehiller's complaint was about above?Harkness
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 - please note the comments - and I've tried to show in this answer how to do it the PowerShell-idiomatic way.Mcwilliams
Why make everything so difficult and convulated?Cowhide
A
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}
}
Amidst answered 16/2, 2018 at 16:26 Comment(0)
P
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
Poplin answered 13/12, 2021 at 20:12 Comment(1)
thank you for this insight!Courtier
H
0

I use wrapper functions with an alias:

function Invoke-BatAsCat { & (Get-Command bat).Source -pp ${Args} }
Set-Alias -Name 'cat' -Value Invoke-BatAsCat

The best practice is to use a PowerShell verb for the function name and alias. However, I use $Args instead of declaring param for brevity.

Hatteras answered 26/12, 2023 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.