<#
.SYNOPSIS
Windows サーバ現状調査 一括出力スクリプト
.DESCRIPTION
一般的なサーバで必要となる情報(ハードウェア/OS/ネットワーク/アプリ/セキュリティ/運用)を収集し、
CSV / JSON / TXT / MD でまとめて出力します。
.NOTES
- 管理者権限での実行を推奨
- 出力先: .\ServerInventory_<HOSTNAME>_<yyyymmddHHmmss>\
- Windows Server 2012 R2 以降を想定。利用不可のコマンドは try/catch で可能な範囲を取得。
#>
# ------------- 初期設定 -------------
$ErrorActionPreference = 'SilentlyContinue'
$HostName = $env:COMPUTERNAME
$Timestamp = (Get-Date).ToString('yyyyMMddHHmmss')
$OutDir = Join-Path -Path (Get-Location) -ChildPath "ServerInventory_${HostName}_$Timestamp"
New-Item -Path $OutDir -ItemType Directory -Force | Out-Null
# UTF-8 出力のデフォルト指定(PowerShell 5.x 互換)
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
$PSDefaultParameterValues['Export-Csv:Encoding'] = 'utf8'
$PSDefaultParameterValues['Set-Content:Encoding'] = 'utf8'
$PSDefaultParameterValues['Add-Content:Encoding'] = 'utf8'
# 管理者権限チェック
function Test-IsAdmin {
$currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentIdentity)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
$IsAdmin = Test-IsAdmin
if (-not $IsAdmin) {
Write-Warning "管理者権限での実行を推奨します。一部の情報(Firewall/GPO/証明書等)が取得できない場合があります。"
}
# 安全な CSV/JSON 出力ヘルパ
function Save-Csv($Object, $Path) {
try { $Object | Export-Csv -Path $Path -NoTypeInformation -Force } catch { $_ | Out-String | Out-File -FilePath ($Path + '.error.txt') }
}
function Save-Json($Object, $Path) {
try { $Object | ConvertTo-Json -Depth 6 | Out-File -FilePath $Path -Force } catch { $_ | Out-String | Out-File -FilePath ($Path + '.error.txt') }
}
# ------------- 1) ハードウェア/仮想化/ディスク -------------
Write-Host "[1/12] ハードウェア情報収集..."
$hw = [ordered]@{}
try {
$cs = Get-CimInstance Win32_ComputerSystem
$os = Get-CimInstance Win32_OperatingSystem
$bios = Get-CimInstance Win32_BIOS
$cpu = Get-CimInstance Win32_Processor
$memGb = [math]::Round(($cs.TotalPhysicalMemory/1GB),2)
$hw.Model = $cs.Model
$hw.Manufacturer = $cs.Manufacturer
$hw.BIOSVersion = ($bios.SMBIOSBIOSVersion)
$hw.SerialNumber = $bios.SerialNumber
$hw.CPU_Name = ($cpu.Name -join '; ')
$hw.CPU_Cores = ($cpu.NumberOfCores | Measure-Object -Sum).Sum
$hw.CPU_Logical = ($cpu.NumberOfLogicalProcessors | Measure-Object -Sum).Sum
$hw.MemoryGB = $memGb
$hw.IsVirtual = ($cs.Model -match 'Virtual|VMware|KVM|Xen|Hyper-V')
$hw.HypervisorPresent = $cs.HypervisorPresent
$hw.LastBoot = [datetime]::Parse($os.LastBootUpTime).ToString("yyyy-MM-dd HH:mm:ss")
} catch {}
# ディスク/ボリューム
$disks = @(); $volumes = @(); $phys = @()
try { $disks = Get-Disk | Select-Object Number, FriendlyName, SerialNumber, BusType, PartitionStyle, OperationalStatus, Size } catch {}
try { $volumes = Get-Volume | Select-Object DriveLetter, FileSystem, FileSystemLabel, HealthStatus, Size, SizeRemaining, Path } catch {}
try { $phys = Get-PhysicalDisk | Select-Object FriendlyName, MediaType, Size, CanPool, OperationalStatus, HealthStatus, Manufacturer, Model, SerialNumber, BusType, SpindleSpeed, Usage, ResiliencySettingName } catch {}
Save-Json $hw (Join-Path $OutDir '01_hardware_os.json')
Save-Csv $disks (Join-Path $OutDir '01_disks.csv')
Save-Csv $volumes (Join-Path $OutDir '01_volumes.csv')
if ($phys) { Save-Csv $phys (Join-Path $OutDir '01_physical_disks.csv') }
# NIC チーミング
try {
$teams = Get-NetLbfoTeam
if ($teams) {
Save-Csv $teams (Join-Path $OutDir '01_nic_teams.csv')
$members = Get-NetLbfoTeamMember
if ($members) { Save-Csv $members (Join-Path $OutDir '01_nic_team_members.csv') }
}
} catch {}
# ------------- 2) OS / 役割 / パッチ / ライセンス -------------
Write-Host "[2/12] OS/役割/パッチ情報収集..."
$osInfo = [ordered]@{}
try {
$comp = Get-ComputerInfo
$osInfo.OSName = $comp.OsName
$osInfo.OSVersion = $comp.OsVersion
$osInfo.OSBuild = $comp.OsBuildNumber
$osInfo.Edition = $comp.WindowsProductName
$osInfo.InstallDate = (Get-CimInstance Win32_OperatingSystem).InstallDate
} catch {
$os = Get-CimInstance Win32_OperatingSystem
$osInfo.OSName = $os.Caption
$osInfo.OSVersion = $os.Version
$osInfo.OSBuild = $os.BuildNumber
$osInfo.InstallDate = $os.InstallDate
}
# 役割/機能
try {
$features = Get-WindowsFeature
Save-Csv ($features | Where-Object {$_.Installed -eq $true}) (Join-Path $OutDir '02_server_roles_features_installed.csv')
} catch {}
# パッチ
try {
$hotfix = Get-HotFix | Select-Object HotFixID, Description, InstalledOn, InstalledBy
Save-Csv $hotfix (Join-Path $OutDir '02_hotfixes.csv')
} catch {}
# ライセンス(WMI)
try {
$lic = Get-CimInstance -ClassName SoftwareLicensingProduct -Filter "Name like 'Windows%Server%'" | Where-Object { $_.PartialProductKey }
Save-Csv ($lic | Select-Object Name, ApplicationID, PartialProductKey, LicenseStatus, Description) (Join-Path $OutDir '02_license_windows.csv')
} catch {}
Save-Json $osInfo (Join-Path $OutDir '02_os_basic.json')
# ------------- 3) ドメイン / GPO -------------
Write-Host "[3/12] ドメイン/GPO 情報収集..."
$domainInfo = [ordered]@{ PartOfDomain = $false }
try {
$cs = Get-CimInstance Win32_ComputerSystem
$domainInfo.PartOfDomain = [bool]$cs.PartOfDomain
$domainInfo.Domain = $cs.Domain
if ($domainInfo.PartOfDomain) {
try {
$d = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$domainInfo.DomainFunctionalLevel = $d.DomainMode.ToString()
$domainInfo.Forest = $d.Forest.Name
$domainInfo.ForestFunctionalLevel = $d.Forest.ForestMode.ToString()
} catch {}
}
} catch {}
Save-Json $domainInfo (Join-Path $OutDir '03_domain.json')
# GPO 適用状況(gpresult 出力)
try {
$gpTxt = Join-Path $OutDir '03_gpresult_computer.txt'
gpresult /SCOPE COMPUTER /R | Out-File -FilePath $gpTxt
if ($IsAdmin) {
$gpXml = Join-Path $OutDir '03_gpresult_computer.xml'