概要・前提

Windows ローカルユーザーの棚卸には net user コマンド(コマンドプロンプト)PowerShell の2つの方法があります。いずれも管理者権限で実行してください。

動作確認環境

  • Windows Server 2016 / 2019 / 2022
  • Windows 10 / 11

PowerShell の Get-LocalUser は PowerShell 5.1 以降で利用可能です。

ユーザー一覧の取得

【net user】ユーザー一覧

REM コマンドプロンプト(管理者)
net user

概要一覧が表示されます。特定ユーザーの詳細は net user ユーザー名 で確認します。

net user Administrator

【PowerShell】ユーザー一覧

# ローカルユーザーをすべて取得
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordExpires, PasswordRequired, PasswordLastSet | Format-Table -AutoSize

【PowerShell】CSV 形式でエクスポート

Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordExpires, PasswordLastSet, Description |
  Export-Csv -Path "C:\audit\local_users.csv" -NoTypeInformation -Encoding UTF8

ロック状態の確認

アカウントロックとは、ログイン試行失敗などで一時的にアクセスが遮断された状態です。Enabled=False は管理者が無効化した状態とは異なります。

【net user】ロック状態の確認

REM 特定ユーザーの詳細を確認("Account active" と "Account lockout" を確認)
net user ユーザー名

REM 例:Administrator
net user Administrator

Account lockoutYes の場合はロックされています。

【PowerShell】ロック中ユーザーを一覧表示

# LockedOut=True のユーザーを抽出
Get-LocalUser | Where-Object { $_.AccountLockout } | Select-Object Name, LastLogon, AccountLockout

【PowerShell】全ユーザーのロック状態を確認

Get-LocalUser | Select-Object Name, Enabled, AccountLockout | Format-Table -AutoSize

ロック解除

REM net user(コマンドプロンプト)
net user ユーザー名 /active:yes

# PowerShell
Unlock-LocalUser -Name "ユーザー名"

最終ログイン日時

【net user】最終ログイン日時の確認

REM 特定ユーザーの詳細情報から "Last logon" を確認
net user ユーザー名

REM 例
net user testuser

出力の Last logon 行に最終ログイン日時が表示されます。

【PowerShell】全ユーザーの最終ログイン日時を一覧表示

Get-LocalUser | Select-Object Name, Enabled, LastLogon |
  Sort-Object LastLogon -Descending |
  Format-Table -AutoSize

【PowerShell】一度もログインしていないユーザーを抽出

Get-LocalUser | Where-Object { $_.LastLogon -eq $null } |
  Select-Object Name, Enabled, Description

特権の確認

Windows ローカルの特権アカウントは Administrators グループへの所属で判断します。

【net localgroup】Administrators グループのメンバー確認

net localgroup Administrators

【PowerShell】Administrators グループのメンバー確認

Get-LocalGroupMember -Group "Administrators" | Select-Object Name, ObjectClass, PrincipalSource

【PowerShell】ユーザーが所属するすべてのグループを確認

# 特定ユーザーが所属するグループを確認
$user = "testuser"
Get-LocalGroup | ForEach-Object {
  $group = $_
  Get-LocalGroupMember -Group $group -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -like "*$user*" } |
    ForEach-Object { [PSCustomObject]@{ User = $user; Group = $group.Name } }
} | Format-Table -AutoSize

グループに所属しているユーザー一覧

【net localgroup】グループ一覧の取得

REM ローカルグループの一覧
net localgroup

REM 特定グループのメンバー確認
net localgroup "グループ名"

REM 例:Administrators と Remote Desktop Users
net localgroup Administrators
net localgroup "Remote Desktop Users"

【PowerShell】全グループとメンバーを一覧表示

Get-LocalGroup | ForEach-Object {
  $group = $_.Name
  $members = Get-LocalGroupMember -Group $group -ErrorAction SilentlyContinue
  foreach ($member in $members) {
    [PSCustomObject]@{
      Group  = $group
      Member = $member.Name
      Type   = $member.ObjectClass
    }
  }
} | Sort-Object Group | Format-Table -AutoSize

【PowerShell】CSV エクスポート

Get-LocalGroup | ForEach-Object {
  $group = $_.Name
  $members = Get-LocalGroupMember -Group $group -ErrorAction SilentlyContinue
  foreach ($member in $members) {
    [PSCustomObject]@{
      Group  = $group
      Member = $member.Name
      Type   = $member.ObjectClass
    }
  }
} | Export-Csv -Path "C:\audit\group_members.csv" -NoTypeInformation -Encoding UTF8

パスワード期限

【net user】パスワード期限の確認

REM "Password expires" 行で確認(Never = 無期限)
net user ユーザー名

【PowerShell】パスワード期限を全ユーザーで一覧表示

Get-LocalUser | Select-Object Name, Enabled, PasswordExpires, PasswordLastSet, PasswordRequired |
  Format-Table -AutoSize

【PowerShell】パスワード無期限のユーザーを抽出

# PasswordExpires が空 ($null) = 無期限
Get-LocalUser | Where-Object { $_.PasswordExpires -eq $null -and $_.Enabled -eq $true } |
  Select-Object Name, PasswordLastSet, Enabled

【PowerShell】30 日以内にパスワードが期限切れになるユーザー

$threshold = (Get-Date).AddDays(30)
Get-LocalUser | Where-Object {
  $_.PasswordExpires -ne $null -and $_.PasswordExpires -lt $threshold
} | Select-Object Name, PasswordExpires | Sort-Object PasswordExpires

一定期間未使用ユーザー

【PowerShell】90 日以上ログインしていないユーザーを抽出

$threshold = (Get-Date).AddDays(-90)
Get-LocalUser | Where-Object {
  $_.Enabled -eq $true -and
  ($_.LastLogon -eq $null -or $_.LastLogon -lt $threshold)
} | Select-Object Name, Enabled, LastLogon | Sort-Object LastLogon

【PowerShell】日数を変数で指定して汎用化

$inactiveDays = 90   # 変更可能
$threshold = (Get-Date).AddDays(-$inactiveDays)

$result = Get-LocalUser | Where-Object {
  $_.Enabled -eq $true -and
  ($_.LastLogon -eq $null -or $_.LastLogon -lt $threshold)
} | Select-Object Name,
  @{N="最終ログイン"; E={ if ($_.LastLogon) { $_.LastLogon } else { "未ログイン" } }},
  Enabled

$result | Format-Table -AutoSize
$result | Export-Csv "C:\audit\inactive_users.csv" -NoTypeInformation -Encoding UTF8

無効化されたユーザー

【net user】無効化ユーザーの確認

REM "Account active" が "No" のユーザーが無効化状態
net user ユーザー名

【PowerShell】無効化されたユーザーを一覧表示

Get-LocalUser | Where-Object { $_.Enabled -eq $false } |
  Select-Object Name, LastLogon, PasswordLastSet, Description |
  Format-Table -AutoSize

【PowerShell】有効・無効をフラグ付きで全件表示

Get-LocalUser | Select-Object Name,
  @{N="状態"; E={ if ($_.Enabled) { "有効" } else { "無効" } }},
  LastLogon, Description |
  Format-Table -AutoSize

ユーザーの有効化・無効化

REM コマンドプロンプト
net user ユーザー名 /active:yes   REM 有効化
net user ユーザー名 /active:no    REM 無効化

# PowerShell
Enable-LocalUser  -Name "ユーザー名"
Disable-LocalUser -Name "ユーザー名"