ファイルサーバの移行に伴う事前アセスメントについて

  1. アセスメント検証用のファイルサーバ作成

移行に伴うということでスクリプトを動作させる検証OSはWindwos 2019にしています

まず仮想環境にアセスメントツールを検証するためのWindowsサーバを作成してファイルサーバっぽい環境にします。
1.ボリュームGドライブに3個のフォルダと30GBのファイルを作成(環境に合わせてパラメータはいじってください)
いずれもPowerShellです(.ps1)
Treeコマンドだと以下のようなフォルダ構成ができます。
G:.
└─share
├─Folder1
├─Folder2
│ └─Folder1
└─Folder3
└─Folder2
└─Folder1


# 保存先のパス(ユーザー指定)
$basePath = "G:\share"

# 作成する総容量(バイト単位:30GB)
$targetSize = 30GB

# 1ファイルのサイズ(例:100MB)
$fileSize = 100MB

# 総ファイル数(切り上げ)
$fileCount = [math]::Ceiling($targetSize / $fileSize)

# フォルダ階層の深さ
$folderDepth = 3

# フォルダ/ファイル名のプレフィックス
$folderPrefix = "Folder"
$filePrefix = "DummyFile"

# 再帰的にフォルダを作成
function Create-FolderStructure {
param (
[string]$path,
[int]$depth
)
if ($depth -le 0) {
return $path
}

$newFolder = Join-Path $path "$folderPrefix$depth"
if (!(Test-Path $newFolder)) {
New-Item -Path $newFolder -ItemType Directory | Out-Null
}

return Create-FolderStructure -path $newFolder -depth ($depth - 1)
}

# メイン処理
if (!(Test-Path $basePath)) {
New-Item -Path $basePath -ItemType Directory | Out-Null
}

Write-Host "ダミーファイルを作成中…"

for ($i = 1; $i -le $fileCount; $i++) {
# フォルダ構造を動的に変える
$depth = ($i % $folderDepth) + 1
$targetDir = Create-FolderStructure -path $basePath -depth $depth

# ファイルパスを作成
$filePath = Join-Path $targetDir "$filePrefix$i.dat"

# ダミーファイルを作成(管理者権限が必要)
fsutil file createnew $filePath $fileSize

Write-Progress -Activity "作成中…" -Status "$i / $fileCount" -PercentComplete (($i / $fileCount) * 100)
}

Write-Host "完了:$fileCount 個のダミーファイルを作成しました(合計約30GB)"


2.100人分のローカルユーザを作成(ADユーザではありません)

# パラメータ
$prefix = "user"
$start = 1
$end = 100
$password = ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force

for ($i = $start; $i -le $end; $i++) {
# ユーザー名をゼロ埋めで作成(例: user001)
$username = "{0}{1:D3}" -f $prefix, $i

# ユーザーが既に存在するか確認
if (Get-LocalUser -Name $username -ErrorAction SilentlyContinue) {
Write-Host "既に存在: $username"
continue
}

# ユーザー作成
New-LocalUser -Name $username -Password $password -FullName $username -Description "自動作成ユーザー" -PasswordNeverExpires -UserMayNotChangePassword:$false

# ユーザーを "Users" グループに追加
Add-LocalGroupMember -Group "Users" -Member $username

Write-Host "作成完了: $username"
}


3.10個のローカルグループを作成(グローバルグループではありません)

# パラメータ
$prefix = "Group"
$start = 1
$end = 10

for ($i = $start; $i -le $end; $i++) {
# グループ名(ゼロ埋め)
$groupName = "{0}{1:D3}" -f $prefix, $i

# グループが存在するか確認
if (Get-LocalGroup -Name $groupName -ErrorAction SilentlyContinue) {
Write-Host "既に存在: $groupName"
continue
}

# グループ作成
New-LocalGroup -Name $groupName -Description "自動作成グループ $groupName"
Write-Host "作成完了: $groupName"
}

4.2と3を別々に作業してユーザをグループに登録してもよいのですが、面倒なら以下のスクリプトを使用してください。10個のグループを作成して、1グループに10人ずつユーザを作成・登録します。(TestUser001から100まで作成、TestGroup01から10まで作成)

