tech.guitarrapc.cóm

Technical updates

PowerShell で WorkGroup 環境の Windows User ユーザーフラグを変更する

WorkGroup 環境 で PowerShell を使って Windows User のユーザーフラグを変更するのは[ADSI] を参照する必要があるため記事に起こしておきましょう。 これで AD 環境じゃなくてユーザー管理がということも少し減るかもですね。 今回は、 既存ユーザーの ユーザーフラグを指定したものに変更する方法です。

 

ユーザーフラグとは

要は、コンピュータの管理 > ユーザーとグループ > ユーザーのプロパティ にあるオプションです。 ここの変更って大事ですよねー。特に Server OS では。 今回のコードは Windows Server 2012 で検証してあります。

サンプルコード

GitHub に挙げてあります。

https://github.com/guitarrapc/PowerShellUtil/tree/master/ADSI-Cmdlets

以下のコードは、指定したユーザー以外のOS に存在するユーザー情報 を取得して、 そのユーザーフラグを Password Never Expired に変更するものです。 PowerShell 3,0以降はこのように書けます。

$excludeuser = "Administrator","Guest"
$HostPC = [System.Environment]::MachineName

# PowerShell V3.0 では cim から取得可能
$users = (Get-CimInstance -ClassName Win32_UserAccount | where Name -notin $excludeuser).Name

foreach ($user in $users)
{
    $targetuser = [ADSI]("WinNT://{0}/{1}, user" -F $HostPC, $user)
    Write-Warning "Setting user [$($targetuser.name)] as password not expire."
    $userFlags = $targetuser.Get("UserFlags")
    $userFlags = $userFlags -bor 0x10000 # 0x10040 will "not expire + not change password"
    $targetuser.Put("UserFlags", $userFlags)
    $targetuser.SetInfo()
}

 

解説

少し説明しましょう。

ユーザーの取得

PowerShell 3.0 には cim cmdlet があるので簡単ですね。 UserAccountを取得して、絞っただけです。

$excludeuser = "Administrator","Guest"
$HostPC = [System.Environment]::MachineName

# PowerShell V3.0 では cim から取得可能
$users = (Get-CimInstance -ClassName Win32_UserAccount | where Name -notin $excludeuser).Name

PowerShell 2.0 には cim cmdlet がないため、 wmiか以下のコードで取得します。 ここでは、[ADSI] 型にしてpsbaseプロパティの全 childlen を嘗めて、 psbase.schemaClassName から user に該当するもの = ユーザー名 を取得しています。 今回は、Administrator と Guest ユーザーを除外しています。

$HostPC = [System.Environment]::MachineName
$adsi = [ADSI]("WinNT://" + $HostPc)
$users = ($adsi.psbase.children | where {$_.psbase.schemaClassName -match "user"} | where Name -notin "Administrator","Guest").Name

除外する対象を先に定義しておいてもいいでしょう。

$excludeuser = "Administrator","Guest"
$HostPC = [System.Environment]::MachineName
$adsi = [ADSI]("WinNT://" + $HostPc)
$users = ($adsi.psbase.children | where {$_.psbase.schemaClassName -match "user"} | where Name -notin $excludeuser).Name

各ユーザーの adsi パス取得とユーザーフラグ設定、コミット

対象のユーザー名を取得出来たら、 adsi パスを出して UserFlag を設定します。 ここで adsi パスを取得しています。 先のやり方では、ユーザ一覧を取得した時は、Doman|WorkGroup がパスに紛れてしまいそのままでは利用できないため、 adsi path をユーザー毎に取得しなおしています。

foreach ($user in $users)
{
    $targetuser = [ADSI]("WinNT://{0}/{1}, user" -F $HostPC, $user)

ここで UserFlag を取得しています。

    $userFlags = $targetuser.Get("UserFlags")

ここで、任意のユーザーフラグを設定します。 サンプルでは、 0x10000 (ADS_UF_DONT_EXPIRE_PASSWD) としています。

    $userFlags = $targetuser.Get("UserFlags")
    $userFlags = $userFlags -bor 0x10000 # 0x10040 will "not expire + not change password"

ユーザーフラグ一覧はmsdn で公開されています。

ADS_USER_FLAG_ENUM enumeration

設定したいフラグ同志でbitを組み合わせて下さい。

ADS_UF_SCRIPT                                  = 1,        // 0x1
  ADS_UF_ACCOUNTDISABLE                          = 2,        // 0x2
  ADS_UF_HOMEDIR_REQUIRED                        = 8,        // 0x8
  ADS_UF_LOCKOUT                                 = 16,       // 0x10
  ADS_UF_PASSWD_NOTREQD                          = 32,       // 0x20
  ADS_UF_PASSWD_CANT_CHANGE                      = 64,       // 0x40
  ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED         = 128,      // 0x80
  ADS_UF_TEMP_DUPLICATE_ACCOUNT                  = 256,      // 0x100
  ADS_UF_NORMAL_ACCOUNT                          = 512,      // 0x200
  ADS_UF_INTERDOMAIN_TRUST_ACCOUNT               = 2048,     // 0x800
  ADS_UF_WORKSTATION_TRUST_ACCOUNT               = 4096,     // 0x1000
  ADS_UF_SERVER_TRUST_ACCOUNT                    = 8192,     // 0x2000
  ADS_UF_DONT_EXPIRE_PASSWD                      = 65536,    // 0x10000
  ADS_UF_MNS_LOGON_ACCOUNT                       = 131072,   // 0x20000
  ADS_UF_SMARTCARD_REQUIRED                      = 262144,   // 0x40000
  ADS_UF_TRUSTED_FOR_DELEGATION                  = 524288,   // 0x80000
  ADS_UF_NOT_DELEGATED                           = 1048576,  // 0x100000
  ADS_UF_USE_DES_KEY_ONLY                        = 2097152,  // 0x200000
  ADS_UF_DONT_REQUIRE_PREAUTH                    = 4194304,  // 0x400000
  ADS_UF_PASSWORD_EXPIRED                        = 8388608,  // 0x800000
  ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION  = 16777216 // 0x1000000

最後に、ユーザーフラグを確定させます。

    $targetuser.SetInfo()
}

以上で、WorkGroup環境でも任意のユーザーのユーザーフラグを変更できます。 一々マウス/キーボードで GUIからやるなどというリスクの高い操作が減らせる機会があれば行えるといいですね。