Skip to main content

PowerShell cmdlet that gets the file name or directory portion of a path. Similar (but not exact) to the POSIX BASENAME(1) command, written in PowerShell.

function Get-Basename
{
    <#
    .SYNOPSIS
        Gets the file name or directory portion of a path.
        Somewhat similar to the POSIX BASENAME(1) command, written in PowerShell.

    .DESCRIPTION
        The Get-Basename cmdlet strips any prefix ending with the last slash
        character present in string (after first stripping trailing slashes),
        and a suffix, if given.

    .PARAMETER Path
        The path target.

    .PARAMETER NoExtension
        When specified, the file extension will be excluded from the basename.

    .EXAMPLE
        PS> Get-Basename https://example.com/archive.zip
        archive.zip

        Returns the file name from a URL.

    .EXAMPLE
        PS> 'https://example.com/archive.zip' | Get-Basename -NoExtension
        archive

        Returns the file name only from a URL.

    .EXAMPLE
        PS> Get-Basename -Path C:\path\to\myfolder
        myfolder

        Returns the folder name (myfolder) from the Windows path.

    .EXAMPLE
        PS> Get-Basename https://example.com
        example.com

        PS> Get-Basename https://example.com:8080
        example.com:8080

        PS> Get-Basename https://example.com?user=theo
        example.com?user=theo

        PS> Get-Basename https://example.com/some-page?user=theo
        some-page?user=theo

    .EXAMPLE
        PS> Get-Basename -Path $("/path/one", "C:\path\two", "https://example.com/path/three")
        one
        two
        three

        Process a list of paths.

    .NOTES
        Author: Jon LaBelle
        License: MIT

        https://jonlabelle.com/snippets/view/powershell/get-path-basename-in-powershell
        https://gist.github.com/jonlabelle/83ee9531b1999813feaa4a98417306bd
    #>
    [CmdletBinding()]
    param
    (
        [Parameter(
            ValueFromPipeLine,
            ValueFromPipelineByPropertyName)]
        [String[]]
        $Path,

        [Switch]
        $NoExtension
    )

    process
    {
        if ([String]::IsNullOrEmpty($Path))
        {
            $Path
        }
        else
        {
            if (-not $NoExtension)
            {
                Split-Path $Path -Leaf
            }
            else
            {
                # Split-Path $Path -LeafBase # -LeafBase only supported in PS 6+
                [IO.Path]::GetFileNameWithoutExtension($Path)
            }
        }
    }
}