# 変数定義
$groupPrefix = "TestGroup"
$userPrefix = "TestUser"
$password = ConvertTo-SecureString "P@ssw0rd!" -AsPlainText -Force

# 1. グループ作成
for ($i = 1; $i -le 10; $i++) {
$groupName = "{0}{1:D2}" -f $groupPrefix, $i
if (-not (Get-LocalGroup -Name $groupName -ErrorAction SilentlyContinue)) {
New-LocalGroup -Name $groupName
Write-Host "グループ作成: $groupName"
}
}

# 2. ユーザー作成 + グループに追加
for ($i = 1; $i -le 100; $i++) {
$userName = "{0}{1:D3}" -f $userPrefix, $i
if (-not (Get-LocalUser -Name $userName -ErrorAction SilentlyContinue)) {
New-LocalUser -Name $userName -Password $password -FullName $userName -Description "テストユーザー"
Write-Host "ユーザー作成: $userName"
}

# グループ番号(1~10)
$groupIndex = [int][math]::Ceiling($i / 10.0)
$groupName = "{0}{1:D2}" -f $groupPrefix, $groupIndex

# グループにユーザーを追加
try {
Add-LocalGroupMember -Group $groupName -Member $userName
Write-Host " → $groupName に追加"
} catch {
Write-Warning " → $groupName に $userName の追加失敗: $_"
}
}

あとは各フォルダとファイル共有と適当にアクセス権を付与しておきます(アクセス権のアセスメントに必要になります)。
要件としては予定した値をアセスメント用のスクリプトがきちんと返すか調べますので、複雑な構成やランダム要素はないほうがいいです。

2.アセスメントツール

ドライブの基本情報と使用量
$csvPath = "$env:USERPROFILE\Desktop\filesvBasic.csv"

Get-PSDrive -PSProvider FileSystem | Select-Object Name,
@{Name="Size(GB)";Expression={[math]::round(($_.Used + $_.Free)/1GB,2)}},
@{Name="Used(GB)";Expression={[math]::round($_.Used/1GB,2)}},
@{Name="Free(GB)";Expression={[math]::round($_.Free/1GB,2)}} |
Export-Csv -Path $csvPath -Encoding UTF8 -NoTypeInformation

filesvBasic.csvのファイルを作成して出力します

共有フォルダ一覧
# 出力ファイルのパス
$csvPath = "$env:USERPROFILE\Desktop\SmbShareList.csv"

# 共有フォルダ情報を取得し、必要な項目を選択してCSVに出力
Get-SmbShare | Where-Object { $_.Name -notin @("IPC$","ADMIN$","C$") } |
Select-Object Name, Path, Description, FolderEnumerationMode, ConcurrentUserLimit |
Export-Csv -Path $csvPath -Encoding UTF8 -NoTypeInformation

Write-Host "共有フォルダ一覧を出力しました: $csvPath"

SmbShareList.csvのファイルを作成して出力します

フォルダ構成treeコマンドっぽいテキスト出力(Gドライブ対象)
こんな感じの出力を目指しました。
└─ G:\
└─ share
└─ Folder1
└─ Folder2
└─ Folder1
└─ Folder3
└─ Folder2
└─ Folder1
以下はコードです


$root = "G:\"
$outputFile = "$env:USERPROFILE\Desktop\FolderTree.txt"

function Show-Tree {
param (
[string]$path,
[int]$level = 0
)

# インデント生成(4スペース * 階層)
$indent = " " * ($level * 4)

# 現在のフォルダ名
$folderName = Split-Path $path -Leaf
if ($folderName -eq "") { $folderName = $path }

# 出力(tree形式)
$line = "$indent└─ $folderName"
Add-Content -Path $outputFile -Value $line

# サブフォルダを再帰的に出力
try {
$subFolders = Get-ChildItem -Path $path -Directory -ErrorAction Stop
foreach ($folder in $subFolders) {
Show-Tree -path $folder.FullName -level ($level + 1)
}
} catch {
Add-Content -Path $outputFile -Value "$indent [アクセス拒否]"
}
}

