PowerShell文件存在驗證:全面指南

您是否使用PowerShell來創建、讀取、更新和刪除文件?如果是的話,您可能會遇到目標文件不存在或已存在時的錯誤。幸運的是,在PowerShell中有多種方法可以在對文件進行任何操作之前檢查文件是否存在。

例如,您可以在代碼創建文件之前先測試文件是否已經存在。如下圖所示,您可以編寫更好的代碼並獲得清晰的輸出結果。

Creating a file that already exists

在本文中,您將學習使用PowerShell檢查文件是否存在的不同方法。您還將學習如何使用這些方法來編寫更好的代碼和具有錯誤處理邏輯的結果。

前提條件

使用自助重置密碼解決方案減少服務台呼叫並更新遠程用戶的緩存憑據,即使在VPN外也可以。 立即獲取Specops uReset的演示!

本文是一個實用指南,您將通過不同的示例進行學習。為了跟隨這些示例,您需要以下內容:

  • 代碼編輯器。推薦的編輯器包括 Visual Studio CodeAtom,它們可以跨平台使用。如果您在Windows計算機上工作,還可以使用Windows PowerShell ISE。
  • Windows PowerShell 5.1(桌面版)或PowerShell 7.1(核心版)。本文中的命令和脚本适用于两个PowerShell版本。只要安装了PowerShell,您可以在Windows、Linux或macOS上使用。

相关内容:如何在Windows、Linux和macOS上下载和安装PowerShell 7

使用PowerShell检查文件是否存在

本文介绍了三种使用PowerShell检查文件是否存在的方法。这三种方法的用法不同,但概念和目标相同。这三种方法分别是:

  • Test-Path命令。
  • Get-ItemGet-ChildItem命令。
  • System.IO.File类。

每种方法都会有示例和演示,包括如何使用错误处理。

使用Test-Path

第一种方法是使用Test-Path命令,该命令特别设计用于确定路径或文件是否存在。当使用此命令来测试文件是否存在时,结果将是truefalse。结果表示文件是否存在。

下面是将Test-Path命令与检查文件一起使用的基本语法。

Test-Path -Path <PATH to FILE> -PathType Leaf

例如,如果您需要检查名为C:\temp\important_file.txt的文件是否存在,使用以下代码。请注意,-PathType Leaf部分告诉cmdlet显式地检查文件而不是目录。

Test-Path -Path C:\temp\important_file.txt -PathType Leaf

在PowerShell中运行上述命令时,如果文件存在,则结果返回True。否则,结果将是False,如下面的屏幕截图所示。

Using Test-Path in PowerShell to check if a file exists

相关信息:如何使用PowerShell的Test-Path Cmdlet

示例:如果文件不存在,则创建文件

此示例是在指定位置创建文件的典型用例。为了避免“文件已存在”错误,脚本在创建文件之前检查文件是否已经存在。如果文件存在,则脚本显示一条消息,并且不再尝试创建文件。

复制下面的代码并将其保存在名为Create-NewFile.ps1的文件中。如果您想更改文件的输出位置,请确保更改$path变量的值。保存脚本后,在PowerShell中运行它进行测试。

# Create-NewFile.ps1

# 文件的完整路径
$file = 'c:\temp\important_file.txt'

# 如果文件不存在,则创建它。
if (-not(Test-Path -Path $file -PathType Leaf)) {
     try {
         $null = New-Item -ItemType File -Path $file -Force -ErrorAction Stop
         Write-Host "The file [$file] has been created."
     }
     catch {
         throw $_.Exception.Message
     }
 }
# 如果文件已存在,则显示消息并且不执行任何操作。
 else {
     Write-Host "Cannot create [$file] because a file with that name already exists."
 }

下面的屏幕截图显示了两种不同的输出结果。第一种是在脚本运行时文件不存在时的输出。第二种是创建了文件,并且文件已经存在时的输出。

Running the PowerShell script to create a file

相关文章: 回归基础:如何运行 PowerShell 脚本

使用 Get-Item 和 Get-ChildItem

Get-Item 命令的目的是获取指定位置的项目。相比之下,Get-ChildItem 命令是获取一个或多个指定位置的项目和子项目。这两个命令的功能并不是显式地用于检查文件是否存在。

当使用 Get-ItemGet-ChildItem 获取不存在的项目时会发生什么?每个缺失的文件都会返回一个错误。以下面的命令为例。

$file = 'c:\temp\important_file.txt'
Get-Item -Path $file
Get-ChildItem -Path $file

假设文件 c:\temp\important_file.txt 不存在。上面的每个命令都会返回一个错误。从下面的示例中可以看到,这两个命令的错误消息是相同的。

Using Get-Item and Get-ChildItem in PowerShell to check if a file exists

示例:归档现有文件并创建新文件

在此示例中,脚本使用了 Get-ItemTest-Path 命令。该脚本的逻辑是执行以下操作:

  • 使用Test-Path測試存檔資料夾是否存在。
    • 如果存檔資料夾不存在,腳本會以以下格式創建新的存檔資料夾 – yyyy-MMM-dd_hh-mm-ss-tt
    • 然後,腳本將舊檔案移動到存檔資料夾。
  • 使用Get-Item測試檔案是否已存在。
    • 如果檔案存在,腳本會先將它移動到存檔資料夾,然後在原始位置創建新檔案。
    • 如果檔案不存在,腳本會創建新檔案。

