PowerShellでスクリプトを書くと、ファイルやフォルダの操作は必ず登場します。存在を確認するTest-Path、一覧を取るGet-ChildItem、作成するNew-Item、コピーや移動のCopy-Item・Move-Item、削除のRemove-Itemが基本セットです。
使い方は素直ですが、知っておくと便利な点がいくつかあります。Test-Pathでファイルとフォルダを区別する方法、New-Itemで親フォルダがないと失敗することとその回避、Get-ChildItemの再帰やフィルタです。この記事では、実機で確認しながら、ファイル操作の基本を整理します。
- 存在確認は
Test-Path。-PathType Leaf(ファイル)/Container(フォルダ)で種類も判定できます。 - 一覧は
Get-ChildItem。-Recurseで再帰、-Filterで絞り込み、-File/-Directoryで種類を限定できます。 - 作成は
New-Item -ItemType File/Directory。親フォルダがないと失敗するので、その場合は-Forceを付けます。 - コピーは
Copy-Item、移動はMove-Item。フォルダごとなら-Recurseです。 - 削除の
Remove-Item -Recurse -Forceは強力で取り消せません。慎重に使います。 - パスの組み立ては
Join-Path、分解はSplit-Pathを使うと安全です。
ファイルの読み書きと文字コードは文字化けを直す方法、操作の失敗に備えるtry-catchでエラー処理、複数ファイルの処理に使うループ完全ガイドもあわせて参考になります。
ファイル・フォルダの存在を確認する(Test-Path)
パスが存在するかどうかはTest-Pathで調べます。$true/$falseが返るので、ifと組み合わせて使います。-PathTypeを付けると、ファイルなのかフォルダなのかも判定できます。
# 存在するか(ファイル・フォルダどちらでも True)
Test-Path "C:\work\data.txt" # True / False
# 種類まで判定する
Test-Path "C:\work\data.txt" -PathType Leaf # ファイルなら True
Test-Path "C:\work" -PathType Container # フォルダなら True
# if と組み合わせる
if (Test-Path "C:\work\config.json") {
Write-Host "設定ファイルがあります"
}
実機でも、ファイルに対してTest-Path -PathType LeafはTrue、-PathType ContainerはFalseになりました。-PathTypeを付けないと、ファイルでもフォルダでも存在すればTrueになります。「フォルダがあるか」を厳密に確かめたいときは-PathType Containerを使います。
一覧を取得する(Get-ChildItem)
フォルダの中身を一覧するのがGet-ChildItemです(エイリアスはls・dir)。再帰やフィルタ、種類の限定など、オプションが充実しています。
# フォルダ直下の一覧 Get-ChildItem "C:\work" # サブフォルダまで再帰的に Get-ChildItem "C:\work" -Recurse # 拡張子で絞り込む(-Filter は高速) Get-ChildItem "C:\work" -Filter "*.log" -Recurse # ファイルだけ / フォルダだけ Get-ChildItem "C:\work" -File # ファイルのみ Get-ChildItem "C:\work" -Directory # フォルダのみ # 隠しファイルも含める Get-ChildItem "C:\work" -Force
実機でも、-Recurse -Filter "*.log"でサブフォルダ内の.logファイルを取得でき、-Directoryでフォルダだけ、-Fileでファイルだけに絞れました。取得した各項目は、.Name(名前)、.FullName(フルパス)、.Length(サイズ)、.LastWriteTime(更新日時)などのプロパティを持つオブジェクトです。
# 各ファイルのプロパティを使う
Get-ChildItem "C:\work" -File | ForEach-Object {
Write-Host "$($_.Name) : $($_.Length) バイト : $($_.LastWriteTime)"
}
# 名前(フルパス)だけ取り出す
Get-ChildItem "C:\work" -Filter "*.txt" |
Select-Object -ExpandProperty FullName
一覧をWhere-Objectで絞り込んだりSort-Objectで並べ替えたりすると、より柔軟に扱えます。詳しくはWhere-Object・Select-Object・Sort-Objectを参照してください。
ファイル・フォルダを作成する(New-Item)
新しいファイルやフォルダを作るにはNew-Itemを使い、-ItemTypeでFileかDirectoryを指定します。ここに、つまずきやすい落とし穴があります。
# 空ファイルを作る New-Item -Path "C:\work\new.txt" -ItemType File # フォルダを作る New-Item -Path "C:\work\logs" -ItemType Directory # 中身付きで作りたいときは Set-Content / Out-File Set-Content "C:\work\memo.txt" "メモの内容" -Encoding UTF8
実機で確認したところ、C:\work\x\y\z\deep.txtのように途中のフォルダ(x\y\z)が存在しない状態でNew-Itemを実行すると、失敗しました。途中のフォルダごと作りたいときは、-Forceを付けてください。-Forceを付けると、存在しない親フォルダを自動的に作成します。
# NG: 親フォルダ x\y\z が無いと失敗する # New-Item -Path "C:\work\x\y\z\deep.txt" -ItemType File # OK: -Force で親フォルダごと作成する New-Item -Path "C:\work\x\y\z\deep.txt" -ItemType File -Force # フォルダだけを階層ごと作る場合も -Force(または親から順に作る) New-Item -Path "C:\work\2026\03\09" -ItemType Directory -Force
存在チェックしてから作成する(定番パターン)
「フォルダが無ければ作る」という処理は頻出します。Test-Pathで確認してからNew-Itemするのが定番です。すでにある場合にNew-Itemでエラーにしたくないときに役立ちます。
$logDir = "C:\work\logs"
# 無ければ作る
if (-not (Test-Path $logDir)) {
New-Item -Path $logDir -ItemType Directory | Out-Null
Write-Host "フォルダを作成しました"
}
# ログファイルに追記する(フォルダがある前提)
$logFile = Join-Path $logDir "app.log"
Add-Content -Path $logFile -Value "$(Get-Date) 処理開始" -Encoding UTF8
| Out-Nullを付けているのは、New-Itemが作成したオブジェクトを画面に出さないためです。日付を使ったログ出力はGet-Dateで日付をフォーマットする方法もあわせて使うと便利です。
コピー・移動する(Copy-Item / Move-Item)
コピーはCopy-Item、移動(名前変更も含む)はMove-Itemです。フォルダを中身ごと扱うときは-Recurse、既存を上書きするときは-Forceを付けます。
# ファイルをコピー Copy-Item "C:\work\a.txt" "C:\work\a_backup.txt" # フォルダを中身ごとコピー Copy-Item "C:\work\logs" "C:\backup\logs" -Recurse # 既存ファイルを上書きしてコピー Copy-Item "C:\work\a.txt" "C:\backup\a.txt" -Force # 移動(名前の変更にも使える) Move-Item "C:\work\old.txt" "C:\work\new.txt"
実機でも、Copy-Itemでコピー先が作られ、Move-Itemでは元ファイルが消えて移動先にだけ残ることを確認しました。名前を変えるだけならMove-Itemを使います(専用のRename-Itemもあります)。
削除する(Remove-Item)※慎重に
削除はRemove-Itemです。フォルダを中身ごと消すには-Recurse、確認なしで消すには-Forceを付けます。ただし、この操作は取り消せません。特に-Recurse -Forceは強力なので、慎重に扱います。
# ファイルを削除
Remove-Item "C:\work\temp.txt"
# 実行前に何が消えるか確認する(-WhatIf)
Remove-Item "C:\work\logs" -Recurse -WhatIf
# 「削除されます」という表示だけで、実際には消えない
# フォルダを中身ごと削除(取り消せないので注意)
Remove-Item "C:\work\logs" -Recurse -Force
# 安全策: 存在を確認し、対象を限定してから消す
$target = "C:\work\old_logs"
if (Test-Path $target -PathType Container) {
Remove-Item $target -Recurse -Force
}
Remove-Itemは元に戻せません。削除スクリプトを作るときは、まず-WhatIfを付けて「何が削除されるか」を表示だけさせ、対象が正しいことを確認してから本実行してください。パスを変数で組み立てる場合は、変数が空($null)になっていないかも確認します。空のパスに-Recurse -Forceを付けると、意図しない範囲を消す事故につながります。
パスを組み立てる・分解する(Join-Path / Split-Path)
パスを文字列の+でつなぐと、区切りの\を二重に入れたり入れ忘れたりしがちです。Join-Pathを使うと、区切りを正しく処理してくれます。逆にパスを分解するのがSplit-Pathです。
# パスを組み立てる(区切りは自動で付く) Join-Path "C:\data" "report.txt" # C:\data\report.txt Join-Path $logDir "app.log" # 変数同士も安全につなげる # パスを分解する Split-Path "C:\data\report.txt" -Leaf # report.txt(ファイル名) Split-Path "C:\data\report.txt" -Parent # C:\data(フォルダ部分) # スクリプト自身の場所を基準にパスを作る(よく使う) $here = Split-Path $MyInvocation.MyCommand.Path -Parent $config = Join-Path $here "config.json"
実機でも、Split-Path -Leafはファイル名report.txt、-Parentはフォルダ部分C:\dataを返し、Join-Pathは区切りを正しく入れてC:\data\report.txtを作りました。スクリプトと同じフォルダにある設定ファイルを読むときなど、Join-PathとSplit-Pathの組み合わせが役立ちます。
よくある失敗
New-Itemが親フォルダなしで失敗する
途中のフォルダが無いとNew-Itemは失敗します。階層ごと作りたいときは-Forceを付けます。
Test-Pathでファイルとフォルダを区別しない
-PathTypeを付けないと、ファイルでもフォルダでも存在すればTrueです。種類まで確かめたいなら-PathType Leaf/Containerを使います。
Remove-Itemを確認せず実行する
削除は取り消せません。まず-WhatIfで対象を確認し、パス変数が空でないかもチェックしてから実行します。
パスを+でつないで区切りを間違える
文字列の+は\の付け忘れや二重付けが起きます。Join-Pathを使えば区切りを正しく処理できます。
Get-ChildItemの結果を再帰なしで探す
サブフォルダの中も探したいなら-Recurseを付けます。付けないと直下しか見ません。
よくある質問
if (-not (Test-Path $dir)) { New-Item -Path $dir -ItemType Directory }が定番です。あるいはNew-Item -Path $dir -ItemType Directory -Forceでも、すでにある場合はエラーにならず通せます。Get-ChildItem -Recurseを使います。拡張子で絞るなら-Filter "*.txt" -Recurse、ファイルだけなら-File、フォルダだけなら-Directoryを組み合わせます。-PathType Leafでファイル、-PathType Containerでフォルダを判定します。指定しなければ、どちらでも存在すればTrueになります。Remove-Item -WhatIfで「何が消えるか」を表示だけさせ、対象を確認してから本実行します。パスを変数で作る場合は、空でないかも必ずチェックしてください。-Recurse -Forceは取り消せないため特に慎重に扱います。Join-Path "C:\data" "file.txt"を使うと、区切りの\を正しく処理してくれます。文字列の+でつなぐより、付け忘れや二重付けを防げます。まとめ
- 存在確認は
Test-Path。-PathType Leaf/Containerで種類も判定します。 - 一覧は
Get-ChildItem。-Recurse・-Filter・-File/-Directoryを使い分けます。 - 作成は
New-Item。親フォルダが無いと失敗するので、必要なら-Forceを付けます。 - コピーは
Copy-Item、移動はMove-Item。フォルダごとなら-Recurseです。 - 削除の
Remove-Itemは取り消せません。-WhatIfで先に確認します。 - パスは
Join-Pathで組み立て、Split-Pathで分解すると安全です。
ファイル操作は、Test-Pathで確かめてから動く、New-Itemの親フォルダに気をつける、Remove-Itemは-WhatIfで確認する、という3つの習慣を持つと安全です。基本コマンドを組み合わせれば、バックアップや整理のスクリプトをすぐ書けるようになります。