# 出力ファイル初期化
if (Test-Path $outputFile) { Remove-Item $outputFile }

# 実行
Show-Tree -path $root

Write-Host "フォルダツリーを出力しました:$outputFile"

FolderTree.txtファイルを作成して出力します

グループとユーザ一覧(サーバに登録されているユーザとグループ一覧)
# 出力用変数
$results = @()

# ローカルグループの一覧を取得
$groups = Get-LocalGroup

foreach ($group in $groups) {
# 各グループに所属するメンバー(ユーザーや他グループ)
try {
$members = Get-LocalGroupMember -Group $group.Name -ErrorAction Stop
foreach ($member in $members) {
# ユーザーかグループかを記録
$results += [PSCustomObject]@{
GroupName = $group.Name
MemberName = $member.Name
ObjectClass = $member.ObjectClass # User / Group / Unknown
PrincipalType = $member.PrincipalSource # Local / ActiveDirectory など
}
}
} catch {
Write-Warning "[$($group.Name)] にアクセスできません:$($_.Exception.Message)"
}
}

# デスクトップにCSV出力
$csvPath = "$env:USERPROFILE\Desktop\LocalUserGroupMapping.csv"
$results | Export-Csv -Path $csvPath -Encoding UTF8 -NoTypeInformation

Write-Host "ユーザーとグループの所属情報をCSVに出力しました:$csvPath"

\LocalUserGroupMapping.csvファイルを作成して出力します

Powershell5.1版

#----------------------------------------
# ローカルグループとメンバー対応表を作成し、
# 現在のユーザのデスクトップへ CSV 出力
#----------------------------------------

# デスクトップパスを取得
$desktop = [Environment]::GetFolderPath("Desktop")
$outputFile = Join-Path $desktop "GroupUserMapping.csv"

$results = @()

# ローカルグループ一覧を取得
$groups = Get-LocalGroup

foreach ($group in $groups) {
try {
$members = Get-LocalGroupMember -Group $group.Name
}
catch {
$members = @()
}

if ($members.Count -gt 0) {
foreach ($member in $members) {
$results += [PSCustomObject]@{
GroupName = $group.Name
MemberName = $member.Name
MemberType = $member.ObjectClass
}
}
}
else {
# メンバーがいないグループも記録
$results += [PSCustomObject]@{
GroupName = $group.Name
MemberName = "<No Members>"
MemberType = "-"
}
}
}

