0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事でやること

VBSでは、ファイルやフォルダを操作するために FileSystemObject をよく使います。

たとえば、次のような処理です。

Set fso = CreateObject("Scripting.FileSystemObject")

If fso.FileExists("C:\work\sample.txt") Then
    WScript.Echo "ファイルがあります"
End If

fso.CopyFile "C:\work\sample.txt", "C:\work\backup\sample.txt"

PowerShellでは、FileSystemObjectを使わなくても、標準コマンドでファイル操作ができます。

この記事では、VBSのFileSystemObjectでよく使う処理を、PowerShellではどのように書くかを整理します。


まず結論

VBSのFileSystemObjectは、PowerShellでは主に次のコマンドに置き換えられます。

VBS FileSystemObject PowerShell
FileExists Test-Path
FolderExists Test-Path
CreateFolder New-Item -ItemType Directory
CreateTextFile New-Item / Set-Content
OpenTextFile Get-Content / Set-Content / Add-Content
CopyFile Copy-Item
CopyFolder Copy-Item -Recurse
MoveFile Move-Item
MoveFolder Move-Item
DeleteFile Remove-Item
DeleteFolder Remove-Item -Recurse
GetFile Get-Item
GetFolder Get-Item
GetFolder.Files Get-ChildItem -File
GetFolder.SubFolders Get-ChildItem -Directory

PowerShellでは、ファイルやフォルダを単なる文字列ではなく、オブジェクトとして扱えます。

たとえば、Get-ChildItem で取得したファイルには、次のような情報があります。

プロパティ 内容
Name ファイル名
FullName フルパス
Extension 拡張子
Length サイズ
CreationTime 作成日時
LastWriteTime 更新日時

この点が、VBSからPowerShellへ移行するときの大きな違いです。


検証用フォルダを作る

まず、検証用フォルダを作成します。

New-Item -ItemType Directory -Path "C:\work\ps-fso-test" -Force
Set-Location "C:\work\ps-fso-test"

検証用ファイルを作成します。

Set-Content -Path ".\sample.txt" -Value "FileSystemObject migration test" -Encoding UTF8

バックアップ用フォルダも作っておきます。

New-Item -ItemType Directory -Path ".\backup" -Force

確認します。

Get-ChildItem

FileExistsをTest-Pathに置き換える

VBSでは、ファイルの存在確認に FileExists を使います。

Set fso = CreateObject("Scripting.FileSystemObject")

If fso.FileExists("C:\work\sample.txt") Then
    WScript.Echo "ファイルがあります"
Else
    WScript.Echo "ファイルがありません"
End If

PowerShellでは、Test-Path を使います。

if (Test-Path ".\sample.txt") {
    Write-Host "ファイルがあります"
}
else {
    Write-Host "ファイルがありません"
}

ただし、Test-Path はファイルにもフォルダにも使えます。
ファイルであることまで確認したい場合は、Get-Item と組み合わせます。

if ((Test-Path ".\sample.txt") -and ((Get-Item ".\sample.txt").PSIsContainer -eq $false)) {
    Write-Host "ファイルです"
}

PowerShell 7では、次のように -PathType Leaf を使うと分かりやすいです。

if (Test-Path ".\sample.txt" -PathType Leaf) {
    Write-Host "ファイルがあります"
}

FolderExistsをTest-Pathに置き換える

VBSでは、フォルダの存在確認に FolderExists を使います。

If fso.FolderExists("C:\work\backup") Then
    WScript.Echo "フォルダがあります"
End If

PowerShellでは、同じく Test-Path を使います。

if (Test-Path ".\backup") {
    Write-Host "フォルダがあります"
}

フォルダであることまで確認したい場合は、PowerShell 7なら -PathType Container を使えます。

if (Test-Path ".\backup" -PathType Container) {
    Write-Host "フォルダがあります"
}

Windows PowerShell 5.1でも、通常の存在確認であれば Test-Path で十分なことが多いです。


CreateFolderをNew-Itemに置き換える

VBSでは、フォルダ作成に CreateFolder を使います。

fso.CreateFolder "C:\work\backup"

PowerShellでは、New-Item を使います。

New-Item -ItemType Directory -Path ".\backup" -Force

