4

How can I tell if a specified folder is in my PATH using PowerShell?

A function like this would be great:

function FolderIsInPATH($Path_to_directory) {
    # If the directory is in PATH, return true, otherwise false
}
7
  • 9
    This question is being discussed on meta. Commented Aug 4, 2022 at 16:13
  • 1
    Does stackoverflow.com/questions/57493560 help? Or stackoverflow.com/questions/5114985 ? Commented Aug 4, 2022 at 19:52
  • 10
    @Braiam - Please stop untagging relevant tags. [path-variables] is pretty obviously applicable here; there aren't many other cases where you have a ;-separated list of directories, and matching entries in it is highly relevant for cases like checking whether a directory is already in it before appending to it. Unless/until you get people to agree on meta to a burnination or usage-change for a tag, please don't remove it from questions where it applies. It's not better to have fewer tags. Commented Aug 4, 2022 at 23:37
  • 4
    @KarlKnechtel, you do a great job at posting Links to Dupes/related Threads, but only posting the bare URL always feels a bit like "Click-Bait"... Maybe more "useful" would be...: [Quoting your Post...]: "Does Get PATH evironment variable in PowerShell help? Or Echo %path% on separate lines? ?" // Syntax to use: [Thread Title](Link to Question, can be shortened like "/q/57493560")... (No Space between the [] and () parts...) // + May want to edit the 1st Link/Thread to correct the ugly Typo in the Title btw... (maybe why that Thread didn't get found...!). Commented Aug 5, 2022 at 5:24
  • 2
    @KarlKnechtel : there's TamperMonkey script SE Comment Link Helper . I use that in Chromium for link posting. If you're going to post bare URLs, at least post the full link so some of the title words are part of the URL, but titles on the links would be much much better, as chivracq says. Commented Aug 5, 2022 at 21:21

4 Answers 4

17

Going off this question, you don't need a function for this but can retrieve this with $Env:Path:

$Env:Path -split ";" -contains $directory

The -contains operator is case-insensitive which is a bonus. It could be useful placing this in a function to ensure trailing slashes are trimmed, but that's uncommon:

function inPath($directory) {
    return ($Env:Path -split ';').TrimEnd('\') -contains $directory.TrimEnd('\')
}
Sign up to request clarification or add additional context in comments.

2 Comments

Any quoting necessary for a directory with a space in it?
If it's in a variable, no. If manually typing it out, then it needs (single or double) quotes like this: $Env:Path -split ";" -contains 'C:\Program Files'
10

There's a bunch of answers that do a $path.Split(";") or $path -split ";" that will probably be fine for 99.9% of real-world scenarios, but there's a comment on the accepted answer on a similar question here by Joey that says:

Will fail with quoted paths that contain semicolons.

Basically, it's a bit of an edge case, but this is a perfectly valid PATH on Windows:

c:\temp;"c:\my ; path";c:\windows

so here's a hot mess of code to address that...

function Test-IsInPath
{
    param( [string] $Path, [string] $Folder )

    # we're going to treat the path as a csv record, but we
    # need to know how many columns there are so we can create
    # some fake header names. this might give a higher count
    # than the real value if there *are* quoted folders with
    # semicolons in them, but that's not really an issue
    $columnCount = $Path.Length - $Path.Replace(";","").Length

    # generate the list of column names. the actual names
    # don't matter - it's just so ConvertFrom-Csv treats our
    # PATH as a data row instead of a header row
    $headers = 0..$columnCount

    # parse the PATH as a csv record using ";" as a delimiter
    $obj = $path | ConvertFrom-Csv -header $headers -delimiter ";"

    # extract an array of all the values (i.e. folders)
    # in the record we just parsed
    $entries = $obj.psobject.properties.value

    # check if the folder we're looking for is in the list
    return $entries.Contains($Folder)

}

Whether this is a "better" answer than the simple split approach depends on whether you expect to have quoted folders that contain semicolons in your PATH or not :-)...

Example usage:

PS C:\> Test-IsInPath -Path $env:PATH -Folder "c:\temp"
False

PS C:\> Test-IsInPath -Path "c:\temp;`"c:\my ; path`";c:\windows" -Folder "c:\temp"
True

PS C:\> Test-IsInPath -Path "c:\temp;`"c:\my ; path`";c:\windows" -Folder "c:\my ; path"
True

Notes

  • what this still doesn't solve is paths that end (or don't end) with a trailing "\" - e.g. testing for C:\temp when the PATH contains C:\temp\ and vice versa.

  • it also doesn't address any of the other myriad exceptions to path handling listed here: How to check if a directory exists in %PATH%

2 Comments

Given a $Path, $AlreadyAddedToSystemPath = [bool]@($env:Path -split ";" | Where-Object { $_ -eq $Path }).Count
@xorcus - $my_path = 'c:\temp;"c:\my ; path";c:\window'; $my_dir = 'c:\my ; path'; [bool]@($my_path -split ";" | Where-Object { $_ -eq $my_dir }).Count returns False. See the bit in my answer that says Will fail with quoted paths that contain semicolons.. The reason is that c:\my ; path is a perfectly valid folder path that could be in your system PATH env variable. If you naively split on ; you'll cut that folder path in half and miss the entry. It's an edge case for sure so use split if you don't care about it, otherwise there's my Test-IsInPath
3

I would go for something like this

function FolderIsInPATH {
    param (
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]$your_searched_folder
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]$Path
    )
    
    $Folders = Get-Childitem -Path $Path -Directory

    foreach ($Folder in $Folders) {
        if ($Folder.Name -eq $your_searched_folder) {
            ##Folder found
        } else {
            ##folder not found
        }
    }
}

3 Comments

Maybe I forgot to explain that PATH is the environment variable...
Why an explicit loop? Isn't there a built-in function to search in arrays?
@PeterMortensen: You are right. There is a built in .Net function calles indexof to seach in arrays. But i choose a foreach loop for two main reasons here: 1. The foreach loop is easier to understand for Caleb Liu on how it works and how the script finds the necessary value. 2. I personally think that you are much more flexible with a loop to process this array. But this is only personal preference ;)
2

You can get your PATH using [Environment]::GetEnvironmentVariables()

[Environment]::GetEnvironmentVariables()

Or if you want to get the user environment variables:

[Environment]::GetEnvironmentVariables("User")

Next, get the PATH variable:

$Path = [Environment]::GetEnvironmentVariables().Path # returns the PATH

Then check if the specified folder is in your PATH:

$Path.Contains($Path_to_directory + ";")

The function put together:

function FolderIsInPath($Path_to_directory) {
    return [Environment]::GetEnvironmentVariables("User").Path.Contains($Path_to_directory + ";")
}

However, this function is case-sensitive. You can use String.ToLower() to make it not case-sensitive.

function FolderIsInPath($Path_to_directory) {
    return [Environment]::GetEnvironmentVariables("User").Path.ToLower().Contains($Path_to_directory.ToLower() + ";")
}

Now call your function like this:

FolderIsInPath("C:\\path\\to\\directory")

Note that the path must be absolute.

As pointed out in mclayton's comment, this function won't work for the last path variable. To address this issue, simply add a ; to the end of the path. Your function would now look like this.

function FolderIsInPath($Path_to_directory) {
    return [Environment]::GetEnvironmentVariables("User").Path.ToLower() + ";".Contains($Path_to_directory.ToLower() + ";")
}

1 Comment

$Path.Contains($Path_to_directory + ";") won't work if it's the last directory in the list and there's no terminating ; - you might be better doing $Path.Split(";").Contains($Path_to_directory) instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.