PowerShell Test-Path Cmdlet:驗證文件、金鑰等

如果您需要驗證路徑到文件、註冊表鍵、證書或任何其他 PowerShell 驅動器路徑,您需要使用 Test-Path 命令。

Test-Path 命令是一種簡單而實用的方式,可以快速檢查文件和其他項目的許多屬性。它可以檢查文件是否存在(或其他項目類型)、字符串是否符合正確的路徑格式,甚至可以檢查項目是否比特定時間更新或更早。

在本教程中,您將學習有關 PowerShell Test-Path 命令的所有知識,以及如何使用它來改進您的 PowerShell 腳本。

先決條件

如果您想按照本教程中的示例進行操作,您需要準備一件事:PowerShell。具體來說,本教程將使用 Windows 10 上的 PowerShell v7.03,儘管您將學到的許多技巧也適用於較舊的版本。

Test-Path 命令有什麼用?

PowerShell Test-Path 命令是最簡單的命令之一。它是 PowerShell 一直以來的命令,只返回兩個值:True 或 False。

但是,不要被它的簡單性所蒙騙;它將節省您在驗證 PowerShell 腳本中的信息時的大量時間。

將PowerShell的Test-Path cmdlet視為在處理PowerShell提供者和驅動程式時的品質控制。在撰寫腳本時,您通常會使用PowerShell驅動程式中包含的各種項目。像C:\、HKLM、Cert等等的PowerShell驅動程式。

Test-Path無法與所有PS驅動程式一起使用。例如,如果您嘗試對註冊表鍵使用Test-Path,它將起作用。但是,如果您嘗試對註冊表值使用Test-Path,它將每次返回False

如果您好奇,現在在PowerShell中運行Get-PSDrive cmdlet,並注意所有出現的PS驅動程式。

PS Drives after running Get-PSDrive

所有這些驅動程式都包含像C:\WindowsHKLM:\Software等的路徑。在PowerShell腳本中處理路徑時,首先測試路徑是否有效或存在是一個好習慣。這就是PowerShell的Test-Path的作用。

Test-Path定義了一個條件,根據特定條件是否符合(通常是文件/文件夾、註冊表鍵、憑證甚至變數是否存在)返回TrueFalse

Test-Path參數和用法

像许多其他PowerShell cmdlet一样,Test-Path cmdlet有各种参数来改变其行为。现在让我们讨论每个参数,并演示它的工作原理以及可能看到的结果是什么。

Path

Path参数是您在每次执行Test-Path时使用的一个必需参数。 Path参数定义了您要测试存在性的PSDrive路径。

例如,如果您想要测试文件夹C:\Foo是否存在,您将为Path参数提供相应的路径。然后,根据C:\Foo是否实际存在,Test-Path将返回TrueFalse

PS> Test-Path -Path 'C:\Foo'
True

这种技术也可以用于任何项目路径。也许您想要测试注册表键HKLM:\Software\Foo是否存在。只需在Path参数中使用注册表键路径即可。

PS> Test-Path -Path 'HKLM:\Software\Foo'
True

请注意,本教程中演示的所有技术都适用于任何PowerShell驱动器路径。

使用通配符

如果您并不在意路径是否具有字面值,而只想检查路径是否与特定模式匹配,该怎么办?在这种情况下,您可以在Path值中使用通配符。

也许您想要检查您的C:\Foo文件夹是否包含以Bar开头的任何子文件夹。在这种情况下,您可以使用通配符。

PS> Test-Path -Path 'C:\Foo\Bar*'

一旦执行上述命令,Test-Path 将检查以任何名称开始为Bar的文件夹是否存在,并根据是否存在匹配此条件的文件夹返回TrueFalse

星号(*)匹配一个或多个字符,但您也可以使用问号(?)来更详细地测试单个字符。

以上述场景为例,如果文件夹C:\Foo\Bar1存在,您可以使用以下命令测试以Bar开头且恰好为四个字符的Foo子文件夹。

PS> Test-Path -Path 'C:\Foo\Bar?'

