tl;dr
- Omit the
start argument and provide the full path of notepad++.exe as the -Value argument, e.g. (if this full path doesn't work for you, see below for how to discover the correct one):
# Shorter alternative:
# Set-Alias notepad $env:ProgramFiles\Notepad++\notepad++.exe
Set-Alias -Name notepad -Value $env:ProgramFiles\Notepad++\notepad++.exe
- Alternatively, if you want to rely on the convenience of
start (Start-Process) being able to discover the location of notepad++.exe for you, you must use a function ($args passes any arguments through):
# PowerShell 7+
function notepad { start notepad++ $args }
# Windows PowerShell, to work around a bug.
function notepad {
$argsParam = if ($args) { @{ ArgumentList = $args } } else { @{} }
start notepad++ @argsParam
}
Building on the helpful comments:
In PowerShell, an alias is simply another name for a command (which can be a PowerShell cmdlet, function, script, or external executable, and even another alias).
Therefore, Set-Alias's -Value parameter only accepts a single argument to describe the target of the name mapping.
set-alias -name notepad -value start notepad++ is therefore broken syntax, because notepad++ is an extra argument that Set-Alias doesn't recognize.
Since Notepad++ is a GUI program, there is no need to use start (Start-Process) to launch it asynchronously, i.e. without blocking the calling session, because direct invocation does that by default (see below for a synchronous solution).
Unfortunately, however, the Notepad++ installer does not include an entry in $env:PATH for its installation directory, hence the need to use notepad.exe's full path above.
It does, however, create a registry entry, which allows Start-Process (as opposed to direct invocation) to discover notepad++.exe; if you want to rely on this for simplicity, you'll need to use a function rather than an alias, as described below (simply remove -Wait from the synchronous variant).
The simplest way to discover nodepad++.exe's full path is to launch Notepad++ interactively with Start-Process -PassThru and access the .Path property of the process-information object that is returned:
# -> 'C:\Program Files\Notepad++\notepad++.exe', typically
(Start-Process -PassThru notepad++).Path
In cases where you do need more than just another command's name or path - typically when your "alias" should include hard-coded arguments to pass to the target command - you must define a function instead:
Here's a variant of your "alias" - now of necessity implemented as a function - that uses Start-Process -Wait to launch Notepad++ synchronously, i.e. in a blocking fashion, while also supporting pass-through arguments (which a true alias definition implicitly does).
function notepad {
if ($args) { # Pass-through arguments specified.
Start-Process -Wait notepad++ $args
} else {
Start-Process -Wait notepad++
}
}
notepad++ binds positionally to the -FilePath parameter, and $args to the -ArgumentList parameter.
- Note the check for whether
$args contains elements (if ($args)), which is - unfortunately - needed in Windows PowerShell, where a bug prevents passing an empty array to -ArgumentList; this problem has been fixed in PowerShell (Core) 7+
If your alias-like function also needs to support pipeline input, see this answer.
For a more sophisticated but more complex way of wrapping other commands using so-called proxy functions, see this answer.
notepad++.exeis already an executable application, why not justSet-Alias -Name notepad -Value 'notepad++.exe'?