tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

PowerShell の Test-Path -IsValid が謎くて使えない

よく利用される、Test-Path は対象のパスが存在するかどうかを検知します。

このTest-Pathには、-IsValid スイッチがあります。

この IsValid でファイルパスのバリデーションをしようとすると、謎に巡り合えます。

TechNet を見よう

何はともあれ説明を見ましょう。

TechNet / Test-Path

-IsValid

パスの構文が正しいかどうかを判断します。パスの要素が存在するかどうかとは無関係です。このパラメーターは、パスの構文が正しい場合は TRUE を返し、そうでない場合は FALSE を返します。

構文としてパスに含まれてはいけない文字

.NETなら GetInvalidFileNameChars() で取得できます。

$invalidfilename = [System.IO.Path]::GetInvalidFileNameChars()
"$invalidfilename"

一覧です。

" < > | : * ? \ /

動作検証

ふつうですね。

Test-Path "C:\Work\Directory" -IsValid
# true

これは、Join-Pathでの解釈を見てるとまぁそうかなと。

Test-Path "C:\Work\Directory\\" -IsValid
# true

ちゃんと<>を検知していますね。

Test-Path "C:\Work\Directory\\<>" -IsValid
# false

大丈夫です。

Test-Path "C:\Work\Directory\\as`"" -IsValid
# false

ま、まぁ。はい。

Test-Path "C:\Work\Directory\\asdf" -IsValid
# true

定義通り、validationしていますね。

Test-Path "C:\Work\Directory\\asd?f" -IsValid
# false

どうしてそうなった

Test-Path "c:\teho\::::\sdfg^#%&'!?>.txt" -IsValid
# true

存在しえないはずなのに。

Test-Path "C:\Work\Directory\." -IsValid
# true

これはまさか

Test-Path "C:\Work\Directory\\asd:" -IsValid
# true

同じです

Test-Path "C:\Work\Directory\\asd::::::::" -IsValid
# true

ふむ

Test-Path "C:\Work\Directory\\asd*" -IsValid
# false

原因は、: です。これが混じると判定が狂います。

Test-Path "C:\Work\Directory\\asd::::::*" -IsValid
# true

当然 *?もスルーされています。

Test-Path "C:\Work\Directory\\asd::::::*?" -IsValid
# true

間違いないようですね。

Test-Path "C:\Work\Directory\\asd::::\\>::\*?" -IsValid
# true

Test-Path -IsValid は使いにくいかも

素直に [System.IO.Path]::GetInvalidFileNameChars()[System.IO.Path]::GetInvalidPathChars()でいいかもですが、ダサいです。

# Get invalid charactors for filename
$invalidfilename = [System.IO.Path]::GetInvalidFileNameChars()

# validation with index
$validationIndex = $matchingname.IndexOfAny("test Text !!!!??>>>>")

正常であれば -1 が返ってくるので、判定できます。

あまり 各国の PowerShell も MVPも指摘がないようなので気を付けましょう。

Re: Test-Path isValid parameter