如果出于某种原因,您想使用通配符的Path参数,但又想要字面匹配通配符字符(如*),您可以使用反引号(`)转义通配符字符。

LiteralPath

LiteralPath参数与Path参数几乎相同,只有一个例外;它不允许使用通配符。使用LiteralPath字面地解释路径的值。

例如,如果您尝试在使用LiteralPath时将星号或问号放在路径值中,Test-Path将完全忽略通配符字符,并字面上测试C:\Foo\Bar?,如下面的示例所示。

PS> Test-Path -LiteralPath 'C:\Foo\Bar?'

如果您不需要使用任何通配符字符来确保Test-Path测试您期望的路径,应将LiteralPath用作默认路径参数。

PathType

預設情況下,在執行 Test-Path 並提供路徑時,如果在該路徑中找到任何項目,它將返回 True。這個路徑中的項目可以是像檔案夾、註冊表鍵、憑證存儲等容器,也可以是像檔案、註冊表值或憑證這樣的葉子。

您可以使用 PathType 參數強制 Test-Path 進行更細粒度的測試,特別是測試容器或葉子項目。

預設情況下,Test-Path 使用 PathTypeAny

例如,如果在 C:\Foo\Bar 路徑下有一個資料夾,而您要尋找該路徑下的檔案,您可以使用下面的 PathType 參數。您只想檢查是否存在名為 C:\Foo\Bar 的檔案。

PS> Test-Path -LiteralPath 'C:\Foo\Bar' -PathType Leaf

也許您需要確認 C:\Foo\Bar 是否實際上是一個檔案。在這種情況下,您需要檢查容器。

PS> Test-Path -LiteralPath 'C:\Foo\Bar' -PathType Container

包含

如果使用 Path 參數和萬用字元,有時候您需要更具體的結果。在這種情況下,您需要使用 IncludeExclude 參數。

假設您有以下資料夾:

  • C:\Foo\Bar1
  • C:\Foo\Bar2
  • C:\Foo\Bar3

您想檢查是否存在以 Bar 開頭且正好有四個字元的資料夾,例如 Bar1Bar2 等。

PS> Test-Path -Path C:\Foo\Bar? -PathType Container

上述命令可以正常運行,但現在您只想在 C:\Foo 中查找名為 Bar2 的資料夾。在這種情況下,您可以使用 Include 參數。

PS> Test-Path -Path C:\Foo\Bar? -PathType Container -Include 'Bar2'

現在上述命令只測試一個文件夾 C:\Foo\Bar2。你最好直接使用 Test-Path -Path 'C:\Foo\Bar2' -PathType Container

排除

排除參數的作用與包含參數類似,只是這次它排除與指定字符串匹配的路徑。

也許你想確保 C:\Foo 文件夾內至少有一個文件,你可以使用以下命令:

PS> Test-Path -Path C:\Foo\* -PathType Leaf

上述命令返回 TrueFalse,如果 C:\Foo 中有任何文件。但也許你想確保除了擁有 txt 文件擴展名的文件外,還存在其他文件。在這種情況下,你可以使用 Exclude 參數,通過使用通配符來排除所有具有 txt 擴展名的文件。

PS> Test-Path -Path C:\Foo\* -PathType Leaf -Exclude *.txt

篩選器

根據微軟的文檔,Filter 參數 “指定以提供者的格式或語言的過濾器。此參數的值屬於 Path 參數。過濾器的語法,包括通配符字符的使用,取決於提供者”。

儘管 Filter 參數應該與其他 cmdlet 一起使用,例如 Get-Childitem,但它很少甚至從不與 Test-Path 一起使用。如果你找到了 Filter 參數的好用法,請在 Twitter 上聯繫 @adbertram。

相關: Get-ChildItem:將文件、註冊表、憑證等列出為一個

NewerThan

您是否曾經需要檢查文件的時間戳,並基於此做出決策?如果是這樣,NewerThanOlderThan參數可以節省大量程式碼。NewerThan參數檢查項目的時間戳是否比指定日期更新。

NewerThan參數接受字符串或DateTime對象表示要檢查的時間戳。例如,要檢查文件C:\Foo\bar.txt是否在2021年1月20日之後創建,您可以像下面這樣運行Test-Path

Test-Path -LiteralPath 'C:\Foo\bar.txt' -NewerThan 'January 20, 2021'
##或
Test-Path -LiteralPath 'C:\Foo\bar.txt' -NewerThan '1/20/21'

OlderThan

OlderThan參數與NewerThan參數完全相同,只是相反。此參數檢查項目是否更早於特定日期。

Test-Path -LiteralPath 'C:\Foo\bar.txt' -OlderThan 'January 20, 2021'
##或
Test-Path -LiteralPath 'C:\Foo\bar.txt' -OlderThan '1/20/21'

IsValid

如果您曾經在腳本中動態構建過路徑,您就會知道這種困難。有時候您可能在路徑中打錯字或者不小心加入了一些特殊字符;如果是這樣,IsValid參數就是為您而設的。

IsValid參數是一個獨特的參數,它將Test-Path轉變為一個檢查路徑語法而不是項目存在性的cmdlet。此參數僅確認路徑是否有效。

例如,您可能需要验证路径是否在语法上有效。您正在使用一对变量,并将它们连接起来构建路径。

在连接路径时,始终使用Join-Path命令。这仅为示例目的!

$someVar = 'abc:dff'
$rootPath = 'C:\'
$path = "$someVar$rootPath

现在,为了确保您动态创建的路径有效,可以使用如下的IsValid参数。您会发现Test-Path返回False

PS> Test-Path -LiteralPath $path -IsValid
False

路径abc:dffC:\现在不是一个有效的路径,从而允许您从这种情况创建验证程序。

如果您使用的是 PowerShell v6.1.2 或更早版本,并且同时使用了IsValidPathType参数,Test-Path将忽略PathType参数。

凭据

尽管您会在Test-Path上找到Credential参数,您可能会认为您可以使用它来作为另一个用户验证到 PS 驱动器。这是一个有效的假设,但是这是错误的。

不幸的是,Credential参数在Test-Path命令中没有太多作用。Microsoft建议使用Invoke-Command命令,并在那里使用Credential参数,如果您想要以其他凭据调用Test-Path

Invoke-Command -Credential (Get-Credential) -Scriptblock {Test-Path -LiteralPath 'C:\'}

相关: Invoke-Command:运行远程代码的最佳方法

Source:
https://adamtheautomator.com/powershell-test-path/