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(Core)。この記事のコマンドとスクリプトは、両方のPowerShellエディションに適用されます。Windows、Linux、またはmacOSを使用している場合、PowerShellがインストールされている限り問題ありません。

関連記事:Windows、Linux、およびmacOSにPowerShell 7をダウンロードしてインストールする方法

ファイルの存在を確認するためにPowerShellを使用する

この記事では、PowerShellを使用してファイルが存在するかどうかを確認するための3つの方法をカバーしています。これらの3つの方法は使用方法が異なりますが、コンセプトと最終目標は同じです。これらの3つの方法は次のとおりです:

  • Test-Pathコマンドレット。
  • Get-ItemおよびGet-ChildItemコマンドレット。
  • System.IO.Fileクラス。

これらの3つの方法の例とデモを示します。また、エラーハンドリングとの使用方法も説明します。

Test-Pathの使用

最初の方法は、特定のパスまたはファイルが存在するかどうかを判断するために設計されたTest-Pathコマンドレットです。このコマンドレットを使用してファイルの存在をテストする場合、結果はtrueまたはfalseです。結果は、ファイルが存在するかどうかを示します。

以下は、Test-Pathコマンドレットを使用してファイルのチェックを行うための基本的な構文です。

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

例えば、C:\temp\important_file.txtという名前のファイルが存在するかどうかを確認する場合、以下のコードを使用してください。なお、-PathType Leafの部分は、コマンドレットに対してディレクトリではなくファイルをチェックするように指示しています。

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コマンドレットの使用方法

例:ファイルが存在しない場合にファイルを作成する

この例は、指定された場所にファイルを作成する一般的な使用例です。ファイルがすでに存在する場合の「ファイルは既に存在します」エラーを回避するために、スクリプトではファイルが既に存在するかどうかを確認してから作成します。ファイルが存在する場合は、メッセージを表示し、ファイルの作成を試みません。

以下のコードをコピーして、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."
 }

以下のスクリーンショットは、2つの異なる出力を示しています。最初の出力は、ファイルが存在しない場合にスクリプトを実行したときのものです。2番目の出力は、ファイルを作成し、既に存在する場合のものです。

Running the PowerShell script to create a file

関連記事: 基礎に戻る: PowerShellスクリプトの実行方法

Get-ItemとGet-ChildItemの使用

Get-Itemコマンドレットの目的は、指定された場所のアイテムを取得することです。一方、Get-ChildItemコマンドレットは、指定された場所のアイテムおよび子アイテムを取得するためのものです。これらの2つのコマンドレットの機能は、ファイルの存在を明示的にチェックするためのものではありません。

Get-ItemまたはGet-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で実行し、結果を確認してください。

# Create-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 の強みの1つは、.NET クラスとメソッドをインポートして使用できることです。

たとえば、PowerShell で Exists() メソッドを使用してファイルが存在するかどうかを確認するには、以下のコードを使用します。

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

上記の方法はブール値の結果を生成します-trueまたはfalse。結果が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でスクリプトを実行してテストします。

# Update-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を使用する方法が複数あることを学びました。ファイルに関連する変更を行う前に、ファイルの存在を確認することは良い習慣です。

あなたは、Get-ItemGet-ChildItem、およびTest-Pathのコマンドレットの使用方法について学びました。さらに、[System.IO.File]::Exists() .NETメソッドについても学びました。例では、これらの技術の使用方法と、エラーハンドリングロジックとの組み合わせ方が示されています。

エラーメッセージを受け入れるのではなく、ファイル関連の操作の前にファイルの存在を確認するためのコードを追加することで、それらを克服しましょう。ここで学んだ技術は基本的なものにすぎませんので、それを改善するのはあなた次第です。

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