none
Validating UNC Paths RRS feed

  • Question

  • Consider the following PowerShell script:

    while ($Path -eq $null -or $Path -eq '') {
    	$Path = Read-Host "Enter a local or UNC path"
    }
    
    if ((Test-Path $Path -PathType Container) -and ((Get-Item $Path).PSDrive.Provider.Name -eq "FileSystem")) {
    	Write-Host The path you entered is valid.
    }
    else {
    	Write-Host The path you entered is NOT valid.
    }
    

    Currently, it works as expected with local paths. However, valid UNC paths are considered invalid by this script. Also, I want it so that if a user accidentally puts "\\server" instead of "\\server\share", the script doesn't return the following error message and then exit:

    Test-Path : The UNC path should be of the form \\server\share.

    How should I modify the code above to achieve this? Thanks!

    Thursday, October 28, 2010 12:01 AM

Answers

  • Take II

     

    if([bool]([uri]$Path).IsUnc -and $Path -notmatch '\\\\\w+\\\w+')
    {
        Throw "The UNC path should be of the form \\server\share."
    }
    else
    {
        if ((Test-Path $Path -PathType Container -IsValid) -and ((Get-Item $Path).PSProvider.Name -eq 'FileSystem'))
        {
            Write-Host "The path you entered is valid."
        }
        else
        {
            Write-Host "The path you entered is NOT valid."
        }
    }



    Shay Levy [MVP]
    PowerShay.com
    PowerShell Toolbar
    Thursday, October 28, 2010 12:35 PM
    Moderator

