12

The user has appropriate permissions to read the share, and the share maps properly. This issue seems to happen only in PowerShell v2.0.

If I remove all mapped drives, remap one drive, and run Test-Path:

net use /delete * /y
net use G: \\somefileserver\share
Test-Path G:\

Test-Path returns False, even though the drive is clearly mapped, and I can access it through Windows Explorer.

If I close the PowerShell session, and open a new session, Test-Path returns True, as it should. Any ideas on, (A): what could be causing this, and how do I make it work properly? or (B): Is there another way to test for the existence of a network drive besides Test-Path? I am attempting to write a logon script to map user's network drives and this behavior is driving me insane.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3418092
  • 123
  • 1
  • 1
  • 4
  • 1
    Just for the record: this works fine in PS v3.0. Starting the PS elevated as administrator makes a difference though in any version. Drives mapped as standard user won't be visible in the elevated PS. – Heinrich Ulbricht Nov 05 '15 at 07:03

8 Answers8

14

I do think I found the answer with this:

Test-Path $('filesystem::\\Server\share$\install.wim')
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    The sub-expression is not necessary, i.e. `Test-Path 'filesystem::\\Server\share$\install.wim'` is fine – codaamok May 29 '20 at 21:36
11

If the Test-Path cmdlet is truly buggy, then I'd suggest using the Exists() method on the System.IO.Directory .NET class.

