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 cmdlet的目的是获取指定位置的项。相比之下,Get-ChildItem cmdlet用于获取一个或多个指定位置的项和子项。这两个cmdlet的功能并不明确用于检查文件是否存在。

当使用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 cmdlet。此脚本的逻辑是执行以下操作:

  • 测试存档文件夹是否存在使用 Test-Path
    • 如果存档文件夹不存在,脚本将按照以下格式创建新的存档文件夹 – yyyy-MMM-dd_hh-mm-ss-tt
    • 然后,脚本将旧文件移动到存档文件夹。
  • 测试文件是否已存在使用 Get-Item
    • 如果文件存在,脚本首先将其移动到存档文件夹。然后脚本在原始位置创建新文件。
    • 如果文件不存在,脚本创建新文件。

复制下面的代码并保存为 Create-NewFileAfterArchive.ps1。保存脚本后,在 PowerShell 中运行并验证结果。

# 创建-NewFileAfterArchive.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 中运行脚本进行测试。

# 更新-文件内容.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检查文件是否存在有多种方法。在进行任何与文件相关的修改之前检查文件的存在是一个良好的实践。

你已经学习了如何使用 cmdlets Get-ItemGet-ChildItemTest-Path,以及 [System.IO.File]::Exists() .NET 方法。示例向你展示了如何运用这些技巧,并如何将它们与错误处理逻辑结合起来。

别再忍受那些错误信息了。通过添加代码来检查文件是否存在,在执行任何与文件相关的操作之前克服它们。你在这里学到的技巧只涵盖了基础知识,现在轮到你来进一步完善它们了。

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