Splitting the PowerShell PSModulePath Cross-Platform

The $env:PSModulePath environment variable contains a list of directory locations that PowerShell searches to locate modules.

1$env:PSModulePath

psmodulepath-cross-plat-split1a

When you're trying to determine what paths are part of the $env:PSModulePath environment variable in PowerShell, you'll find that most examples split the results on the semicolon (;) character to return each path on a separate line.

1$env:PSModulePath -split ';'

psmodulepath-cross-plat-split2a

Another variation is to use the Split method instead of the operator.

1$env:PSModulePath.Split(';')

psmodulepath-cross-plat-split3a

Splitting on a semicolon was a great solution back in the day of Windows (only) PowerShell. The cross-platform GA release of PowerShell in 2018 made using the semicolon to split paths obsolete because Linux and macOS use a colon (:) as a path separator.

For the following examples, I've established a PowerShell remoting session to Windows, Linux, and macOS systems and stored those sessions in a variable named PSSession. I've also created a function called uname on the Windows system.

Notice that each path is on a separate line for the Windows system when splitting the $env:PSModulePath using a semicolon, but the paths for both Linux and macOS are on a single wrapped line.

1Invoke-Command -Session $PSSession {. uname; $env:PSModulePath -split ';'}

psmodulepath-cross-plat-split4a

Splitting the $env:PSModulePath with a colon solves the problem for Linux and macOS, but mangles the paths for Windows.

1Invoke-Command -Session $PSSession {. uname; $env:PSModulePath -split ':'}

psmodulepath-cross-plat-split5a

A tip I received from Andrew Pearce is that "[System.IO.Path]::PathSeparator is your friend".

1[System.IO.Path]::PathSeparator

psmodulepath-cross-plat-split6a

Splitting the $env:PSModulePath using [System.IO.Path]::PathSeparator solves the problem for Windows, Linux, and macOS.

1Invoke-Command -Session $PSSession {. uname; $env:PSModulePath -split [System.IO.Path]::PathSeparator}

psmodulepath-cross-plat-split7a

Summary

Don't use a semicolon to split the $env:PSModulePath in a cross-platform world. Use [System.IO.Path]::PathSeparator instead.

1$env:PSModulePath -split [System.IO.Path]::PathSeparator

psmodulepath-cross-plat-split8a

References