[System.IO.Directory]::Exists('G:\'); # This returns $true for me
  • Where do I loose is, when trying this above out? Tried it out and it didn't work with a UNC path, but local patch it worked But I do think it's me not fully understanding the Q and A...? – Daniel Lindegaard Apr 10 '17 at 13:53
8

To validate a UNC, use:

[bool]([System.Uri]$path).IsUnc
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Krzysztof Gapski
  • 528
  • 6
  • 10
  • 2
    This does not actually test the path - it simply tests whether the parsed string is a UNC path. – Dan Atkinson Sep 18 '19 at 10:45
  • 1
    To validate parameter, I would use `[ValidateScript({(test-path $_) -and ([System.Uri]$_).IsUnc})]`. Just saying because this could help someone. Thanks @DanAtkinson – PollusB Jul 17 '20 at 19:22
1

I had the exact same problem trying two network paths like this:

$verif_X = Test-Path "X:\"
$verif_S = Test-Path "S:\"
if($verif_X -and $verif_S){
    Write-Host "X: and S: network paths found"
}
else{
    Write-Host "Not all network paths found"
}

... At first, I always got > "Not all network paths found" which seemed really strange to me...

Then I tried to put those paths in simple quotes (') and searched for an existing folder inside those both network paths like this:

$verif_X = Test-Path 'X:\ISOs'
$verif_S = Test-Path 'S:\Scripts'

And then

if($verif_X -and $verif_S){[..]}

condition is accepted..

I think the Test-path cmdlet is a bit buggy as we enter only the first letter of a network path... but like this I do not get errors any more...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andy McRae
  • 525
  • 7
  • 15
1

I found also this answer which can be found here: It says that one can use the .NET framework to do so:

$path = "C:\text.txt"
if([System.IO.File]::Exists($path)){
    # file with path $path exists
}

Works fine if its a file. To find a folder, use:

$path = x:\
if([System.IO.Directory]::Exists($path)){
    # file with path $path exists
}
Andy McRae
  • 525
  • 7
  • 15
0

For me the only way to fix it was to use the full UNC, rather than the share name.

So instead of \\server\share I used \\server\c$\sharedir.

Another issue I ran into was when using Import-Module sqlps, I had to make sure to CD back into the file system and then the PowerShell commands worked normally.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
blizz
  • 4,102
  • 6
  • 36
  • 60
  • 1
    \\server\share and \\server\c$\shareddir are not the same thing, though. They have the same NTFS ACL, but the share ACLs are different. – Mike Shepard Aug 09 '18 at 19:57
0

SHORT ANSWER

if(-Not(Test-Path "filesystem::\\$server\c$")) {Write-Error "Server not found: $server"; continue} If Test-Path fails unexpectedly then make sure SMB2=1 (or other SMB setting) is set on both client and target server.

MORE INFO

IMPORTANT SMB NOTE: Both current system and target system must have at least on common SMB protocol enabled for Test-Path to succeed. (SMB2 or later strongly recommended.) For example, if target has SMB1 enabled + SMB2 disabled and client has only SMB2 enabled then logic above will return "Server not found...". This threw me off track until I finally checked my target server (Win7) and found it had SMB2=0 (disabled) and no entry for SMB1 (enabled by default). I fixed by setting SMB2=1 per article below.

SMB OS-specific and scripting details: https://support.microsoft.com/en-us/help/2696547/detect-enable-disable-smbv1-smbv2-smbv3-in-windows-and-windows-server

Excerpt: Win8/Win20012

Detect: Get-SmbServerConfiguration | Select EnableSMB1Protocol
Disable:    Set-SmbServerConfiguration -EnableSMB1Protocol $false
Enable: Set-SmbServerConfiguration -EnableSMB1Protocol $true

Excerpt: Win7/Win2008R2Server

Detect:
Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters | ForEach-Object {Get-ItemProperty $_.pspath}
Default configuration = Enabled (No registry key is created), so no SMB1 value will be returned

Disable:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" SMB1 -Type DWORD -Value 0 –Force

Enable:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" SMB1 -Type DWORD -Value 1 –Force

Code sample: Copy-Item a folder (recursive) only if target server exists

$scriptRootPath="." 
$scriptToolsPath="$scriptRootPath\Tools" 
$targetServerList="$scriptToolsPath\DeployServerList-INT-POC.txt"   #DeployServerList-INT.txt, DeployServerList-QA.txt, DeployServerList-PROD.txt
$stageTargetDrive="c"
$stageFolderPath="$stageTargetDrive$\staging"

$VerbosePreference="Continue"                                       #"SilentlyContinue" (default), "Continue", "Stop", "Inquire"
$InformationPreference="Continue"

Write-Host "Getting list of servers from $targetServerList to stage deployment files to..."
    $serverList = (get-content "$targetServerList")
    Write-Verbose "scriptToolsPath=$scriptToolsPath"
    Write-Verbose "serverlist=$serverList"
    Write-Verbose "stageFolderPath=$StageFolderPath"

Write-Host -Separator "-"
Read-Host -Prompt "READY TO STAGE FILES: Check info above, then press Enter to continue (or Ctrl+C to exit)."
Write-Host "-------------------------------------------------"

Write-Host "Staging files to $stageFolderPath on each target server..."
foreach ($server in $serverlist) {
    # Input validation
    if([string]::IsNullOrWhiteSpace($server)) {continue}
    if($server.StartsWith("#")) {Write-Verbose "Comment skipped: $server"; continue}    # Skip line if line begins with hashtag comment char
    Write-Verbose "Testing filesystem access to $server..."
    if(-Not(Test-Path "filesystem::\\$server\$stageTargetDrive$")) {Write-Error "Server not found: $server"; continue}
        # TIP: If Test-Path returns false unexpectedly then check if SMB2 is enabled on target server, check SMB1 disabled for both src and target servers.

    Write-Verbose "Staging files to $server..."
    Copy-Item ".\" -Destination "\\$server\$stageFolderPath" -Recurse -Force -ErrorAction Continue
    Write-Information "Files staged on $server."
} 
Zephan Schroeder
  • 695
  • 6
  • 12
0

I had this issue today, and found this issue.

For me, the error occurred in PowerShell ISE x(86), but not in the ISE 64-bit.

We use the BizTalk PowerShell extensions, which only work in x(86), so sometimes on my servers I default to using that.

The solution of using

[System.IO.Directory]::Exists($dirname); 

worked for me on both x86 and 64 bit.

NealWalters
  • 17,197
  • 42
  • 141
  • 251