複製下面的程式碼,並將其儲存為Create-NewFileAfterArchive.ps1。儲存腳本後,在PowerShell中執行它並驗證結果。

# 創建-在存檔後建立新檔案.ps1

# 檔案的完整路徑
$file = 'c:\temp\important_file.txt'

# 存檔資料夾的完整路徑
$archiveFolder = "c:\temp\archive_$(get-date -Format 'yyyy-MMM-dd_hh-mm-ss-tt')\"

# 若檔案存在,將其移至存檔資料夾,然後建立新檔案。
if (Get-Item -Path $file -ErrorAction Ignore) {
    try {
        ## 若存檔資料夾不存在,現在就建立。
        if (-not(Test-Path -Path $archiveFolder -PathType Container)) {
            $null = New-Item -ItemType Directory -Path $archiveFolder -ErrorAction STOP
        }
        ## 將現有檔案移至存檔資料夾。
        Move-Item -Path $file -Destination $archiveFolder -Force -ErrorAction STOP
        Write-Host "The old file [$file] has been archived to [$archiveFolder]"
     } catch {
        throw $_.Exception.Message
     }
 }
 Create the new file
 try {
     $null = New-Item -ItemType File -Path $file -Force -ErrorAction Stop
     Write-Host "The new file [$file] has been created."
 } catch {
    Write-Host $_.Exception.Message
 }

提示:使用 -ErrorAction Ignore 參數可以抑制錯誤(不會顯示在控制台上),並且不會將錯誤記錄到 $error 自動變數

在下方的螢幕截圖中,第一次執行指令建立了檔案 c:\temp\important_file.txt。接著的指令執行每次都建立一個新的存檔資料夾,將現有的檔案移至存檔資料夾,然後在 c:\temp\important_file.txt 中建立新檔案。

Running a script in PowerShell to check if a file exists using Get-Item

使用 [System.IO.File]::Exists() .NET 方法

本文中要學習的最後一種方法是使用 System.IO.File .NET 類別,具體來說是使用 Exists() 方法。PowerShell 的一個優勢就是能夠匯入和使用 .NET 類別和方法。

例如,若要在 PowerShell 中使用 Exists() 方法來檢查檔案是否存在,請使用下面的程式碼。

[System.IO.File]::Exists("PATH")

上述方法產生一個布爾結果-truefalse。如果結果返回true,則表示目標文件存在。否則,當目標文件不存在時,返回的結果是false

在下面的示例代碼中,該命令檢查文件c:\temp\important_file.txt的存在性。

$file = 'c:\temp\important_file.txt'
[System.IO.File]::Exists($file)

從下面的結果可以看出,結果返回true,確認文件存在。

Using System.IO.File class in PowerShell

使用這個.NET方法,您還可以使用三元操作,如下面的示例所示。您可以自定義結果消息,以更簡潔的方式顯示,而不是顯示默認的true或false結果。但是,在此示例中,三元運算符僅適用於PowerShell 7+。

$file = 'c:\temp\important_file.txt'
[System.IO.File]::Exists($file) ? "The file exists." : "The file does not exist."

示例:如果文件存在,則更新文件內容

此示例腳本通過追加新的GUID值來更新文本文件。但是,只有在文件存在的情況下才進行內容更新。否則,腳本顯示一個消息,然後不做其他操作。

複製下面的腳本,將其保存為Update-FileContents.ps1。如果需要,請更改$file變量的文件路徑值。然後在PowerShell中運行腳本進行測試。

# 更新-FileContents.ps1

#文件的完整路徑
$file = 'c:\temp\important_file.txt'

#如果文件存在,在文件中追加新的GUID值。
if ([System.IO.File]::Exists($file)) {
    try {
        $newValue = ((New-Guid).Guid)
        Add-Content -Path $file -Value $newValue -ErrorAction STOP
        Write-Host "The file [$file] has been updated with [$newValue]"
     } catch {
        throw $_.Exception.Message
     }    
 }

#如果文件不存在,顯示一條消息並且不執行任何操作。
 else {
     Write-Host "The file [$file] could not be updated because it does not exist."
 }

您可以在下面的截圖中看到,腳本在每次運行時都會更新文件。更新發生是因為[System.IO.File]::Exists()方法確認了文件c:\temp\important_file.txt的存在。

最後,使用命令gc c:\temp\important_file.txt讀取文件的內容確認腳本已使用GUID值更新了文件。

Using [System.IO.File]::Exists() .NET Method in PowerShell

相關: 使用PowerShell數據類型加速器加快編程速度

結論

通過自助密碼重置解決方案,減少服務台呼叫和更新遠程用戶的緩存憑據,即使在VPN外也可以進行。了解Specops uReset的演示!

在本文中,您已經學到了使用PowerShell檢查文件是否存在的多種方法。在進行任何與文件相關的修改之前,檢查文件的存在是一種良好的實踐。

您已經學習了使用 cmdlet Get-ItemGet-ChildItemTest-Path,以及 [System.IO.File]::Exists() .NET 方法。示例向您展示了如何使用這些技巧以及如何將它們與錯誤處理邏輯結合使用。

不再忍受那些錯誤訊息,通過在任何與文件相關的操作之前添加代碼來檢查文件是否存在,克服它們。您在這裡學到的技巧只涵蓋了基礎知識,現在由您來改進它們。

Source:
https://adamtheautomator.com/powershell-check-if-file-exists/