Active DirectoryのOU配下ユーザーをPowerShellでCSVエクスポートする完全ガイド|LastLogonDate・高速化・文字化け対策まで

Active Directory(AD)の特定OU配下にいるユーザーをCSVへエクスポートする最短のPowerShellコマンドから、GUIでの代替、数万ユーザー環境での高速化、文字化け対策、監査でよく求められる属性選定までを一気に整理しました。提示のコマンドは少しの修正で安定運用できます。貼って実行できる完成例と“現場の落とし穴”も併記します。

目次

質問概要

  • 目的:特定のOU(組織単位)配下にいるユーザーを、PowerShellでCSVファイルへ出力したい。
  • 相談内容:提示コマンドの正否、実行手順、GUIでの代替方法、注意点を知りたい。
# (質問者が提示したコマンド)
Get-ADUser -Filter * -SearchBase "OU=MYOU,OU=TopLevelOU,DC=contoso,DC=com" -Properties * |
  Select-Object DisplayName, Description, UserPrincipalName, SamAccountName, LastLogin |
  Export-Csv C:\output.csv -NoTypeInformation

結論(最短の正解コマンド)

次のワンライナーに差し替えれば、そのまま実用に耐えます。LastLoginは存在しないためLastLogonDateへ修正し、-Properties *は必要な属性のみを明示します。

Import-Module ActiveDirectory  # 自動読み込みされる環境も多いが明示しておくと安心
Get-ADUser -Filter * `
  -SearchBase "OU=MYOU,OU=TopLevelOU,DC=contoso,DC=com" `
  -SearchScope Subtree `
  -Properties DisplayName,Description,UserPrincipalName,SamAccountName,LastLogonDate |
  Select-Object DisplayName,Description,UserPrincipalName,SamAccountName,LastLogonDate |
  Export-Csv "C:\output.csv" -NoTypeInformation -Encoding UTF8
  • 修正点1:LastLogin → LastLogonDate(複製される利便プロパティ。後述)
  • 修正点2:-Properties *は取得コストが大きいので、必要属性のみを列挙
  • 実務Tips:Excelでの文字化けを避けるため、まずは-Encoding UTF8で出力。開けない環境では-Encoding Defaultも検討(後述)。

提示コマンドは正しい?差分と理由

項目提示コマンド推奨修正版理由
属性指定-Properties *必要属性のみ列挙不要な属性まで取得するとコスト増(応答遅延・CSV肥大)。サーバー負荷軽減のためも絞る。
ログオン日時LastLoginLastLogonDateLastLoginという属性は存在しません。実務では複製されるLastLogonDateが扱いやすい(精度の注意は後述)。
エンコーディング未指定-Encoding UTF8Excelでの文字化け抑止。環境により-Encoding Default(日本語OSではCP932)も選択肢。
SearchScope未指定-SearchScope Subtree既定値だが、配下の階層も含めて取得する意図を明示でき、可読性が上がる。

パッと使える3パターン

用途コマンド例ポイント
最小限の出力Get-ADUser -Filter * -SearchBase "OU=MYOU,OU=TopLevelOU,DC=contoso,DC=com" ` -Properties DisplayName,UserPrincipalName,SamAccountName,LastLogonDate | Select-Object DisplayName,UserPrincipalName,SamAccountName,LastLogonDate | Export-Csv "C:\AD_Users.csv" -NoTypeInformation -Encoding UTF8必要最小限の属性のみ。まずはこれでOK。
有効ユーザーのみGet-ADUser -Filter 'Enabled -eq $true' -SearchBase "OU=..." ` -Properties DisplayName,UserPrincipalName,SamAccountName,LastLogonDate | Select-Object DisplayName,UserPrincipalName,SamAccountName,LastLogonDate | Export-Csv "C:\AD_EnabledUsers.csv" -NoTypeInformation -Encoding UTF8Where-Objectではなく-Filterでサーバー側フィルタ(高速)。
大量件数向け(堅牢)Get-ADUser -LDAPFilter "(&(objectCategory=person)(objectClass=user))" ` -SearchBase "OU=..." -SearchScope Subtree ` -ResultPageSize 1000 -ResultSetSize $null ` -Properties DisplayName,UserPrincipalName,sAMAccountName,LastLogonDate | Select-Object DisplayName,UserPrincipalName,sAMAccountName,LastLogonDate | Export-Csv "C:\AD_Users_Paged.csv" -NoTypeInformation -Encoding UTF8-ResultPageSizeでページング、-ResultSetSize $nullで全件取得を明示。
(注:-PageSizeではなく-ResultPageSizeが正しいパラメーター名)