-Force を付けると、既にフォルダが存在していてもエラーになりにくくなります。

実務では、コピー先やログ出力先のフォルダを先に作ることが多いです。

$backupDir = ".\backup"
New-Item -ItemType Directory -Path $backupDir -Force | Out-Null

| Out-Null を付けると、フォルダ作成時の表示を抑制できます。


CreateTextFileをSet-Contentに置き換える

VBSでは、テキストファイル作成に CreateTextFile を使います。

Set file = fso.CreateTextFile("C:\work\log.txt", True)
file.WriteLine "処理開始"
file.Close

PowerShellでは、Set-Content を使うと簡単です。

Set-Content -Path ".\log.txt" -Value "処理開始" -Encoding UTF8

追記したい場合は、Add-Content を使います。

Add-Content -Path ".\log.txt" -Value "処理終了" -Encoding UTF8

使い分けは次の通りです。

コマンド 動き
Set-Content 上書き
Add-Content 追記
Get-Content 読み込み

ログ出力では、基本的に Add-Content を使うことが多いです。


OpenTextFileをGet-Content / Set-Content / Add-Contentに置き換える

VBSでは、テキストファイルの読み書きに OpenTextFile を使います。

Set file = fso.OpenTextFile("C:\work\sample.txt", 1)
text = file.ReadAll
file.Close

PowerShellで読み込む場合は、Get-Content を使います。

$text = Get-Content -Path ".\sample.txt" -Encoding UTF8

1つの文字列としてまとめて読みたい場合は、-Raw を使います。

$text = Get-Content -Path ".\sample.txt" -Raw -Encoding UTF8

上書きする場合は Set-Content です。

Set-Content -Path ".\sample.txt" -Value "上書きしました" -Encoding UTF8

追記する場合は Add-Content です。

Add-Content -Path ".\sample.txt" -Value "追記しました" -Encoding UTF8

文字コード問題を避けるため、日本語を扱う場合は -Encoding を明示しておくと安全です。


CopyFileをCopy-Itemに置き換える

VBSでは、ファイルコピーに CopyFile を使います。

fso.CopyFile "C:\work\sample.txt", "C:\work\backup\sample.txt", True

PowerShellでは、Copy-Item を使います。

Copy-Item -Path ".\sample.txt" -Destination ".\backup\sample.txt" -Force

コピー先フォルダが存在しないと失敗します。
そのため、先にフォルダを作成します。

$backupDir = ".\backup"
New-Item -ItemType Directory -Path $backupDir -Force | Out-Null

Copy-Item -Path ".\sample.txt" -Destination (Join-Path $backupDir "sample.txt") -Force

実務では、このように New-ItemCopy-Item をセットで使うことが多いです。


CopyFolderをCopy-Item -Recurseに置き換える

VBSでは、フォルダコピーに CopyFolder を使います。

fso.CopyFolder "C:\work\data", "C:\work\backup\data", True

PowerShellでは、Copy-Item -Recurse を使います。

Copy-Item -Path ".\data" -Destination ".\backup\data" -Recurse -Force

検証用にフォルダを作って試します。

New-Item -ItemType Directory -Path ".\data" -Force | Out-Null
Set-Content -Path ".\data\a.txt" -Value "a" -Encoding UTF8
Set-Content -Path ".\data\b.txt" -Value "b" -Encoding UTF8

Copy-Item -Path ".\data" -Destination ".\backup\data" -Recurse -Force

確認します。

Get-ChildItem ".\backup\data" -Recurse

MoveFileをMove-Itemに置き換える

VBSでは、ファイル移動に MoveFile を使います。

fso.MoveFile "C:\work\sample.txt", "C:\work\backup\sample.txt"

PowerShellでは、Move-Item を使います。

Move-Item -Path ".\sample.txt" -Destination ".\backup\sample.txt" -Force

移動先フォルダが存在しないと失敗します。
先に作成しておくと安全です。

$destDir = ".\moved"
New-Item -ItemType Directory -Path $destDir -Force | Out-Null

Move-Item -Path ".\backup\sample.txt" -Destination (Join-Path $destDir "sample.txt") -Force

