First, a workaround using the .NET framework:
[IO.Path]::Combine('a', 'b', 'c')
This yields a/b/c on Unix, and a\b\c on Windows, and conveniently supports any number of path components.
Note:
This workaround is only for filesystem paths, whereas Join-Path is designed to work with any PowerShell drive provider's paths.
Make sure that no component other than the first starts with \ (Windows) or / (Unix), because any preceding component is then ignored; e.g., on Windows:
[IO.Path]::Combine('\a', '\b', 'c') # -> '\b\c' - '\a' is ignored(!)
Note that Join-Path does not exhibit this behavior; see this answer for details.
As an alternative to sequencing Join-Path calls with a pipeline you can simply use (...) (a subexpression):
Join-Path a (Join-Path b c) # -> 'a\b\c' (on Windows)
The syntax displayed by Join-Path -? as of Windows PowerShell v5.1.14393.693 (incidental parameters omitted):
Join-Path [-Path] <String[]> [-ChildPath] <String> ...
This syntax implies that invocation Join-Path a b c results in a syntax error in Windows PowerShell, because there is no parameter to bind the c argument to.
By contrast, the syntax displayed in PowerShell (Core) 7 reveals an additional parameter:
Join-Path [-Path] <String[]> [-ChildPath] <String> [[-AdditionalChildPath] <String[]>]
It is the additional -AdditionalChildPath parameter, which is declared in a manner that collects all remaining positional arguments that (ValueFromRemainingArguments), that makes specifying an arbitrary number of child components work, so that Join-Path a b c indeed works, for instance.
Unfortunately, this enhancement won't be back-ported to Windows PowerShell.
Note that even though [-Path] <String[]> is an array parameter, its purpose is not to accept multiple child path components of a single output path, but to allow joining of multiple parent-child path pairs; e.g.:
$ Join-Path a,b c # same as: Join-Path -Path a,b -ChildPath c
a\c
b\c
As of PowerShell 7.4.x, there is a green-lit, but as yet unimplemented feature request to allow passing an array of components directly to -ChildPath, without the need for -AdditionalPath:
# FUTURE ENHANCEMENT, in *some* version *after* 7.4
Join-Path -Path a -ChildPath b, c
# Ditto with positional arguments
Join-Path a b, c
See GitHub issue #21367
Finally, even you can typically get away with hard-coding / as the path separator on both platforms, because many Windows API functions as well as PowerShell's own cmdlets accept \ and / interchangeably.
However, not all utilities may behave this way, so it's generally safer to use the platform-appropriate separator.
For instance, the following works just fine on Windows:
Get-Item c:/windows/system32 # same as: Get-Item c:\windows\system32
Join-Pathcan only take two paths. Piping to another join or using .Net's[io.path]::combine()method are the two workarounds I know of.