GUI(ADユーザーとコンピューター)での代替方法

  1. dsa.msc(Active Directory ユーザーとコンピューター)を起動。
  2. 左ペインで対象OUを選択し、右ペインでユーザー一覧を表示。
  3. 列ヘッダーを右クリックして「列の追加…」を選び、出力したい列を追加。
  4. 右ペインの空白部分を右クリック、またはメニュー「操作」→「一覧のエクスポート…」を選択。
  5. 保存形式でCSVを選び、ファイルを保存。

制限:GUI出力は表示列に依存し、任意属性の柔軟な選択や複数階層の条件指定は不得手。定期運用や監査用途はPowerShell推奨。

実行手順(PowerShell):初めてでも迷わない

  1. 実行環境:ドメイン参加済みの管理端末、またはドメインコントローラー。RSATの「Active Directory モジュール」を導入済みであること。
  2. 権限:ユーザー属性の読み取りは通常ドメインユーザーで可。特別な権限は基本不要(組織のセキュリティポリシーに従う)。
  3. OU DNの確認:ADUCで対象OUを右クリック→「プロパティ」→「属性エディター」→distinguishedNameをコピー。
    (表示→拡張機能を有効化すると「属性エディター」が見えます)
  4. 疎通テスト:まず1件だけ出してみると安心。 Get-ADUser -Filter * -SearchBase "OU=..." -ResultSetSize 1 | Format-Table
  5. 本番出力:前掲のワンライナーを実行。完了後、CSVをExcelで開いて確認。
  6. 再現性:コマンドと実行日時を残すため、Transcriptの活用がおすすめ。 Start-Transcript -Path "C:\logs\ad_export_$(Get-Date -f yyyyMMdd_HHmm).log" # ここにエクスポートコマンド Stop-Transcript

効果的な属性選定のヒント

目的代表属性解説
一般的な台帳DisplayName, sAMAccountName, UserPrincipalName, Enabled人に見せる一覧に必須。Enabledで無効化アカウントを識別。
棚卸し・監査LastLogonDate, PasswordLastSet, AccountExpirationDate, whenCreated休眠・長期未使用や期限管理を検出。
メール/連絡先mail, telephoneNumber, department, title連絡先名簿に便利。
グループ管理memberOfDNで返るため、見やすい文字列に整形する例を後述。

フィルタの書き方(速い/遅いの分かれ目)

抽出条件はサーバー側でかけるのが鉄則。次の優先度で考えると高速です。

  1. -LDAPFilter(最速・柔軟)
  2. -Filter(多くのケースで十分速い)
  3. Where-Object(取得後の絞り込み。大量件数では避ける)
要件例ポイント
会社名で前方一致Get-ADUser -Filter 'Company -like "Alpha*"' -SearchBase "OU=..." ...-Filterで十分高速。
有効アカウントのみGet-ADUser -LDAPFilter "(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))))" ...ビット演算フィルターでDisabledフラグを除外。
OU直下のみGet-ADUser -Filter * -SearchBase "OU=..." -SearchScope OneLevel ...配下のサブOUを含めない。

大量ユーザー環境での安定化テクニック

  • ページング:-ResultPageSize 500~1000を指定(AD側のサイズ制限を安全に回避)。
  • 全件取得:-ResultSetSize $null(既定で全件だが、明記すると読みやすい)。
  • プロパティ最小化:CSVに不要な列は取らない(速度とサイズに直結)。
  • パイプライン優先:メモリ節約のため、都度Export-Csvへ流す。
  • ターゲットDC固定:-Server <DC名>でアクセス先を固定すると、障害時の切り分けが容易。

ログオン情報を正しく理解する

  • lastLogon:DCごとに保持(複製されない)。正確だが全DC照会が必要。
  • lastLogonTimestamp:おおむね9~14日周期で複製される。
  • LastLogonDate:lastLogonTimestampからPowerShellが計算した利便プロパティ。運用上はこれで十分な場面が多い。

全DCの最大値で「本当の最終ログオン」を出す例(重いので計画実行推奨):