ファイル名だけ変更したい場合は、Rename-Item を使います。

Rename-Item -Path ".\moved\sample.txt" -NewName "sample_renamed.txt"

移動とリネームは似ていますが、意味を分けて使うと読みやすくなります。


DeleteFileをRemove-Itemに置き換える

VBSでは、ファイル削除に DeleteFile を使います。

fso.DeleteFile "C:\work\sample.txt", True

PowerShellでは、Remove-Item を使います。

Remove-Item -Path ".\moved\sample_renamed.txt"

ただし、削除は危険な処理です。
まずは -WhatIf を付けて、削除対象を確認します。

Remove-Item -Path ".\moved\sample_renamed.txt" -WhatIf

複数ファイルを削除する場合も、最初は必ず -WhatIf で確認します。

Get-ChildItem -Path ".\" -File -Filter "*.log" |
    Remove-Item -WhatIf

問題なければ、-WhatIf を外します。

Get-ChildItem -Path ".\" -File -Filter "*.log" |
    Remove-Item

DeleteFolderをRemove-Item -Recurseに置き換える

VBSでは、フォルダ削除に DeleteFolder を使います。

fso.DeleteFolder "C:\work\data", True

PowerShellでは、Remove-Item -Recurse を使います。

Remove-Item -Path ".\data" -Recurse

ただし、フォルダ削除は影響が大きいため、まず -WhatIf で確認します。

Remove-Item -Path ".\data" -Recurse -WhatIf

読み取り専用ファイルなども含めて削除する場合は、-Force を使うことがあります。

Remove-Item -Path ".\data" -Recurse -Force

ただし、-Recurse -Force は強力です。
対象パスを必ず確認してから実行します。


GetFileをGet-Itemに置き換える

VBSでは、GetFile を使ってファイルオブジェクトを取得します。

Set file = fso.GetFile("C:\work\sample.txt")
WScript.Echo file.Name
WScript.Echo file.Size
WScript.Echo file.DateLastModified

PowerShellでは、Get-Item を使います。

$file = Get-Item ".\sample.txt"

Write-Host $file.Name
Write-Host $file.Length
Write-Host $file.LastWriteTime

PowerShellでは、取得したファイルにさまざまなプロパティがあります。

$file | Select-Object Name, FullName, Length, CreationTime, LastWriteTime

ファイルサイズは Length です。
バイト単位なので、MB表示にしたい場合は次のようにします。

[math]::Round($file.Length / 1MB, 2)

GetFolder.FilesをGet-ChildItem -Fileに置き換える

VBSでは、フォルダ内のファイル一覧を取得するために GetFolder(...).Files を使います。

Set folder = fso.GetFolder("C:\work")
For Each file In folder.Files
    WScript.Echo file.Name
Next

PowerShellでは、Get-ChildItem -File を使います。

Get-ChildItem -Path "." -File

必要な項目だけ表示するなら、Select-Object を使います。

Get-ChildItem -Path "." -File |
    Select-Object Name, FullName, Length, LastWriteTime

サブフォルダも含める場合は、-Recurse を付けます。

Get-ChildItem -Path "." -File -Recurse |
    Select-Object Name, FullName, Length, LastWriteTime

PowerShellでは、この一覧をそのままCSVに出力できます。

Get-ChildItem -Path "." -File -Recurse |
    Select-Object Name, FullName, Length, LastWriteTime |
    Export-Csv -Path ".\file_list.csv" -NoTypeInformation -Encoding UTF8

GetFolder.SubFoldersをGet-ChildItem -Directoryに置き換える

VBSでは、サブフォルダ一覧に SubFolders を使います。

Set folder = fso.GetFolder("C:\work")
For Each subFolder In folder.SubFolders
    WScript.Echo subFolder.Name
Next

PowerShellでは、Get-ChildItem -Directory を使います。

Get-ChildItem -Path "." -Directory

サブフォルダも含めて取得する場合は、-Recurse を付けます。

Get-ChildItem -Path "." -Directory -Recurse

必要な項目だけ表示します。

Get-ChildItem -Path "." -Directory -Recurse |
    Select-Object Name, FullName, CreationTime, LastWriteTime

BuildPathはJoin-Pathに置き換える

