AD内のユーザーアカウントの設定プロパティを一括でCSVに出力する方法
PowerShell(RSAT: Active Directory)で目的別に出力する4+2パターンをまとめます。
前提条件
- RSAT: Active Directory をインストール(Windows 10/11)
Get-WindowsCapability -Name RSAT.ActiveDirectory* -Online
Add-WindowsCapability -Name RSAT.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 -Online - ドメイン参加PC:そのまま実行可。ワークグループPC:
-Serverと-Credentialを指定。 - CSVは UTF-8 で保存。出力メッセージは英語推奨(文字化け回避)。
① 個人:特定の属性だけに絞って出力
最小限の列(基本情報+所属グループ名)をCSVへ。
# ADUserExport_Selected.ps1
param(
[Parameter(Mandatory=$true)][string]$UserSamAccountName, # e.g., taro.yamada
[string]$Server, # e.g., dc1.contoso.com
[System.Management.Automation.PSCredential]$Credential,
[string]$ExportPath = ".\UserInfo_Selected.csv"
)
Import-Module ActiveDirectory -ErrorAction Stop
$common = @{ Identity = $UserSamAccountName; Properties='*' }
if ($Server) { $common.Server = $Server }
if ($Credential) { $common.Credential = $Credential }
$user = Get-ADUser @common -ErrorAction Stop
# Resolve direct groups to names
$groupNames = @()
if ($user.MemberOf) {
foreach ($dn in $user.MemberOf) {
try {
$gp = @{ Identity=$dn; Properties='Name' }
if ($Server) { $gp.Server = $Server }
if ($Credential) { $gp.Credential = $Credential }
$g = Get-ADGroup @gp
$groupNames += $g.Name
} catch { $groupNames += $dn }
}
}
$result = [PSCustomObject]@{
SamAccountName = $user.SamAccountName
UserPrincipalName = $user.UserPrincipalName
DisplayName = $user.DisplayName
Enabled = $user.Enabled
Department = $user.Department
Company = $user.Company
Mail = $user.Mail
LastLogonDate = $user.LastLogonDate
MemberOf_Names = ($groupNames | Sort-Object -Unique -join ';')
}
$result | Export-Csv -Path $ExportPath -NoTypeInformation -Encoding UTF8
Write-Output ("Export completed. File: {0}" -f $ExportPath)
② 個人:全属性(展開+日付変換付き/1行)
# ADUserExport_Full.ps1
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][string]$UserSamAccountName,
[string]$Server,
[System.Management.Automation.PSCredential]$Credential,
[string]$ExportFolder = "."
)
function Convert-FileTime([object]$v) {
if ($null -eq $v -or $v -eq '') { return $null }
try {
[int64]$t = [int64]$v
if ($t -le 0 -or $t -eq 9223372036854775807) { return $null } # Never/Not set
return [DateTime]::FromFileTime($t)
} catch { return $null }
}
function Convert-If-DateLike([hashtable]$raw,[string]$name,[string]$kind='Auto'){
if (-not $raw.ContainsKey($name)) { return }
$val = $raw[$name]; $converted = $null
switch ($kind) {
'FileTime' { $converted = Convert-FileTime $val }
'DateTime' { try { $converted = [DateTime]$val } catch { } }
default {
if ($val -is [int64] -or $val -is [int32] -or ($val -is [string] -and $val -match '^\d+$')) {
$converted = Convert-FileTime $val
} else { try { $converted = ($val -is [DateTime]) ? $val : [DateTime]$val } catch { } }
}
}
$raw["${name}_Converted"] = $converted
}
Import-Module ActiveDirectory -ErrorAction Stop
$cp = @{ Identity=$UserSamAccountName; Properties='*' }
if ($Server) { $cp.Server = $Server }
if ($Credential) { $cp.Credential = $Credential }
$user = Get-ADUser @cp -ErrorAction Stop
# Expand multi-valued
$groupNames = @()
if ($user.MemberOf) {
foreach ($dn in $user.MemberOf) {
try {
$gp=@{ Identity=$dn; Properties='Name' }
if ($Server) { $gp.Server = $Server }
if ($Credential) { $gp.Credential = $Credential }
$g=Get-ADGroup @gp
$groupNames+= $g.Name
} catch { $groupNames+= $dn }
}
}
$proxyJoined = if ($user.ProxyAddresses) { $user.ProxyAddresses -join ';' } else { '' }
$memberOfNames = ($groupNames | Where-Object { $_ } | Sort-Object -Unique) -join ';'
$memberOfDNs = if ($user.MemberOf) { ($user.MemberOf -join ';') } else { '' }
# Merge single-row
$raw = @{}
($user | Select-Object *).PSObject.Properties | ForEach-Object { $raw[$_.Name] = $_.Value }
$raw['ProxyAddresses_Joined'] = $proxyJoined
$raw['MemberOf_Direct_Names'] = $memberOfNames
$raw['MemberOf_DN_Joined'] = $memberOfDNs
$ft = @('lastLogonTimestamp','lastLogon','lastLogoff','pwdLastSet','badPasswordTime','lockoutTime','accountExpires','msDS-UserPasswordExpiryTimeComputed')
foreach ($n in $ft) { Convert-If-DateLike -raw $raw -name $n -kind 'FileTime' }
$dt = @('whenCreated','whenChanged','LastLogonDate','PasswordLastSet','AccountExpirationDate')
foreach ($n in $dt) { Convert-If-DateLike -raw $raw -name $n -kind 'DateTime' }
$singleRow = [PSCustomObject]$raw
$ts = Get-Date -Format "yyyyMMdd-HHmmss"
$path = Join-Path $ExportFolder ("UserInfo_{0}_{1}.csv" -f $UserSamAccountName,$ts)
$singleRow | Export-Csv -Path $path -NoTypeInformation -Encoding UTF8
Write-Output ("Export completed. File: {0}" -f $path)
③ 一括:グループ/OU配下のユーザーを出力
# ADUserBulkExport.ps1
[CmdletBinding(DefaultParameterSetName='ByGroup')]
param(
[Parameter(ParameterSetName='ByGroup', Mandatory=$true)][string]$Group, # sAMAccountName or DN
[Parameter(ParameterSetName='ByGroup')][switch]$Recursive,
[Parameter(ParameterSetName='ByOU', Mandatory=$true)][string]$SearchBase, # OU DN
[string]$Server,
[System.Management.Automation.PSCredential]$Credential,
[string]$ExportFolder = "."
)
function Convert-FileTime([object]$v){
if ($null -eq $v -or $v -eq '') { return $null }
try { [int64]$t=[int64]$v; if ($t -le 0 -or $t -eq 9223372036854775807){return $null}; return [DateTime]::FromFileTime($t) }
catch { return $null }
}
function Convert-If-DateLike([hashtable]$raw,[string]$name,[string]$kind='Auto'){
if (-not $raw.ContainsKey($name)) { return }
$val=$raw[$name]; $converted=$null
switch($kind){
'FileTime' { $converted=Convert-FileTime $val }
'DateTime' { try{$converted=[DateTime]$val}catch{} }
default {
if ($val -is [int64] -or $val -is [int32] -or ($val -is [string] -and $val -match '^\d+$')) {
$converted=Convert-FileTime $val
} else { try{ $converted = ($val -is [DateTime]) ? $val : [DateTime]$val }catch{} }
}
}
$raw["${name}_Converted"]=$converted
}
Import-Module ActiveDirectory -ErrorAction Stop
$uCommon=@{ Properties='*' }
if ($Server) { $uCommon.Server = $Server }
if ($Credential) { $uCommon.Credential = $Credential }
# Cache group names
$script:__adCache=@{}
function Get-GroupName([string]$dn){
$key="group|$dn|$Server"
if ($__adCache.ContainsKey($key)) { return $__adCache[$key] }
$p=@{ Identity=$dn; Properties='Name' }
if ($Server) { $p.Server = $Server }
if ($Credential) { $p.Credential = $Credential }
try { $g=Get-ADGroup @p; $__adCache[$key]=$g.Name; return $g.Name } catch { $__adCache[$key]=$dn; return $dn }
}
function Expand-User($user){
$gNames=@()
if ($user.MemberOf) {
foreach($dn in $user.MemberOf){ $gNames+= Get-GroupName $dn }
$gNames = $gNames | Where-Object { $_ } | Sort-Object -Unique
}
$proxy = if ($user.ProxyAddresses){ $user.ProxyAddresses -join ';' } else { '' }
$raw=@{}
($user|Select-Object *).PSObject.Properties | ForEach-Object { $raw[$_.Name]=$_.Value }
$raw['ProxyAddresses_Joined']= $proxy
$raw['MemberOf_Direct_Names']= $gNames -join ';'
$raw['MemberOf_DN_Joined'] = if ($user.MemberOf){ ($user.MemberOf -join ';') } else { '' }
$ft=@('lastLogonTimestamp','lastLogon','lastLogoff','pwdLastSet','badPasswordTime','lockoutTime','accountExpires','msDS-UserPasswordExpiryTimeComputed')
foreach($n in $ft){ Convert-If-DateLike -raw $raw -name $n -kind 'FileTime' }
$dt=@('whenCreated','whenChanged','LastLogonDate','PasswordLastSet','AccountExpirationDate')
foreach($n in $dt){ Convert-If-DateLike -raw $raw -name $n -kind 'DateTime' }
return [PSCustomObject]$raw
}
# Resolve users
$users=@()
if ($PSCmdlet.ParameterSetName -eq 'ByGroup'){
$gp=@{ Identity=$Group }
if ($Server) { $gp.Server = $Server }
if ($Credential) { $gp.Credential = $Credential }
$grp=Get-ADGroup @gp
$mp=@{ Identity=$grp.DistinguishedName }
if ($Recursive) { $mp.Recursive=$true }
if ($Server) { $mp.Server = $Server }
if ($Credential) { $mp.Credential = $Credential }
$members = Get-ADGroupMember @mp | Where-Object { $_.objectClass -eq 'user' }
foreach($m in $members){ $users += Get-ADUser @uCommon -Identity $m.DistinguishedName }
} else {
$sp=@{ SearchBase=$SearchBase; Filter='*' }
if ($Server) { $sp.Server = $Server }
if ($Credential) { $sp.Credential = $Credential }
$users = Get-ADUser @sp @uCommon
}
# Build rows
$rows = foreach($u in $users){ Expand-User $u }
$ts = Get-Date -Format "yyyyMMdd-HHmmss"
$csv = if ($PSCmdlet.ParameterSetName -eq 'ByGroup') { "UserInfo_Group_$($Group -replace '[\\/:*?""<>|]','_')_$ts.csv" } else { "UserInfo_OU_$ts.csv" }
$path = Join-Path $ExportFolder $csv
$rows | Export-Csv -Path $path -NoTypeInformation -Encoding UTF8
Write-Output ("Export completed. Rows: {0}, File: {1}" -f $rows.Count, $path)
④ 日付(FileTime)を人間可読に変換する方法
PowerShell:
$dt = [DateTime]::FromFileTime($user.lastLogonTimestamp) # 0 / 9223372036854775807 は未設定扱い
Excel:
=(((A1/10000000)/86400) + DATE(1601,1,1))
⑤ 軽量版:監査用(列順固定)
# ADUserExport_Audit.ps1
param(
[Parameter(Mandatory=$true)][string]$UserSamAccountName,
[string]$Server,
[System.Management.Automation.PSCredential]$Credential,
[string]$ExportPath = ".\UserInfo_Audit.csv"
)
Import-Module ActiveDirectory -ErrorAction Stop
$common = @{ Identity = $UserSamAccountName; Properties='*' }
if ($Server) { $common.Server = $Server }
if ($Credential) { $common.Credential = $Credential }
$user = Get-ADUser @common -ErrorAction Stop
# Groups (direct)
$groupNames = @()
if ($user.MemberOf) {
foreach ($dn in $user.MemberOf) {
try {
$gp = @{ Identity=$dn; Properties='Name' }
if ($Server) { $gp.Server = $Server }
if ($Credential) { $gp.Credential = $Credential }
$g = Get-ADGroup @gp
$groupNames += $g.Name
} catch { $groupNames += $dn }
}
}
$groupsJoined = $groupNames -join ';'
function Convert-FileTime([object]$v){
if ($null -eq $v -or $v -eq '') { return $null }
try {
[int64]$t=[int64]$v
if ($t -le 0 -or $t -eq 9223372036854775807){ return $null }
return [DateTime]::FromFileTime($t)
} catch { return $null }
}
$auditRow = [PSCustomObject]@{
SamAccountName = $user.SamAccountName
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
Enabled = $user.Enabled
Department = $user.Department
Company = $user.Company
Mail = $user.Mail
WhenCreated = $user.WhenCreated
LastLogonDate = $user.LastLogonDate
LastLogonTS = Convert-FileTime $user.lastLogonTimestamp
PwdLastSet = Convert-FileTime $user.pwdLastSet
AccountExpires = Convert-FileTime $user.accountExpires
Groups = $groupsJoined
}
$auditRow | Select-Object SamAccountName,DisplayName,UserPrincipalName,Enabled,Department,Company,Mail,WhenCreated,LastLogonDate,LastLogonTS,PwdLastSet,AccountExpires,Groups |
Export-Csv -Path $ExportPath -NoTypeInformation -Encoding UTF8
Write-Output ("Audit export completed. File: {0}" -f $ExportPath)
⑥ 一括エクスポート:軽量監査版(列順固定)
# ADUserBulkExport_Audit.ps1
[CmdletBinding(DefaultParameterSetName='ByGroup')]
param(
[Parameter(ParameterSetName='ByGroup', Mandatory=$true)]
[string]$Group,
[Parameter(ParameterSetName='ByGroup')][switch]$Recursive,
[Parameter(ParameterSetName='ByOU', Mandatory=$true)]
[string]$SearchBase,
[string]$Server,
[System.Management.Automation.PSCredential]$Credential,
[string]$ExportFolder = "."
)
function Convert-FileTime([object]$v){
if ($null -eq $v -or $v -eq "") { return $null }
try {
[int64]$t = [int64]$v
if ($t -le 0 -or $t -eq 9223372036854775807){ return $null }
return [DateTime]::FromFileTime($t)
} catch { return $null }
}
$script:__cache = @{}
function Get-GroupNameFromDN([string]$dn){
$key = "group|$dn|$Server"
if ($__cache.ContainsKey($key)) { return $__cache[$key] }
$p = @{ Identity=$dn; Properties='Name' }
if ($Server) { $p.Server = $Server }
if ($Credential) { $p.Credential = $Credential }
try { $g = Get-ADGroup @p; $__cache[$key] = $g.Name; return $g.Name } catch { $__cache[$key] = $dn; return $dn }
}
Import-Module ActiveDirectory -ErrorAction Stop
$uCommon = @{ Properties = '*' }
if ($Server) { $uCommon.Server = $Server }
if ($Credential) { $uCommon.Credential = $Credential }
$users = @()
if ($PSCmdlet.ParameterSetName -eq 'ByGroup') {
$gp = @{ Identity=$Group }
if ($Server) { $gp.Server = $Server }
if ($Credential) { $gp.Credential = $Credential }
$grp = Get-ADGroup @gp
$mp = @{ Identity=$grp.DistinguishedName }
if ($Recursive) { $mp.Recursive = $true }
if ($Server) { $mp.Server = $Server }
if ($Credential) { $mp.Credential = $Credential }
$members = Get-ADGroupMember @mp | Where-Object { $_.objectClass -eq 'user' }
foreach($m in $members) { $users += Get-ADUser @uCommon -Identity $m.DistinguishedName }
} else {
$sp = @{ SearchBase=$SearchBase; Filter='*' }
if ($Server) { $sp.Server = $Server }
if ($Credential) { $sp.Credential = $Credential }
$users = Get-ADUser @sp @uCommon
}
$rows = foreach($user in $users){
$gNames = @()
if ($user.MemberOf) {
foreach($dn in $user.MemberOf){ $gNames += Get-GroupNameFromDN $dn }
$gNames = $gNames | Where-Object { $_ } | Sort-Object -Unique
}
$groupsJoined = $gNames -join ';'
[PSCustomObject]@{
SamAccountName = $user.SamAccountName
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
Enabled = $user.Enabled
Department = $user.Department
Company = $user.Company
Mail = $user.Mail
WhenCreated = $user.WhenCreated
LastLogonDate = $user.LastLogonDate
LastLogonTS = Convert-FileTime $user.lastLogonTimestamp
PwdLastSet = Convert-FileTime $user.pwdLastSet
AccountExpires = Convert-FileTime $user.accountExpires
Groups = $groupsJoined
}
}
$ts = Get-Date -Format "yyyyMMdd-HHmmss"
$name = if ($PSCmdlet.ParameterSetName -eq 'ByGroup') {
"UserInfo_Audit_Group_$($Group -replace '[\\/:*?""<>|]','_')_${ts}.csv"
} else {
"UserInfo_Audit_OU_${ts}.csv"
}
$path = Join-Path $ExportFolder $name
$rows | Select-Object SamAccountName,DisplayName,UserPrincipalName,Enabled,Department,Company,Mail,WhenCreated,LastLogonDate,LastLogonTS,PwdLastSet,AccountExpires,Groups |
Export-Csv -Path $path -NoTypeInformation -Encoding UTF8
Write-Output ("Audit export completed. Rows: {0}, File: {1}" -f $rows.Count, $path)


コメント