Directory.Exists()
and be done with it. But the PowerShell way is Test-Path. You can still use the C# version [System.IO.Directory]::Exists()
but since using Test-Path
and wanting to be more PowerShelly I stuck to it and forgot about Directory.Exists()
I mean its the same thing anyway, right? No way! It seems like there are some other checks which I'm not sure what perhaps permissions etc the function tests for both existence and accessibility (permissions). All i really wanted to test was if the drive exists.
So one other quick way is to useGet-ChildItem "C:\"
and wrap this in a try except and check for exception of type System.Management.Automation.DriveNotFoundException
So much like:
function DriveExists($path) { try { Get-ChildItem $path | Out-Null } catch { if ($_.Exception.gettype() -eq [System.Type]::GetType("System.Management.Automation.DriveNotFoundException")) { Write-Host "FAIL!" Write-Host $Error[0].exception return $false } } return $true }But this doesn't work either because the catch block is never executed, WTF? So it turns out that in powershell only fatal exceptions will invoke the catch block: To get around this you have to check the return value from the last command as suggested and then check the error:
function DriveExists($path) { Get-ChildItem $path -ErrorAction SilentlyContinue | Out-Null if (-not $?) # http://www.neolisk.com/techblog/powershell-specialcharactersandtokens { if ($Error[0].exception.gettype() -eq [System.Type]::GetType("System.Management.Automation.DriveNotFoundException")) { return $false } } return $true }Now that I have this handy function again i found that for some reason a new drive mounted while executing the script cannot be seen, again WTF? It's as if it is cached in the session and can't be accessed. Then I think hey let me just test the existence by using
Directory.Exists()
and what do you know it works.
In order to get Test-Path to work I had to run this out of process in a new session using a job, so something like this:
function DriveExistUsingJob($path) { $ScriptBlock = { Write-Output (Test-Path $args[0]) } $Job = Start-Job -ScriptBlock $ScriptBlock -ArgumentList @($path) Wait-Job $job | Out-Null $jobResult = [string](Receive-Job -Job $Job ) while ($job.HasMoreData) { $jobResult = [string](Receive-Job -Job $Job) } return $jobResult }So why did I use PowerShell's
Test-Path
function one in the first place? I don't know I think I'll stick to the C# functions where I can, at least I know what that does.
Remember: All I really wanted to do was to say Directory.Exists()
, but no...
It really makes me feel like Windows Powers Hell or at least mine.