VBSでは、パスを結合するために BuildPath を使うことがあります。

path = fso.BuildPath("C:\work", "sample.txt")

PowerShellでは、Join-Path を使います。

$path = Join-Path "C:\work" "sample.txt"

.ps1 と同じフォルダを基準にするなら、次のようにします。

$filePath = Join-Path $PSScriptRoot "sample.txt"

文字列を直接結合することもできます。

$filePath = $PSScriptRoot + "\sample.txt"

ただし、実務では Join-Path を使う方が安全で読みやすいです。


GetExtensionNameはExtensionに置き換える

VBSでは、拡張子を取得するために GetExtensionName を使います。

ext = fso.GetExtensionName("C:\work\sample.txt")

PowerShellでは、Get-ItemGet-ChildItemExtension プロパティを使います。

$file = Get-Item ".\sample.txt"
$file.Extension

結果は .txt のようにドット付きで返ります。

複数ファイルの拡張子を表示します。

Get-ChildItem -File |
    Select-Object Name, Extension

拡張子で絞る場合は、Where-Object を使います。

Get-ChildItem -File |
    Where-Object { $_.Extension -eq ".txt" }

GetBaseNameはBaseNameに置き換える

VBSでは、拡張子を除いたファイル名を取得するために GetBaseName を使います。

baseName = fso.GetBaseName("C:\work\sample.txt")

PowerShellでは、BaseName プロパティを使います。

$file = Get-Item ".\sample.txt"
$file.BaseName

複数ファイルで確認する場合です。

Get-ChildItem -File |
    Select-Object Name, BaseName, Extension

日付付きファイル名を作る場合にも使えます。

$file = Get-Item ".\sample.txt"
$today = Get-Date -Format "yyyyMMdd"

$newName = "$($file.BaseName)_$today$($file.Extension)"
Write-Host $newName

GetParentFolderNameはDirectoryNameに置き換える

VBSでは、親フォルダを取得するために GetParentFolderName を使います。

parent = fso.GetParentFolderName("C:\work\sample.txt")

PowerShellでは、DirectoryName を使います。

$file = Get-Item ".\sample.txt"
$file.DirectoryName

ファイル一覧で親フォルダを表示します。

Get-ChildItem -File -Recurse |
    Select-Object Name, DirectoryName, FullName

共有フォルダ調査などでは、どのフォルダにファイルがあるかを確認するために便利です。


VBSとPowerShellの大きな違い

FileSystemObjectをPowerShellに置き換えるとき、単純にコマンド名を置き換えるだけでは不十分です。

大きな違いは、PowerShellがオブジェクトを扱うことです。

VBSでは、ファイルパスやファイル名を文字列として扱う場面が多くなります。

WScript.Echo file.Name
WScript.Echo file.Size

PowerShellでは、Get-ChildItem の結果にプロパティが含まれています。

Get-ChildItem -File |
    Select-Object Name, FullName, Length, LastWriteTime

さらに、条件抽出や並べ替えもできます。

Get-ChildItem -File -Recurse |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
    Sort-Object LastWriteTime |
    Select-Object Name, FullName, LastWriteTime

このように、PowerShellでは次の流れで考えると分かりやすいです。

集める
絞る
並べる
選ぶ
出力する

実務で使いやすいテンプレート

FileSystemObject移行でよく使う処理をまとめたテンプレートです。

$baseDir = $PSScriptRoot
$inputDir = Join-Path $baseDir "input"
$backupDir = Join-Path $baseDir "backup"
$logDir = Join-Path $baseDir "logs"

New-Item -ItemType Directory -Path $inputDir -Force | Out-Null
New-Item -ItemType Directory -Path $backupDir -Force | Out-Null
New-Item -ItemType Directory -Path $logDir -Force | Out-Null

$today = Get-Date -Format "yyyyMMdd"
$logPath = Join-Path $logDir "process_$today.log"

function Write-Log {
    param(
        [string]$Message,
        [string]$Level = "INFO"
    )

    $now = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    Add-Content -Path $logPath -Value "[$now][$Level] $Message" -Encoding UTF8
}

Write-Log "処理開始"
Write-Log "inputDir: $inputDir"
Write-Log "backupDir: $backupDir"