$searchBase = "OU=MYOU,OU=TopLevelOU,DC=contoso,DC=com"
$users = Get-ADUser -Filter * -SearchBase $searchBase -Properties sAMAccountName,DisplayName
$dcs   = Get-ADDomainController -Filter * | Select-Object -ExpandProperty HostName

$result = foreach ($u in $users) {
$max = 0
foreach ($dc in $dcs) {
$t = (Get-ADUser -Identity $u.SamAccountName -Server $dc -Properties lastLogon).lastLogon
if ($t -gt $max) { $max = $t }
}
[pscustomobject]@{
DisplayName     = $u.DisplayName
SamAccountName  = $u.SamAccountName
LastLogonExact  = if ($max -gt 0) [DateTime]::FromFileTime($max) else $null
}
}
$result | Export-Csv "C:\AD_Users_LastLogonExact.csv" -NoTypeInformation -Encoding UTF8 

グループ(memberOf)を読みやすく出力する

Get-ADUser -Filter * -SearchBase "OU=..." -Properties DisplayName,sAMAccountName,memberOf |
  Select-Object DisplayName,sAMAccountName,
    @{Name='Groups';Expression={
        ($_.memberOf | ForEach-Object {
            if ($_ -match '^CN=([^,]+),') { $Matches[1] }
        }) -join ';'
    }} |
  Export-Csv "C:\AD_Users_WithGroups.csv" -NoTypeInformation -Encoding UTF8

グループ名をセミコロン区切りに整形してCSVへ。DNのままでは可読性が落ちるため、レポート用途には上記のような整形が便利です。

コンピューターアカウントも取得したい

