PowerShellでファイル操作を行う際、こんなニーズに直面することがよくあります:
「既存のログファイルに新しい記録を追加したい」
「設定ファイルに項目を追記したい」
「複数のファイルの内容を統合したい」
このような場面で活躍するのがAdd-Contentコマンドレットです。
この記事では、PowerShell初心者から中級者まで役立つ、Add-Contentの基本から応用までを実例とともに詳しく解説します。
Add-Contentとは?

基本概念
Add-Content
は、PowerShellで既存のファイルにテキストやデータを追記するためのコマンドレットです。
ファイルの末尾に新しい内容を追加し、元の内容はそのまま保持されます。
基本構文
Add-Content
[-Path] <string[]>
[-Value] <Object[]>
[-PassThru]
[-Filter <string>]
[-Include <string[]>]
[-Exclude <string[]>]
[-Force]
[-Credential <pscredential>]
[-WhatIf]
[-Confirm]
[-NoNewline]
[-Encoding <Encoding>]
[-AsByteStream]
[-Stream <string>]
[<CommonParameters>]
最もシンプルな使用例:
Add-Content -Path "C:\log\app.log" -Value "処理が完了しました"
主要なパラメーター
パラメーター | 説明 | 必須 |
---|---|---|
-Path | 追記先のファイルパス | ✓ |
-Value | 追記する内容 | ✓ |
-Encoding | 文字エンコーディング | |
-Force | 読み取り専用ファイルにも追記 | |
-NoNewline | 末尾の改行を追加しない | |
-WhatIf | 実行せずに結果を予測表示 |
基本的な使い方

単一行の追記
# 基本的な文字列の追記
Add-Content -Path "C:\temp\sample.txt" -Value "Hello World"
# 変数を使った追記
$message = "PowerShellで追記しました"
Add-Content -Path "C:\temp\sample.txt" -Value $message
# 現在の日時を追記
Add-Content -Path "C:\temp\sample.txt" -Value (Get-Date)
複数行の追記
# 配列を使った複数行追記
$lines = @(
"第1行目",
"第2行目",
"第3行目"
)
Add-Content -Path "C:\temp\sample.txt" -Value $lines
# ヒアストリングを使った複数行追記
$multilineText = @"
これは複数行の
テキストです。
まとめて追記できます。
"@
Add-Content -Path "C:\temp\sample.txt" -Value $multilineText
パイプラインとの組み合わせ
# パイプラインから値を受け取って追記
"行1", "行2", "行3" | Add-Content -Path "C:\temp\sample.txt"
# Get-Contentと組み合わせてファイル統合
Get-Content "source1.txt" | Add-Content -Path "combined.txt"
Get-Content "source2.txt" | Add-Content -Path "combined.txt"
実践的な使用例