try {
    $files = Get-ChildItem -Path $inputDir -File -Filter "*.txt" -ErrorAction Stop

    Write-Log "対象ファイル数: $($files.Count)"

    foreach ($file in $files) {
        try {
            $destPath = Join-Path $backupDir $file.Name

            Copy-Item -Path $file.FullName -Destination $destPath -Force -ErrorAction Stop

            Write-Log "コピー成功: $($file.FullName) -> $destPath"
        }
        catch {
            Write-Log "コピー失敗: $($file.FullName) / $($_.Exception.Message)" "ERROR"
        }
    }
}
catch {
    Write-Log "全体エラー: $($_.Exception.Message)" "ERROR"
}
finally {
    Write-Log "処理終了"
}

このテンプレートでは、次の処理をしています。

スクリプト配置場所を基準にする
input / backup / logs フォルダを作る
input内の.txtファイルを取得する
backupへコピーする
処理結果をログに残す

VBSのFileSystemObjectでよくある「指定フォルダ内のファイルを処理する」パターンを、PowerShellらしい形に置き換えた例です。


よくあるつまずき

Test-Pathだけではファイルかフォルダか分からない

Test-Path は、ファイルにもフォルダにも使えます。

Test-Path ".\sample.txt"

ファイルかフォルダかを明確にしたい場合は、PowerShell 7では -PathType を使えます。

Test-Path ".\sample.txt" -PathType Leaf
Test-Path ".\backup" -PathType Container

コピー先フォルダを作っていない

Copy-Item は、コピー先フォルダがないと失敗します。

Copy-Item -Path ".\sample.txt" -Destination ".\backup\sample.txt"

先に作成します。

New-Item -ItemType Directory -Path ".\backup" -Force | Out-Null

削除処理をいきなり実行している

Remove-Item は強力です。

Remove-Item ".\*.log"

まずは -WhatIf を使います。

Get-ChildItem -File -Filter "*.log" |
    Remove-Item -WhatIf

相対パスで実行場所がズレる

タスクスケジューラで実行すると、相対パスが想定外の場所を指すことがあります。

Copy-Item ".\sample.txt" ".\backup\sample.txt"

.ps1 と同じフォルダを基準にするなら、$PSScriptRoot を使います。

$sourcePath = Join-Path $PSScriptRoot "sample.txt"
$backupDir = Join-Path $PSScriptRoot "backup"

日本語ファイル名や特殊文字でうまく扱えない

通常は -Path で問題ありませんが、[] など特殊文字を含むパスでは -LiteralPath を検討します。

Get-Content -LiteralPath ".\売上[2026].txt" -Encoding UTF8

まとめ

この記事では、VBSのFileSystemObjectをPowerShellに置き換える基本パターンを整理しました。

代表的な対応関係は次の通りです。

VBS FileSystemObject PowerShell
FileExists / FolderExists Test-Path
CreateFolder New-Item -ItemType Directory
CreateTextFile Set-Content
OpenTextFile Get-Content / Set-Content / Add-Content
CopyFile / CopyFolder Copy-Item
MoveFile / MoveFolder Move-Item
DeleteFile / DeleteFolder Remove-Item
GetFile / GetFolder Get-Item
Files / SubFolders Get-ChildItem
BuildPath Join-Path
GetExtensionName Extension
GetBaseName BaseName
GetParentFolderName DirectoryName

VBSからPowerShellへ移行するときは、FileSystemObjectのメソッドを1対1で置き換えるだけではなく、PowerShellの考え方に合わせることが重要です。

特に大事なのは、次の5つです。

パスはJoin-Pathで作る
スクリプト基準の場所は$PSScriptRootを使う
一覧取得はGet-ChildItemを使う
削除前は-WhatIfで確認する
処理結果はログに残す

PowerShellでは、ファイルやフォルダをオブジェクトとして扱えるため、VBSよりも条件抽出、並べ替え、CSV出力、ログ管理が書きやすくなります。

FileSystemObjectからPowerShellへ移行する目的は、単に古い文法を新しい文法に変えることではありません。
社内にある小さな自動化を、より安全に、より運用しやすい形に作り直すことです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?