Get-ADComputer -Filter * -SearchBase "OU=MYOU,OU=TopLevelOU,DC=contoso,DC=com" `
  -Properties Name,DNSHostName,IPv4Address,OperatingSystem,LastLogonDate |
  Select-Object Name,DNSHostName,IPv4Address,OperatingSystem,LastLogonDate |
  Export-Csv "C:\AD_Computers.csv" -NoTypeInformation -Encoding UTF8

構文はユーザーと同様。棚卸しやパッチ計画の基礎データに向きます。

CSVの文字化け・改行問題を防ぐ

  • まずはUTF-8:-Encoding UTF8(BOM付き)で多くのExcelが正しく開けます。
  • それでも文字化けする場合:日本語OSでは-Encoding Default(CP932/Shift_JIS)が無難。
  • 改行混入対策:Descriptionなどに改行があるとCSVの見映えが崩れることがあります。必要なら整形。 Select-Object @{N='Description';E={($_.Description -replace '\r?\n',' ')}}

よくあるエラーと対処

症状原因対処
Select-ObjectでLastLoginが空属性名の誤りLastLogonDateへ修正。精度が必要なら全DC照会へ。
The term 'Get-ADUser' is not recognizedADモジュール未導入/未読み込みRSAT導入。Import-Module ActiveDirectory。
Access to the path 'C:\output.csv' is denied.書き込み権限不足/ファイルが使用中別パスへ出力、管理者で実行、既存ファイルを閉じる。
件数が少ない/多すぎるOU DN誤り/スコープ違い-SearchBaseと-SearchScope(Subtree/OneLevel)を再確認。

運用のコツ(監査・定期エクスポート)

  • スナップショット管理:ファイル名に日付を入れて差分管理。 $stamp = Get-Date -Format 'yyyyMMdd' Export-Csv "C:\reports\AD_Users_$stamp.csv" ...
  • 差分抽出:前回CSVと比較して新規/削除/変更を把握。 $a = Import-Csv .\AD_Users_20250101.csv $b = Import-Csv .\AD_Users_20250201.csv Compare-Object $a $b -Property SamAccountName,UserPrincipalName -PassThru | Export-Csv .\AD_Users_Diff.csv -NoTypeInformation -Encoding UTF8
  • 再利用性:パラメーター化したスクリプトにして、OUや出力属性を変えても使い回せるように。
  • 監査証跡:Start-Transcriptで操作ログを保存。

付録:貼って使える「実務スクリプト」

OU・出力属性・有効アカウント限定などを引数で切り替えられるテンプレートです。

param(
  [Parameter(Mandatory=$true)][string]$SearchBase,
  [string[]]$Attributes = @('DisplayName','Description','UserPrincipalName','SamAccountName','LastLogonDate'),
  [string]$OutFile = "C:\AD_Users.csv",
  [switch]$OnlyEnabled,
  [ValidateSet('UTF8','Default')][string]$Encoding = 'UTF8'
)

Import-Module ActiveDirectory

# フィルタ定義

if ($OnlyEnabled) {
$filter = 'Enabled -eq $true'
} else {
$filter = '*'
}

# 取得

$props = $Attributes -join ','
$users = Get-ADUser -Filter $filter -SearchBase $SearchBase -SearchScope Subtree `          -ResultPageSize 1000 -ResultSetSize $null`
-Properties $Attributes

# 出力(列順をAttributesに合わせる)

$users | Select-Object $Attributes | Export-Csv $OutFile -NoTypeInformation -Encoding $Encoding

Write-Host "Exported to $OutFile" 

付録:CSVDE/DSQUERYによる代替(参考)

  • csvde:OS標準。属性リストも自由だが、PowerShellに比べ整形が難しい。 csvde -f C:\ad_users.csv -d "OU=MYOU,OU=TopLevelOU,DC=contoso,DC=com" -r "(&(objectCategory=person)(objectClass=user))" -l "displayName,description,userPrincipalName,sAMAccountName,lastLogonTimestamp"
  • dsquery:手軽だが柔軟性は限定的。 dsquery user "OU=MYOU,OU=TopLevelOU,DC=contoso,DC=com" -limit 0

まとめ

  • 提示コマンドは、LastLogin → LastLogonDate、-Properties *を必要最小への2点を直せば実用レベル。
  • 大量環境では-ResultPageSizeとサーバー側フィルタで安定・高速。
  • GUI(ADUC)の一覧のエクスポートは簡単だが拡張性に乏しい。定期運用はPowerShell一択。
  • ログオン情報は用途に応じて精度を選ぶ(日常運用=LastLogonDate、厳密監査=全DC照会)。
  • 文字化けは-Encoding UTF8を第一候補に、必要に応じて-Encoding Default。

(クイックリファレンス)「このまま使える」コマンド集

目的コマンド(抜粋)
特定OU配下の全ユーザーGet-ADUser -Filter * -SearchBase "OU=..." -Properties DisplayName,UserPrincipalName,sAMAccountName,LastLogonDate | Select-Object DisplayName,UserPrincipalName,sAMAccountName,LastLogonDate | Export-Csv "C:\AD_Users.csv" -NoTypeInformation -Encoding UTF8
有効ユーザーのみGet-ADUser -Filter 'Enabled -eq $true' -SearchBase "OU=..." -Properties ... | Select ... | Export-Csv ...
グループ名も出すGet-ADUser -Filter * -SearchBase "OU=..." -Properties memberOf | Select-Object DisplayName,sAMAccountName,@{N='Groups';E={($_.memberOf -replace '^CN=([^,]+),','$1') -join ';'}} | Export-Csv "C:\AD_Users_WithGroups.csv" -NoTypeInformation -Encoding UTF8
厳密な最終ログオン(重め)# 全DCからlastLogonを集約して最大値を採用
コンピューター一覧Get-ADComputer -Filter * -SearchBase "OU=..." -Properties Name,DNSHostName,IPv4Address,OperatingSystem,LastLogonDate | Select-Object Name,DNSHostName,IPv4Address,OperatingSystem,LastLogonDate | Export-Csv "C:\AD_Computers.csv" -NoTypeInformation -Encoding UTF8

安全運用の注意点

  • 最小権限:読み取りに管理者権限は原則不要。不要に昇格しない。
  • 個人情報:部署・電話などの属性は取り扱いに注意。外部共有時はマスキング。
  • スケジュール実行:タスクスケジューラで夜間に実行すると業務時間帯の負荷を抑制。
  • 障害対策:-Serverで特定DCを指す場合は、予備DC向けのフェイルオーバー手順を用意。

このページのゴール

特定OU配下のユーザーをPowerShellでCSVへ確実・高速にエクスポートするための正しいサンプルと実運用の定石を提供しました。GUIでの単発出力から、監査対応・定期レポートまで一通りこなせます。まずは最短ワンライナーから始め、必要に応じてフィルタ・属性・エンコーディングをカスタマイズしてください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次