# CSV 出力
$results | Sort-Object GroupName, MemberName | `
Export-Csv -Path $outputFile -NoTypeInformation -Encoding UTF8

Write-Host "CSVをデスクトップに出力しました:"
Write-Host " $outputFile"
フォルダ単位のアクセス権
# 結果格納用
$results = @()

# Gドライブのフォルダ一覧(再帰的に取得)
Get-ChildItem -Path "G:\" -Recurse -Directory -Force -ErrorAction SilentlyContinue | ForEach-Object {
$folderPath = $_.FullName
try {
$acl = Get-Acl -Path $folderPath

# アクセス権の処理(空の場合は "-" を設定)
if ($acl.Access.Count -gt 0) {
$accessList = ($acl.Access | ForEach-Object {
"$($_.IdentityReference): $($_.FileSystemRights) ($($_.AccessControlType))"
}) -join "; "
} else {
$accessList = "-"
}

# 結果格納
$results += [PSCustomObject]@{
FolderPath = $folderPath
Access = $accessList
}
} catch {
Write-Warning "権限エラー: $folderPath - $($_.Exception.Message)"
}
}

# デスクトップにCSVとして出力
$csvPath = "$env:USERPROFILE\Desktop\GDrive_FolderPermissions.csv"
$results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

Write-Host "アクセス権一覧をCSV出力しました:$csvPath"

GDrive_FolderPermissions.csvファイルを作成して出力します

先頭に階層番号をつけて整理したバージョン(0はG:¥直下、1は1階層目等)

# 結果格納用
$results = @()

# ベースパス
$basePath = "G:\"

# フォルダ一覧(再帰的)
Get-ChildItem -Path $basePath -Recurse -Directory -Force -ErrorAction SilentlyContinue | ForEach-Object {
$folderPath = $_.FullName
try {
$acl = Get-Acl -Path $folderPath

# アクセス権が存在する場合のみ整形
$accessList = if ($acl.Access.Count -gt 0) {
($acl.Access | ForEach-Object {
"$($_.IdentityReference): $($_.FileSystemRights) ($($_.AccessControlType))"
}) -join "; "
} else {
"-"
}

# 階層レベルの算出(\ の数 - 基準パスの \ の数)
$level = ($folderPath -replace [regex]::Escape($basePath), "").Split("\").Count - 1

# インデント(見やすくするため)
$indent = (" " * 2 * $level) + (Split-Path $folderPath -Leaf)

# 結果に追加
$results += [PSCustomObject]@{
Level = $level
IndentedName= $indent
FolderPath = $folderPath
Access = $accessList
}
} catch {
Write-Warning "権限エラー: $folderPath - $($_.Exception.Message)"
}
}

# CSVとして出力
$csvPath = "$env:USERPROFILE\Desktop\GDrive_FolderPermissions_Hierarchy.csv"
$results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

Write-Host "階層付きアクセス権一覧をCSVに出力しました:$csvPath"

GDrive_FolderPermissions_Hierarchy.csvファイルを作成して出力します

前記2通りを試しましたが、次のコードがサーバ移行には一番使える気がしました。
単純にフォルダのACLをリストします。前期の2パターンはACL(ファイル共有)にセキュリティリスクが無いかまで調べるつもりがないと冗長的な出力だと思います。

アクセス権情報の取得(共有フォルダのACL)
$targetPath = "G:\share"   # 調査対象のパスに変更
$csvPath = "$env:USERPROFILE\Desktop\FolderAclList.csv" # 出力先CSV

$results = @()

$folders = Get-ChildItem -Path $targetPath -Directory -Recurse -ErrorAction SilentlyContinue
foreach ($folder in $folders) {
$acl = Get-Acl -Path $folder.FullName
foreach ($access in $acl.Access) {
$results += [pscustomobject]@{
FolderPath = $folder.FullName
IdentityReference = $access.IdentityReference
FileSystemRights = $access.FileSystemRights
AccessControlType = $access.AccessControlType
}
}
}

# CSV出力
$results | Export-Csv -Path $csvPath -Encoding UTF8 -NoTypeInformation

Write-Host "出力完了: $csvPath"

FolderAclList.csvファイルを作成して出力します

Powershell5.1版
$targetPath = "G:\share" # 調査対象
$csvPath = "$env:USERPROFILE\Desktop\FolderAclList.csv"

# 数値 FileSystemRightsをアクセス権名に変換(Powershell Ver5.1系)
function Convert-FileSystemRights {
param([System.Security.AccessControl.FileSystemRights]$rights)

# PowerShell 5.1 の Enum 生値
$raw = $rights.value__

# GENERIC_xxx 手動マップ
$genericMap = @{
268435456 = "GENERIC_ALL (FullControl)"
536870912 = "GENERIC_WRITE"
1073741824 = "GENERIC_READ"
2147483648 = "GENERIC_EXECUTE"
}

if ($genericMap.ContainsKey($raw)) {
return $genericMap[$raw]
}

# 通常変換
try {
return ([System.Security.AccessControl.FileSystemRights]$raw).ToString()
}
catch {
return $raw
}
}

# 権限分類(フル / 変更 / 読み取り)
function Classify-Rights {
param([string]$rights)

$r = $rights.ToLower()

if ($r.Contains("fullcontrol") -or $r.Contains("generic_all")) {
return "フル"
}
elseif ($r.Contains("modify") -or ($r.Contains("write") -and $r.Contains("delete"))) {
return "変更"
}
elseif ($r.Contains("read") -or $r.Contains("listdirectory") -or $r.Contains("execute")) {
return "読み取り"
}
else {
return "その他"
}
}

$results = @()

$folders = Get-ChildItem -Path $targetPath -Directory -Recurse -ErrorAction SilentlyContinue
foreach ($folder in $folders) {

$acl = Get-Acl -Path $folder.FullName

foreach ($access in $acl.Access) {

# 権限名(GENERIC_ALL → FullControl など)
$rightsReadable = Convert-FileSystemRights $access.FileSystemRights

# 簡易分類
$rightsCategory = Classify-Rights $rightsReadable

$results += [pscustomobject]@{
FolderPath = $folder.FullName
IdentityReference = $access.IdentityReference
FileSystemRights = $rightsReadable
Category = $rightsCategory
AccessControlType = $access.AccessControlType
}
}
}

# CSV 出力
$results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
Write-Host "出力完了: $csvPath"
ドライブ使用容量(全体から3階層フォルダまで)
# 出力用リスト
$results = @()

# Gドライブ全体のサイズ(MB単位)
$drive = Get-PSDrive -Name G
$totalUsedMB = [math]::Round(($drive.Used / 1MB), 2)

# ドライブ全体情報を追加
$results += [PSCustomObject]@{
FolderPath = "G:\ (全体)"
Level = 0
SizeMB = $totalUsedMB
}

# 基準となるパス
$basePath = "G:\"

# 3階層までのフォルダを対象にサイズを計算
Get-ChildItem -Path $basePath -Recurse -Directory -Force -ErrorAction SilentlyContinue | Where-Object {
($_.FullName -replace [regex]::Escape($basePath), "").Split('\').Count -le 3
} | ForEach-Object {
$folderPath = $_.FullName
try {
# サブフォルダ・ファイルを含めたサイズ計算
$folderSize = Get-ChildItem -Path $folderPath -Recurse -File -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum
$sizeMB = [math]::Round(($folderSize.Sum / 1MB), 2)

# 階層レベル
$level = ($folderPath -replace [regex]::Escape($basePath), "").Split("\").Count

# 結果に追加
$results += [PSCustomObject]@{
FolderPath = $folderPath
Level = $level
SizeMB = $sizeMB
}
} catch {
Write-Warning "サイズ取得エラー: $folderPath - $($_.Exception.Message)"
}
}

# デスクトップにCSV出力
$csvPath = "$env:USERPROFILE\Desktop\GDrive_Usage_3Levels.csv"
$results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

Write-Host "Gドライブの容量情報を出力しました:$csvPath"

GDrive_Usage_3Levels.csvのファイルを作成して出力します
深い階層まで調べても移行においては効果が薄いので3階層までにしています

Gドライブの総ファイル数と総フォルダ数、ファイル容量の平均値と中央値、500KB以下のファイルの数

データのコピーにどのくらい時間がかかるかの参考にするため【200KB以下のファイルでもいいかもそれません。小容量多数のファイルがあるとサーバ間のコピーが遅くなる】

# Gドライブ内のファイルとフォルダを再帰的に取得
$files = Get-ChildItem -Path "G:\" -Recurse -File -Force -ErrorAction SilentlyContinue
$folders = Get-ChildItem -Path "G:\" -Recurse -Directory -Force -ErrorAction SilentlyContinue

# ファイルサイズ(バイト)一覧
$fileSizes = $files | Select-Object -ExpandProperty Length

# 平均サイズ(KB)
$averageKB = if ($fileSizes.Count -gt 0) {
[math]::Round(($fileSizes | Measure-Object -Average).Average / 1KB, 2)
} else { 0 }

# 中央値(KB)
$medianKB = if ($fileSizes.Count -gt 0) {
$sorted = $fileSizes | Sort-Object
$mid = [int]($sorted.Count / 2)
if ($sorted.Count % 2 -eq 0) {
[math]::Round((($sorted[$mid - 1] + $sorted[$mid]) / 2) / 1KB, 2)
} else {
[math]::Round(($sorted[$mid] / 1KB), 2)
}
} else { 0 }

# 500KB以下のファイル数
$under500KB = ($fileSizes | Where-Object { $_ -le 500KB }).Count

# 結果オブジェクト
$result = [PSCustomObject]@{
TotalFiles = $files.Count
TotalFolders = $folders.Count
AverageFileSizeKB = $averageKB
MedianFileSizeKB = $medianKB
FilesUnder500KB = $under500KB
}

# CSV出力
$csvPath = "$env:USERPROFILE\Desktop\GDrive_FileStats.csv"
$result | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

Write-Host "Gドライブの統計をCSV出力しました:$csvPath"

GDrive_FileStats.csvファイルを作成して出力します

ファイルの種別と容量を調査

# 調査対象フォルダ(必要に応じて変更)
$targetPath = "G:\share"

# 出力ファイル(デスクトップに保存)
$csvPath = "$env:USERPROFILE\Desktop\FileTypeSummary.csv"

# ファイル一覧取得
$files = Get-ChildItem -Path $targetPath -Recurse -File -ErrorAction SilentlyContinue

# 拡張子別に分類・集計
$grouped = $files | Group-Object { $_.Extension.ToLower() }

# 結果格納用
$results = @()

foreach ($group in $grouped) {
$ext = if ($group.Name) { $group.Name } else { "[no extension]" }
$count = $group.Count
$totalSizeMB = [math]::Round(($group.Group | Measure-Object -Property Length -Sum).Sum / 1MB, 2)

$results += [pscustomobject]@{
Extension = $ext
FileCount = $count
TotalSizeMB = $totalSizeMB
}
}

# CSV出力
$results | Sort-Object -Property TotalSizeMB -Descending | Export-Csv -Path $csvPath -Encoding UTF8 -NoTypeInformation

Write-Host "ファイル種別ごとの件数と容量を出力しました: $csvPath"

FileTypeSummary.csvのファイルを作成して出力します
拡張子のないファイルは”no extension”にまとめられます

付録:パラメータシートにあるだろう情報一覧の取得
# 出力ファイルパス(タイムスタンプ付き)
$csvPath = "$env:USERPROFILE\Desktop\System_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$data = @()

# ホスト名とドメイン名
$hostname = $env:COMPUTERNAME
$domain = (Get-WmiObject Win32_ComputerSystem).Domain
$data += [PSCustomObject]@{
Category = "System"
Name = "HostName"
Version = $hostname
Detail = ""
}
$data += [PSCustomObject]@{
Category = "System"
Name = "Domain"
Version = $domain
Detail = ""
}

# OS情報
$os = Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, OsArchitecture, CsName
$data += [PSCustomObject]@{
Category = "OS"
Name = $os.WindowsProductName
Version = $os.WindowsVersion
Detail = "$($os.OsArchitecture), $($os.CsName)"
}

# CPU情報
foreach ($cpu in Get-CimInstance Win32_Processor) {
$data += [PSCustomObject]@{
Category = "CPU"
Name = $cpu.Name
Version = "Cores: $($cpu.NumberOfCores)"
Detail = "LogicalProcessors: $($cpu.NumberOfLogicalProcessors)"
}
}

# メモリ情報
foreach ($mem in Get-CimInstance Win32_PhysicalMemory) {
$capacityGB = "{0:N2}" -f ($mem.Capacity / 1GB)
$data += [PSCustomObject]@{
Category = "Memory"
Name = $mem.Manufacturer
Version = "$capacityGB GB"
Detail = "$($mem.Speed) MHz"
}
}

# ディスク情報
foreach ($disk in Get-CimInstance Win32_DiskDrive) {
$sizeGB = "{0:N2}" -f ($disk.Size / 1GB)
$data += [PSCustomObject]@{
Category = "Disk"
Name = $disk.Model
Version = $disk.InterfaceType
Detail = "$sizeGB GB"
}
}

# 論理ドライブ
foreach ($vol in Get-CimInstance Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 }) {
$totalGB = "{0:N2}" -f ($vol.Size / 1GB)
$freeGB = "{0:N2}" -f ($vol.FreeSpace / 1GB)
$data += [PSCustomObject]@{
Category = "Volume"
Name = $vol.DeviceID
Version = $vol.FileSystem
Detail = "Total: $totalGB GB / Free: $freeGB GB"
}
}

# ネットワークアダプター(IPv4のみ)とデフォルトゲートウェイ
foreach ($nic in Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled }) {
$ip = ($nic.IPAddress | Where-Object { $_ -match '^\d{1,3}(\.\d{1,3}){3}$' }) -join ", "
$dns = ($nic.DNSServerSearchOrder | Where-Object { $_ -match '^\d{1,3}(\.\d{1,3}){3}$' }) -join ", "
$gw = ($nic.DefaultIPGateway | Where-Object { $_ -match '^\d{1,3}(\.\d{1,3}){3}$' }) -join ", "
$data += [PSCustomObject]@{
Category = "NIC"
Name = $nic.Description
Version = $nic.MACAddress
Detail = "IP: $ip | GW: $gw | DNS: $dns"
}
}

# スタティックルート情報(IPv4のみ)
$routes = Get-NetRoute | Where-Object { $_.DestinationPrefix -notlike '*:*' -and $_.DestinationPrefix -ne '0.0.0.0/0' -and $_.RouteMetric -ne $null }
foreach ($route in $routes) {
$data += [PSCustomObject]@{
Category = "StaticRoute"
Name = $route.DestinationPrefix
Version = $route.NextHop
Detail = "Interface: $($route.InterfaceAlias) | Metric: $($route.RouteMetric)"
}
}

# デフォルトゲートウェイ(0.0.0.0/0)
$defaultRoutes = Get-NetRoute | Where-Object { $_.DestinationPrefix -eq '0.0.0.0/0' }
foreach ($dr in $defaultRoutes) {
$data += [PSCustomObject]@{
Category = "DefaultGateway"
Name = $dr.InterfaceAlias
Version = $dr.NextHop
Detail = "Metric: $($dr.RouteMetric)"
}
}

# インストール済みソフトウェア
$installedApps = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*,
HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object { $_.DisplayName }

foreach ($app in $installedApps) {
$data += [PSCustomObject]@{
Category = "Software"
Name = $app.DisplayName
Version = $app.DisplayVersion
Detail = $app.Publisher
}
}

# サービス状態
$services = Get-Service | Sort-Object DisplayName
foreach ($svc in $services) {
$data += [PSCustomObject]@{
Category = "Service"
Name = $svc.DisplayName
Version = $svc.Status
Detail = $svc.ServiceType
}
}

# イベントログ設定の取得
$eventLogs = Get-EventLog -List | Sort-Object LogDisplayName
foreach ($elog in $eventLogs) {
$logFilePath = try {
$rawPath = (Get-WinEvent -ListLog $elog.Log).LogFilePath
if ($rawPath) {
[Environment]::ExpandEnvironmentVariables($rawPath)
} else {
"N/A"
}
} catch {
"N/A"
}

$data += [PSCustomObject]@{
Category = "EventLog"
Name = $elog.LogDisplayName
Version = "MaxSize: $([math]::Round($elog.MaximumKilobytes / 1024, 2)) MB"
Detail = "Retention: $($elog.OverflowAction) | Entries: $($elog.Entries.Count) | Path: $logFilePath"
}
}

# Windowsファイアウォールの状態とルールの一覧
$fwProfiles = Get-NetFirewallProfile
foreach ($profile in $fwProfiles) {
$status = if ($profile.Enabled) { "Enabled" } else { "Disabled" }
$data += [PSCustomObject]@{
Category = "Firewall"
Name = "$($profile.Name) Profile"
Version = $status
Detail = "Inbound: $($profile.DefaultInboundAction), Outbound: $($profile.DefaultOutboundAction)"
}

if ($profile.Enabled) {
$rules = Get-NetFirewallRule | Where-Object { $_.Enabled -eq "True" }
foreach ($rule in $rules) {
$data += [PSCustomObject]@{
Category = "FirewallRule"
Name = $rule.DisplayName
Version = $rule.Direction
Detail = "Action: $($rule.Action), Profile: $($rule.Profile)"
}
}
}
}

# CSVに出力
$data | Export-Csv -Path $csvPath -Encoding UTF8 -NoTypeInformation
Write-Host "システム情報をCSV形式で出力しました:`n$csvPath"

System_Report_yyyyMMdd_HHmmss.csvファイルを作成して出力します

以上、ご参考まで

関連記事

TOP