今回で「PowerShellでデータ管理ツールを作る」というシリーズは最終回となります。長い間、ご一緒いただきありがとうございます。
これまでの記事では、データの追加、削除、保存、検索、そしてソートなど、多様なデータ管理機能をPowerShellで実装してきました。特に、エンジニアになるにはどうしたらよいか、PowerShellプログラミングの入門として、基本的な機能から応用まで幅広くカバーしてきました。
今回は、これらの機能に加えて非常に重要な「データのバックアップ機能」を追加します。データは企業活動や個人の日常においても非常に価値のあるものです。その価値あるデータを失わないように、また、何らかのトラブルからすぐに復旧できるようにするためには、バックアップが不可欠です。
この記事を通じて、PowerShellを用いたデータのバックアップ機能の追加方法を学び、より堅牢なデータ管理ツールを作成していきましょう。
上司からの新たな依頼: データのバックアップ
ツールありがとうね。最初に言っていたバックアップ機能もつくってほしいな。
わかりました!
この一言には、データ管理ツールが日常業務での重要な位置を占め始めたこと、そしてそのデータがどれだけ価値を持っているかという認識が込められています。基本的なデータの追加や削除、検索機能などはすでに実装していますが、それだけでは不十分です。何らかの理由でデータが失われた場合、それを復元する手段が必要です。
上司のこの依頼は、データ管理ツールをさらに堅牢で信頼性の高いものにするための重要なステップです。この依頼を受け、今回はデータのバックアップ機能の追加に取り組みます。
バックアップ機能の設計
データのバックアップは、データ管理ツールの信頼性と堅牢性を高めるために非常に重要な機能です。このセクションでは、バックアップ機能の要件と設計について詳しく説明します。
要件
- バックアップファイルは「bk」という名前の新しいフォルダに保存される。このフォルダは手動で作成する。
- データを保存する際に、自動的にバックアップが行われる。
- バックアップファイルはCSV形式で保存される。
- バックアップファイルの名称は「data_yyyymmdd.csv」とする。
- データを保存する際に、保存日付から5日以上経過したバックアップファイルは自動的に削除される(容量の関係)。
設計
- 「bk」フォルダの作成(手動):
ユーザーが手動で「bk」という名前の新しいフォルダを作成します。このフォルダは、バックアップファイルの保存場所となります。 - データ保存時のバックアップ:
ユーザーがデータを保存するたびに、バックアップファイルが自動的に作成されます。 - CSVファイルのコピーと格納:
バックアップが行われる際には、現在のデータが保存されているCSVファイルをコピーし、「bk」フォルダに格納します。 - バックアップファイルの命名規則:
作成されるバックアップファイルの名称は「data_yyyymmdd.csv」とします。これにより、いつのバックアップか一目でわかるようになります。 - 古いバックアップファイルの自動削除:
データを保存するときに、保存日付から5日以上経過したバックアップファイルは自動的に削除されます。これはディスク容量を節約するための措置です。
以上がバックアップ機能の基本的な設計です。この設計に基づき、次のセクションで具体的な実装に取り組みます。
バックアップ機能の実装
このセクションでは、前述した設計に基づいて、バックアップ機能の具体的な実装手順を解説します。コードの各部分にコメントも付けて、初心者の方でも理解しやすいように工夫しています。
「bk」フォルダの作成(手動)
まずは、「bk」という名前の新しいフォルダを手動で作成してください。このフォルダは、バックアップファイルの保存場所となります。
バックアップファイルの自動作成
データを保存する関数SaveData
内で、バックアップファイルを自動的に作成します。
# データ書き込み関数
function SaveData {
$global:data | Export-Csv -Path $dataFile -NoTypeInformation -Encoding Default
Write-Host "データがCSVファイルに保存されました。"
# バックアップの作成
$backupFileName = "data_" + (Get-Date -Format "yyyyMMdd") + ".csv"
$backupPath = "$commonPath\bk$backupFileName"
Copy-Item $dataFile -Destination $backupPath
Write-Host "バックアップが作成されました。"
}
$backupFileName
: 今日の日付をyyyyMMdd
形式で取得し、バックアップファイル名を生成します。$backupPath
: バックアップファイルの保存先パスを指定します。Copy-Item
: 現在のデータファイルをコピーして、バックアップフォルダに保存します。
バックアップファイルの命名規則
上記のコードにおいて、バックアップファイルの名称は「data_yyyymmdd.csv」となるように設定しています。yyyymmddはシステム日付(ツールを実行するPC上の日付)です。
古いバックアップファイルの自動削除
データを保存する際に、保存日付から5日以上経過したバックアップファイルを自動で削除します。
# 古いバックアップファイルの削除
$limitDate = (Get-Date).AddDays(-5).ToString("yyyyMMdd")
Get-ChildItem "$commonPath\bk\" -Filter "data_*.csv" | ForEach-Object {
$fileDate = $_.Name.Substring(5, 8)
if ([int]$fileDate -le [int]$limitDate) {
Remove-Item $_.FullName
Write-Host "$($_.Name) が削除されました。"
}
}
$limitDate
: 今日から5日前の日付をyyyyMMdd
形式で取得します。Get-ChildItem
: バックアップフォルダ内のCSVファイルを取得します。$fileDate
: ファイル名から日付部分を抽出します。Remove-Item
: 条件に合致する古いバックアップファイルを削除します。
このコードをSaveData
関数の最後に追加してください。
ソースコード(完成版)
Try {
# 共通のパスの設定
$commonPath = "$PSScriptRoot\.."
# CSVファイル設定
$dataFile = "$commonPath\data\data.csv"
# 主キー用の定義ファイル設定
$keyFile = "$commonPath\data\last_key.txt"
# データの配列を宣言
$global:data = @()
# 主キーの初期値設定
if (Test-Path $keyFile) {
$newPrimaryKey = [int](Get-Content $keyFile)
} else {
$newPrimaryKey = 1
}
# ファイル存在チェック
if (Test-Path $dataFile) {
# ファイル読み込み(Shift-JIS)
$tempData = Import-Csv -Path $dataFile -Encoding Default
# $tempData が配列でない場合、配列に変換
$global:data = @($tempData)
Write-Host "データがCSVファイルから読み込まれました。"
}
# データ書き込み関数
function SaveData {
$global:data | Export-Csv -Path $dataFile -NoTypeInformation -Encoding Default
Write-Host "データがCSVファイルに保存されました。"
}
# データ書き込み関数
function SaveData {
$global:data | Export-Csv -Path $dataFile -NoTypeInformation -Encoding Default
Write-Host "データがCSVファイルに保存されました。"
# バックアップの作成
$backupFileName = "data_" + (Get-Date -Format "yyyyMMdd") + ".csv"
$backupPath = "$commonPath\bk$backupFileName"
Copy-Item $dataFile -Destination $backupPath
Write-Host "バックアップが作成されました。"
# 古いバックアップファイルの削除
$limitDate = (Get-Date).AddDays(-5).ToString("yyyyMMdd")
Get-ChildItem "$commonPath\bk\" -Filter "data_*.csv" | ForEach-Object {
$fileDate = $_.Name.Substring(5, 8)
if ([int]$fileDate -le [int]$limitDate) {
Remove-Item $_.FullName
Write-Host "$($_.Name) が削除されました。"
}
}
}
# データ追加関数
function AddData {
# 主キーの更新
$newPrimaryKey++
$date = Read-Host "日付を入力してください(YYYYMMDD形式)"
$content1 = Read-Host "内容1を入力してください"
$content2 = Read-Host "内容2を入力してください"
$content3 = Read-Host "内容3を入力してください"
$newData = [PSCustomObject]@{
'主キー' = $newPrimaryKey
'日付' = $date
'内容1' = $content1
'内容2' = $content2
'内容3' = $content3
}
$global:data += $newData
Write-Host "新しいデータが追加されました。"
# 主キー用の定義ファイルを更新
$newPrimaryKey | Out-File $keyFile
}
# データ削除関数
function RemoveData {
$keyToRemove = Read-Host "削除するデータの主キーを入力してください"
$global:data = $global:data | Where-Object { $_.'主キー' -ne $keyToRemove }
Write-Host "$keyToRemove のデータが削除されました。"
}
# 複数条件でのデータ検索関数
function MultiSearchData {
$searchDateRange = Read-Host "検索する日付範囲を入力してください(YYYYMMDD-YYYYMMDD、空白で全範囲)"
$startDate, $endDate = $searchDateRange -split '-'
$searchKeyword = Read-Host "検索するキーワードを入力してください"
$searchResult = @($global:data | Where-Object {
($_.日付 -ge $startDate -or -not $startDate) -and
($_.日付 -le $endDate -or -not $endDate) -and
($_.内容1 -like "*$searchKeyword*" -or $_.内容2 -like "*$searchKeyword*" -or $_.内容3 -like "*$searchKeyword*")
})
if ($searchResult.Count -eq 0) {
Write-Host "該当するデータはありません。"
} else {
Write-Host "検索結果:"
$searchResult
}
}
#ソート関数
function SortData {
$sortColumn = Read-Host "ソートする列を選択してください(主キー、日付、内容1、内容2、内容3)"
$sortOrder = Read-Host "ソート順を選択してください(asc: 昇順, desc: 降順)"
if ($sortOrder -eq 'asc') {
$global:data = $global:data | Sort-Object $sortColumn
} elseif ($sortOrder -eq 'desc') {
$global:data = $global:data | Sort-Object $sortColumn -Descending
} else {
Write-Host "無効なソート順です。ソートは実行されません。"
return
}
Write-Host "$sortColumn 列を $sortOrder でソートしました。"
}
# メニュー表示
do {
$choice = Read-Host "操作を選択してください (1: データ追加, 2: データ削除, 3: データ保存, 4: データ検索, 5: データソート, 6: 終了)"
switch ($choice) {
'1' { AddData }
'2' { RemoveData }
'3' { SaveData }
'4' { MultiSearchData }
'5' { SortData }
'6' { Write-Host "プログラムを終了します。"; break }
default { Write-Host "無効な選択です。再度選択してください。" }
}
} while ($choice -ne '6')
} Catch {
# エラーメッセージ出力
Write-Host "予期せぬエラーが発生しました: $($_.Exception.Message)"
}
バックアップ機能のテスト
このセクションでは、実装したバックアップ機能が正しく動作するかどうかを確認するためのテスト方法とその結果を示します。例では2023/09/08に実行しています。
バックアップファイルの自動作成テスト
- データを追加または削除して、
SaveData
関数を実行します。 - 「bk」フォルダ内に今日の日付に基づいたバックアップファイル(例:
data_20230908.csv
)が作成されていることを確認します。
結果: バックアップファイルが正しく作成されました。
バックアップファイルの命名規則テスト
- 複数日にわたってデータを保存します。
- 「bk」フォルダ内のバックアップファイルが、それぞれ異なる日付で命名されていることを確認します。
結果: バックアップファイルの命名規則が正しく適用されました。
古いバックアップファイルの自動削除テスト
- 5日以上前のバックアップファイルを「bk」フォルダに保存します。
- データを追加または削除して、
SaveData
関数を実行します。 - 5日以上前のバックアップファイルが自動的に削除されていることを確認します。
結果: 古いバックアップファイルが正しく削除されました。
できました!
ありがとう!お疲れ様。
まとめと次のステップ
このシリーズを通じて、PowerShellを用いたデータ管理ツールの設計から実装、そしてテストまでの一連の流れを学ぶことができました。
学べたこと
- データのCRUD操作: データの追加、読み込み、更新、削除(CRUD)の基本的な操作方法
- エラーハンドリング: 予期せぬエラーに対処するためのエラーハンドリングの基礎
- データの検索とソート: 効率的なデータ管理のための検索とソート機能
- バックアップ機能: データの安全性を確保するためのバックアップ機能
プログラミングスキルをさらに高めたい、またはエンジニアとしてのキャリアを考えている方は、専門的なプログラミングスクールに参加することをお勧めします。
また、転職サイトを活用して、より高度なエンジニアリングの仕事を探すことも一つの方法です。
以下のおすすめ記事では、おすすめのサービスを紹介しています。参考にしていただければ幸いです。
🔍 おすすめ記事
🔹 次のステップへ進む
🔗 「プログラミング学習の進め方 – オンラインリソースとプログラミングスクール」を読む
🔗 「プログラミングでキャリアチェンジを考える – 転職サイトとその活用方法」を読む
🔹 全体のまとめとガイド
サイト全体の内容や、他の関連記事をチェックして、学びをさらに深めましょう。
🔗 「PowerShellを使ったプログラム作成とキャリア開発ガイド」を見る
コメント