ログファイルの管理
日時付きログの追記:
function Write-Log {
param(
[string]$Message,
[string]$LogPath = "C:\logs\application.log",
[string]$Level = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "[$timestamp] [$Level] $Message"
Add-Content -Path $LogPath -Value $logEntry
}
# 使用例
Write-Log -Message "アプリケーションが開始されました"
Write-Log -Message "エラーが発生しました" -Level "ERROR"
ローテーション機能付きログ:
function Write-RotatingLog {
param(
[string]$Message,
[string]$LogPath = "C:\logs\app.log",
[int]$MaxSizeMB = 10
)
# ファイルサイズをチェック
if (Test-Path $LogPath) {
$fileSize = (Get-Item $LogPath).Length / 1MB
if ($fileSize -gt $MaxSizeMB) {
$backupPath = $LogPath.Replace(".log", "_$(Get-Date -Format 'yyyyMMdd_HHmmss').log")
Move-Item $LogPath $backupPath
}
}
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $LogPath -Value "[$timestamp] $Message"
}
CSVファイルの操作
# CSVヘッダーの作成
$csvHeader = "名前,年齢,部署"
Add-Content -Path "C:\data\employees.csv" -Value $csvHeader
# データの追記
$newEmployee = "田中太郎,30,営業部"
Add-Content -Path "C:\data\employees.csv" -Value $newEmployee
# オブジェクトからCSV形式で追記
$employee = [PSCustomObject]@{
Name = "佐藤花子"
Age = 28
Department = "技術部"
}
$csvLine = "$($employee.Name),$($employee.Age),$($employee.Department)"
Add-Content -Path "C:\data\employees.csv" -Value $csvLine
設定ファイルの管理
# INI形式の設定ファイルに追記
function Add-ConfigEntry {
param(
[string]$ConfigPath,
[string]$Section,
[string]$Key,
[string]$Value
)
$configEntry = if ($Section) {
"[$Section]`n$Key=$Value"
} else {
"$Key=$Value"
}
Add-Content -Path $ConfigPath -Value $configEntry
}
# 使用例
Add-ConfigEntry -ConfigPath "C:\config\app.ini" -Section "Database" -Key "Server" -Value "localhost"
レポート生成
# システム情報レポートの作成
$reportPath = "C:\reports\system_report_$(Get-Date -Format 'yyyyMMdd').txt"
# レポートヘッダー
Add-Content -Path $reportPath -Value "=== システムレポート ==="
Add-Content -Path $reportPath -Value "生成日時: $(Get-Date)"
Add-Content -Path $reportPath -Value ""
# システム情報の追記
Add-Content -Path $reportPath -Value "=== コンピューター情報 ==="
Get-ComputerInfo | Select-Object WindowsProductName, TotalPhysicalMemory |
ForEach-Object { Add-Content -Path $reportPath -Value $_.ToString() }
# プロセス情報の追記
Add-Content -Path $reportPath -Value "`n=== 上位プロセス(CPU使用率順) ==="
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU |
ForEach-Object { Add-Content -Path $reportPath -Value "$($_.Name): $($_.CPU)" }
エンコーディングの管理

PowerShell 5.1での文字化け対策
# UTF-8エンコーディングで追記(PowerShell 5.1)
$utf8 = New-Object System.Text.UTF8Encoding $false
Add-Content -Path "file.txt" -Value "日本語テキスト" -Encoding UTF8
# Shift-JISエンコーディングで追記
Add-Content -Path "file.txt" -Value "日本語テキスト" -Encoding Default
PowerShell 7以降の改善されたエンコーディング
# PowerShell 7では自動的にUTF-8が使用される
Add-Content -Path "file.txt" -Value "日本語テキスト"
# 明示的なエンコーディング指定
Add-Content -Path "file.txt" -Value "日本語テキスト" -Encoding utf8BOM
Add-Content -Path "file.txt" -Value "日本語テキスト" -Encoding utf8NoBOM
エラー処理とTips
ファイル存在チェック
# ファイルが存在しない場合の処理
$filePath = "C:\logs\app.log"
if (-not (Test-Path $filePath)) {
# ディレクトリも含めて確実に作成
$directory = Split-Path $filePath -Parent
if (-not (Test-Path $directory)) {
New-Item -Path $directory -ItemType Directory -Force
}
# 空のファイルを作成
New-Item -Path $filePath -ItemType File -Force
}
Add-Content -Path $filePath -Value "ログエントリ"
Try-Catchを使用したエラーハンドリング
function Safe-AddContent {
param(
[string]$Path,
[string]$Value
)
try {
Add-Content -Path $Path -Value $Value -ErrorAction Stop
Write-Host "正常に追記されました: $Path" -ForegroundColor Green
}
catch [System.UnauthorizedAccessException] {
Write-Error "アクセス権限がありません: $Path"
}
catch [System.IO.DirectoryNotFoundException] {
Write-Error "ディレクトリが見つかりません: $Path"
}
catch {
Write-Error "予期しないエラーが発生しました: $($_.Exception.Message)"
}
}
# 使用例
Safe-AddContent -Path "C:\protected\file.txt" -Value "テストデータ"
大量データの効率的な処理
# 大量のデータを効率的に処理
function Add-BulkContent {
param(
[string]$Path,
[string[]]$Data,
[int]$BatchSize = 1000
)
for ($i = 0; $i -lt $Data.Count; $i += $BatchSize) {
$batch = $Data[$i..([Math]::Min($i + $BatchSize - 1, $Data.Count - 1))]
Add-Content -Path $Path -Value $batch
Write-Progress -Activity "データ書き込み中" -PercentComplete (($i / $Data.Count) * 100)
}
Write-Progress -Activity "データ書き込み中" -Completed
}
関連コマンドレットとの使い分け

Add-Content vs Set-Content
コマンドレット | 動作 | 使用場面 |
---|---|---|
Add-Content | ファイルに追記 | ログ記録、データ蓄積 |
Set-Content | ファイルを上書き | 設定ファイルの更新、新規作成 |
# Add-Content: 既存内容を保持して追記
Add-Content -Path "log.txt" -Value "新しいログ"
# Set-Content: 既存内容を削除して新規作成
Set-Content -Path "config.txt" -Value "新しい設定"
Add-Content vs Out-File
# Add-Content: シンプルな追記
Add-Content -Path "file.txt" -Value "追記内容"
# Out-File: オブジェクトの書式化出力(追記モード)
Get-Process | Out-File -FilePath "processes.txt" -Append
# Out-File: 幅を指定して出力
Get-Service | Out-File -FilePath "services.txt" -Append -Width 200
Export-Csvとの使い分け
# CSV形式でオブジェクトを追記する場合
$data = @(
[PSCustomObject]@{Name="田中"; Age=30},
[PSCustomObject]@{Name="佐藤"; Age=25}
)
# Export-Csv(ヘッダー付き、既存ファイルに追記)
$data | Export-Csv -Path "data.csv" -Append -NoTypeInformation -Encoding UTF8
# Add-Content(手動でCSV形式を作成)
$data | ForEach-Object {
Add-Content -Path "data.csv" -Value "$($_.Name),$($_.Age)"
}
高度な使用例

条件付き追記
# 特定の条件でのみ追記
$errorLevel = "WARNING"
$logPath = "C:\logs\app.log"
# エラーレベルによって異なる処理
switch ($errorLevel) {
"INFO" {
Add-Content -Path $logPath -Value "[INFO] $(Get-Date): 情報メッセージ"
}
"WARNING" {
Add-Content -Path $logPath -Value "[WARNING] $(Get-Date): 警告メッセージ"
# 警告の場合は別ファイルにも記録
Add-Content -Path "C:\logs\warnings.log" -Value "[WARNING] $(Get-Date): 警告メッセージ"
}
"ERROR" {
Add-Content -Path $logPath -Value "[ERROR] $(Get-Date): エラーメッセージ"
# エラーの場合はイベントログにも記録
Write-EventLog -LogName Application -Source "MyApp" -EventId 1001 -Message "エラーが発生しました"
}
}
テンプレート機能
function Add-TemplatedContent {
param(
[string]$TemplatePath,
[string]$OutputPath,
[hashtable]$Replacements
)
$template = Get-Content -Path $TemplatePath -Raw
foreach ($key in $Replacements.Keys) {
$template = $template -replace "\{\{$key\}\}", $Replacements[$key]
}
Add-Content -Path $OutputPath -Value $template
}
# テンプレートファイル(template.txt)の内容例:
# こんにちは、{{Name}}さん
# 今日は{{Date}}です。
# {{Message}}
# 使用例
$replacements = @{
"Name" = "田中"
"Date" = (Get-Date -Format "yyyy年MM月dd日")
"Message" = "PowerShellの学習をがんばりましょう!"
}
Add-TemplatedContent -TemplatePath "template.txt" -OutputPath "output.txt" -Replacements $replacements
並行処理での安全な追記
# ファイルロックを考慮した安全な追記
function Add-ContentSafe {
param(
[string]$Path,
[string]$Value,
[int]$RetryCount = 3,
[int]$RetryDelayMs = 100
)
for ($i = 0; $i -lt $RetryCount; $i++) {
try {
Add-Content -Path $Path -Value $Value -ErrorAction Stop
return $true
}
catch [System.IO.IOException] {
if ($i -eq ($RetryCount - 1)) {
throw "ファイルへの書き込みに失敗しました: $Path"
}
Start-Sleep -Milliseconds $RetryDelayMs
}
}
return $false
}
パフォーマンスの最適化

バッチ処理による高速化
# 非効率な方法(1行ずつ追記)
$data = 1..10000
Measure-Command {
foreach ($item in $data) {
Add-Content -Path "slow.txt" -Value "Item: $item"
}
}
# 効率的な方法(まとめて追記)
Measure-Command {
$lines = foreach ($item in $data) { "Item: $item" }
Add-Content -Path "fast.txt" -Value $lines
}
StringBuilder を使用した大量データ処理
# 大量のデータを効率的に処理
function Add-LargeContent {
param(
[string]$Path,
[array]$Data
)
$stringBuilder = New-Object System.Text.StringBuilder
foreach ($item in $Data) {
[void]$stringBuilder.AppendLine($item)
}
Add-Content -Path $Path -Value $stringBuilder.ToString()
}
トラブルシューティング(よくある問題と解決策)

文字化けが発生する
# 問題のあるコード
Add-Content -Path "file.txt" -Value "日本語"
# 解決策
Add-Content -Path "file.txt" -Value "日本語" -Encoding UTF8
ファイルが読み取り専用でエラーになる
# エラーが発生するコード
Add-Content -Path "readonly.txt" -Value "テスト"
# 解決策
Add-Content -Path "readonly.txt" -Value "テスト" -Force
パスが存在しない
# ディレクトリも含めて作成
$filePath = "C:\logs\subfolder\app.log"
$directory = Split-Path $filePath -Parent
if (-not (Test-Path $directory)) {
New-Item -Path $directory -ItemType Directory -Force
}
Add-Content -Path $filePath -Value "ログメッセージ"
改行コードの問題
# Windows形式の改行コード(CRLF)で追記
Add-Content -Path "file.txt" -Value "行1`r`n行2"
# 改行なしで追記
Add-Content -Path "file.txt" -Value "改行なし" -NoNewline
実際の業務での活用例

サーバー監視スクリプト
# サーバーの健全性チェックと結果の記録
$monitoringScript = {
$logPath = "C:\monitoring\server_status.log"
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
# CPU使用率チェック
$cpuUsage = Get-Counter "\Processor(_Total)\% Processor Time" |
Select-Object -ExpandProperty CounterSamples |
Select-Object -ExpandProperty CookedValue
# メモリ使用率チェック
$totalMemory = (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory
$availableMemory = (Get-Counter "\Memory\Available Bytes").CounterSamples.CookedValue
$memoryUsage = [math]::Round((($totalMemory - $availableMemory) / $totalMemory) * 100, 2)
# ディスク使用率チェック
$diskUsage = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" |
Select-Object DeviceID, @{Name="UsedSpace";Expression={[math]::Round((($_.Size - $_.FreeSpace) / $_.Size) * 100, 2)}}
# 結果をログに記録
Add-Content -Path $logPath -Value "[$timestamp] CPU: $([math]::Round($cpuUsage, 2))%, Memory: $memoryUsage%"
foreach ($disk in $diskUsage) {
Add-Content -Path $logPath -Value "[$timestamp] Disk $($disk.DeviceID) Usage: $($disk.UsedSpace)%"
}
}
# スケジュールタスクとして実行
バックアップログの管理
# バックアップ処理とログ記録
function Backup-WithLogging {
param(
[string]$SourcePath,
[string]$DestinationPath,
[string]$LogPath = "C:\logs\backup.log"
)
$startTime = Get-Date
Add-Content -Path $LogPath -Value "[$startTime] バックアップ開始: $SourcePath -> $DestinationPath"
try {
# バックアップ実行(例:Robocopyを使用)
$result = robocopy $SourcePath $DestinationPath /E /R:3 /W:5 /LOG+:$LogPath
$endTime = Get-Date
$duration = $endTime - $startTime
Add-Content -Path $LogPath -Value "[$endTime] バックアップ完了: 所要時間 $($duration.ToString())"
return $true
}
catch {
$errorTime = Get-Date
Add-Content -Path $LogPath -Value "[$errorTime] バックアップエラー: $($_.Exception.Message)"
return $false
}
}
まとめ
PowerShellのAdd-Content
コマンドレットは、ファイルへの追記操作において非常に強力で柔軟なツールです。
基本機能:
- 既存ファイルへの安全な追記
- 複数行や配列の一括追記
- パイプラインとの連携
実践的な活用:
- ログファイルの管理と分析
- レポート生成の自動化
- 設定ファイルの動的更新
- データの統合と集約
重要なポイント:
- エンコーディングの適切な指定
- エラーハンドリングの実装
- パフォーマンスの最適化
- ファイルロックの対処
コメント