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からやるなどというリスクの高い操作が減らせる機会があれば行えるといいですね。