All replies

  • This should work better for getting the path input 

    while ($Path -notmatch "\\\\\w+\\\w+") {
          $Path = Read-Host "Enter a local or UNC path"
          }


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
    Thursday, October 28, 2010 12:39 AM
  • Hi

    Have you considered using fullpath including provider? Take a look:

    Script:

     

    $LocalPathTest = 'c:\windows'
    $UNCServerOnlyPathTest = '\\server-only'
    $UNCServerSharePathTest = '\\server\share'
    Get-Variable *PathTest | Where-Object { Test-Path ('Microsoft.PowerShell.Core\FileSystem::' + $_.Value) -PathType Container }
    

    Output:

     Name Value
    ---- -----
    LocalPathTest c:\windows
    Test-Path : The UNC path should be of the form \\server\share.
    At line:4 char:50
    + Get-Variable *PathTest | Where-Object { Test-Path <<<< ('Microsoft.PowerShell.Core\FileSystem::' + $_.Value) -PathType Container }
    + CategoryInfo : NotSpecified: (:) [Test-Path], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.TestPathCommand

    UNCServerSharePathTest \\server\share

     

    HTH

    Bartek

    Thursday, October 28, 2010 7:28 AM
  • [bool]([System.Uri]$path).IsUnc

    See this blog post - QuickTip: How to validate a UNC path
    http://PowerShay.com/archive/2010/05/27/quicktip-how-to-validate-a-unc-path.aspx
    Shay Levy [MVP]
    PowerShay.com
    PowerShell Toolbar
    Thursday, October 28, 2010 9:17 AM
    Moderator
  • But that will return 'true' for \\server.

    And won't check if server/share is there or not:

     PS>Test-Path 'Microsoft.PowerShell.Core\FileSystem::\\server'
    Test-Path : The UNC path should be of the form \\server\share.
    At line:1 char:10
    + Test-Path <<<< 'Microsoft.PowerShell.Core\FileSystem::\\server'
    + CategoryInfo : InvalidArgument: (\\server:String) [Test-Path], ArgumentException
    + FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.TestPathCommand

    False
    PS>Test-Path 'Microsoft.PowerShell.Core\FileSystem::\\server\share'
    False
    PS>[bool]([System.Uri]'\\server').IsUnc
    True
    PS>[bool]([System.Uri]'\\server\share').IsUnc
    True

    Thursday, October 28, 2010 11:40 AM
  • Correct, it validates the UNC path elements only. To ensure the path exists physically we need to use Test-Path.

    Shay Levy [MVP]
    PowerShay.com
    PowerShell Toolbar
    Thursday, October 28, 2010 11:42 AM
    Moderator
  • I guess the point here is: how to make sure path is correct (Test-Path) and that it's within correct provider. And the real problem is not test-path (it works fine both for local and UNC) but test for provider.

    One option is to use fullpath (with provider). Second: query for PsProvider directly on the item:


    PS C:\> (Get-Item 'c:\temp').PsProvider.Name
    FileSystem

    ________________________________________________________________________________________________________________________________________________________________________
    PS C:\> (Get-Item '\\pl-war-vfp001\vol1').PsProvider.Name
    FileSystem

    back to original question: to fix the code it is enough to delete 'PSDrive' - this property does not exist on UNC paths and causes query against them to return $false, shorten and UNC-friendly way:

    ((Get-Item $Path).PSProvider.Name -eq "FileSystem")

     

    Thursday, October 28, 2010 12:03 PM
  • Take II

     

    if([bool]([uri]$Path).IsUnc -and $Path -notmatch '\\\\\w+\\\w+')
    {
        Throw "The UNC path should be of the form \\server\share."
    }
    else
    {
        if ((Test-Path $Path -PathType Container -IsValid) -and ((Get-Item $Path).PSProvider.Name -eq 'FileSystem'))
        {
            Write-Host "The path you entered is valid."
        }
        else
        {
            Write-Host "The path you entered is NOT valid."
        }
    }



    Shay Levy [MVP]
    PowerShay.com
    PowerShell Toolbar
    Thursday, October 28, 2010 12:35 PM
    Moderator
  • It looks like that the following two methods have the same results

    PS C:\> [bool]([System.Uri]$unc="\\server01\folder\file.txt").IsUnc
    True

    PS C:\> Test-Path -Path "\\server01\folder\file.txt" -IsValid
    True

    both Methods tests only if the syntax for an UNC Path is correct, but do not test if the path exist (or can be accessed)

    I came to the following validation method:

     

    Validate UNC Path

     Tested using PS 4.0 with Win 7

    Using Test-Path cmdlet

     

    Param (

        [Parameter(Position=0,Mandatory=$False,

            HelpMessage="Enter a UNC path like \\server\share")]

        [ValidateScript({ Test-Path –Path $_ -IsValid })]

        [string]$unc = "\server01\My Share\folder"

    )

     

    NOTE:

    Servername as full DNS Names is also valid, but  \\server01.com\\My dir\test.txt with ‘\\’ after the servername or after the sharename  is also valid.

    Spaces in the Path is allowed.

    The –isValid Switch tests only if the path syntax is valid, not if the path really exist.

     

     

    Using System.Uri class

     

    Param (

        [Parameter(Position=0,Mandatory=$False,

            HelpMessage="Enter a UNC path like \\server\share")]

        [ValidateScript({ [bool]([System.Uri]$_).IsUnc })]

        [string]$unc = "\server01\My Share\folder"

    )

     

    NOTE:

    Servername as full DNS Names is also valid, but  "\\server01.com\\My dir\test.txt" with ‘\\’ after the servername or after the sharename  is also valid.

    Spaces in the Path is allowed. Test only if syntax is valid valid, not if the path really exist.

    The same result as the Test-Path cmdlet with –isValid switch.

     

    Using RegEx

     

    Param (

     [Parameter(Position=0,Mandatory=$True,

       HelpMessage="Enter a UNC path like \\server\share")]

     [validatepattern({^\\\\\w+\\\w+})]

     [ValidateScript({Test-Path -Path $_ })]

     [string]$UNC_Path="\\server01\My share\folder"

    # [string]$UNC_Path="\\server01\My share\folder\file.txt"  is also valid

    )

     

    NOTE:

    The regex pattern ‘^\\\\\w+\\\w+’ does not validate DNS servername like server.contoso.com

    "\\server01.com\\My dir\test.txt"  ‘\\’ after the servename or after the sharename is not allowed.

    Test-Path used to test if the path really exist (or is accessible).


    It depends what you want to validate and maybe return a specific Warning Message, I would do the test outside the Param() section.

    Pasquale Lantella

    Thursday, February 12, 2015 4:08 PM