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肥大)。サーバー負荷軽減のためも絞る。 |
| ログオン日時 | LastLogin | LastLogonDate | LastLoginという属性は存在しません。実務では複製されるLastLogonDateが扱いやすい(精度の注意は後述)。 |
| エンコーディング | 未指定 | -Encoding UTF8 | Excelでの文字化け抑止。環境により-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 UTF8 | Where-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ユーザーとコンピューター)での代替方法
- dsa.msc(Active Directory ユーザーとコンピューター)を起動。
- 左ペインで対象OUを選択し、右ペインでユーザー一覧を表示。
- 列ヘッダーを右クリックして「列の追加…」を選び、出力したい列を追加。
- 右ペインの空白部分を右クリック、またはメニュー「操作」→「一覧のエクスポート…」を選択。
- 保存形式でCSVを選び、ファイルを保存。
制限:GUI出力は表示列に依存し、任意属性の柔軟な選択や複数階層の条件指定は不得手。定期運用や監査用途はPowerShell推奨。
実行手順(PowerShell):初めてでも迷わない
- 実行環境:ドメイン参加済みの管理端末、またはドメインコントローラー。RSATの「Active Directory モジュール」を導入済みであること。
- 権限:ユーザー属性の読み取りは通常ドメインユーザーで可。特別な権限は基本不要(組織のセキュリティポリシーに従う)。
- OU DNの確認:ADUCで対象OUを右クリック→「プロパティ」→「属性エディター」→
distinguishedNameをコピー。
(表示→拡張機能を有効化すると「属性エディター」が見えます) - 疎通テスト:まず1件だけ出してみると安心。
Get-ADUser -Filter * -SearchBase "OU=..." -ResultSetSize 1 | Format-Table - 本番出力:前掲のワンライナーを実行。完了後、CSVをExcelで開いて確認。
- 再現性:コマンドと実行日時を残すため、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 | 連絡先名簿に便利。 |
| グループ管理 | memberOf | DNで返るため、見やすい文字列に整形する例を後述。 |
フィルタの書き方(速い/遅いの分かれ目)
抽出条件はサーバー側でかけるのが鉄則。次の優先度で考えると高速です。
-LDAPFilter(最速・柔軟)-Filter(多くのケースで十分速い)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 recognized | ADモジュール未導入/未読み込み | 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での単発出力から、監査対応・定期レポートまで一通りこなせます。まずは最短ワンライナーから始め、必要に応じてフィルタ・属性・エンコーディングをカスタマイズしてください。

コメント