treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

※https化しました。その影響でしばらくリンク切れなどがあるかもしれませんが徐々に修正していきます。 リンク切れなどのお気づきの点がございましたらコメントなどでご指摘いただけますと助かります。

Windows10のローカルユーザの存在有無判定と有効化処理をバッチで

Windows10のローカルユーザをちょっと操作する必要があったので、バッチファイルで処理してみました。
作成したバッチファイルをご報告です。

ローカルユーザが無効化⇒有効化に切り替えたい

PCによってビルトインのAdministratorユーザが有効だったり無効だったり、(たぶん大型アップデートを適用したら)Administratorが無効になっていたり、そんなPC環境を揃えるためにビルトインAdministratorユーザを有効化するバッチを用意することになったので作成してみました。
※実際は、Administratorじゃないのですが、ここではビルトインのAdministratorユーザということで話を進めていきます。

ユーザの有効化と無効化

Windows10のローカルユーザが有効か無効かを判断する箇所は、

f:id:treedown:20210306023103p:plain

この画面の「アカウントを無効にする」の箇所にチェックが入っていればアカウントは無効になっています。

そうなると、この箇所の有無が検出できれば、目的は達成出来そうな気がします。

コマンドで調べてみる

コマンドでユーザの有効化と無効化を調べるには「net user」コマンドが使えます。このコマンドにユーザ名を引数にする(例えば、「net user administrator」のように)ことでユーザの情報の詳細が画面に表示されます。
この画面表示中に「アカウント有効」という項目が「Yes」とか「No」とかで表現されています。

うーん、となると、最初は

net user administrator | find "アカウント有効"

で、

--------------------------------------------------------------
アカウントが無効の場合
--------------------------------------------------------------
C:\>net user administrator | find "アカウント有効"
アカウント有効 No
--------------------------------------------------------------
アカウントが有効の場合
--------------------------------------------------------------
C:\>net user administrator | find "アカウント有効"
アカウント有効 Yes
--------------------------------------------------------------

このような感じで画面に表示させることができました。でも、これだと、どう判定に使おうか迷います。結局YesかNoかをどうにかして収集して判定条件にしないといけない。

そこで、さらに条件を追加して以下で判定するのが良さそうという結論に至りました。

net user administrator | find "アカウント有効" | find "Yes"
net user administrator | find "アカウント有効" | find "No"

これなら
--------------------------------------------------------------
アカウントが無効の場合
--------------------------------------------------------------

f:id:treedown:20210306023214p:plain
--------------------------------------------------------------
アカウントが有効の場合
--------------------------------------------------------------

f:id:treedown:20210306023225p:plain
--------------------------------------------------------------

アカウントの状態を決め打ちして判定に使えそうです。
これで「if %ERRORLEVEL%」を使ってエラーレベルを取れば判定可能じゃないか?と考えました。早速やってみます。

バッチファイル(デバッグ用のメッセージ入り)

最初に、echoでメッセージが画面に表示されて、どの処理が実行されたかを見えるようにしたバッチファイルを用意しました。
※ただし、実行は「管理者:コマンドプロンプト」で実行する必要があります。net userコマンド実行には管理者権限が必要です。

--------------------------------------------------------------
<AdmActive.bat>メッセージ表示(デバッグ)版
--------------------------------------------------------------
@echo off

set UsrID=Administrator

echo アカウント有効化確認:判定条件=No
net user %UsrID% | find "アカウント有効" | find "No"

rem 条件を満たせばERRORLEVELは0に、条件外の場合にはERRORLEVELは1になる
if %ERRORLEVEL% == 0 goto AccountActive
if %ERRORLEVEL% == 1 goto Confirmation

:AccountActive
echo "ERRORLEVELは"%ERRORLEVEL%
echo アカウントは無効になっています。有効化します。
net user %UsrID% /active:yes
echo 以下のように変更しました。
net user %UsrID%
goto end

:Confirmation
echo "ERRORLEVELは"%ERRORLEVEL%
echo 再度条件を変えて動作確認
net user %UsrID% | find "アカウント有効" | find "Yes"
echo "ERRORLEVELは"%ERRORLEVEL%
echo なので、アカウントは有効になっています。
if %ERRORLEVEL% == 0 goto end
if %ERRORLEVEL% == 1 goto exception
echo なにもせずに終了。
goto end

:exception
rem echo "net user"コマンドの実行結果が予期せぬ出力を出しているため、コマンド実行結果を出力して終了します。
rem net user %UsrID%>>%COMPUTERNAME%_%DATE:/=%.txt
goto end

:end
set UsrID=
echo 処理を終了します。
--------------------------------------------------------------

まず、setコマンドで変数UsrIDに「Administrator」を入れておきます。これでAdministrator以外のユーザを処理の対象にしたい場合には、このset行のユーザ文字列を書き直すだけで、別ユーザを処理対象にすることができます。後で再利用する時に便利。

最初に「アカウント有効=No」の表示を探して、無効化されていれば、「net user %UsrID% /active:yes」のコマンドで有効化して処理を完了します。(ラベル「:AccountActive」の箇所の処理)

アカウントがYesならラベル「:Confirmation」の箇所の処理で再度「アカウント有効=Yes」となることを確認して、何もせずに終了させています。

まず、このようなことはないのですが、どっちにも当てはまらなかった場合、ラベル「:exception」にジャンプするようにしました。rem文でコメントアウトしていますが、「net user %UsrID%」の出力結果を「コンピュータ名_日付.txt」の書式でカレントディレクトリに保存する命令を用意しました。この出力結果を見れば最終的にはどっちにも引っ掛からなかった処理の原因が掴めるかなと。(※重ねて言えば、remでコメントアウトしていますが)

バッチファイル(本番用)

単純なバッチファイルなので、確認用のecho行やrem文を消してすっきりさせたのが、このバッチファイルです。これを使います。
※ただし、実行は「管理者:コマンドプロンプト」で実行する必要があります。net userコマンド実行には管理者権限が必要なのは同じです。

--------------------------------------------------------------
<AdmActive-ss.bat>サイレントrem行全消し版
--------------------------------------------------------------
@echo off

set UsrID=Administrator

net user %UsrID% | find "アカウント有効" | find "No"
if %ERRORLEVEL% == 0 goto AccountActive
if %ERRORLEVEL% == 1 goto Confirmation

:AccountActive
net user %UsrID% /active:yes
goto end

:Confirmation
net user %UsrID% | find "アカウント有効" | find "Yes"
if %ERRORLEVEL% == 0 goto end
if %ERRORLEVEL% == 1 goto exception
goto end

:exception
rem echo "net user"コマンドの実行結果が予期せぬ出力を出しているため、コマンド実行結果を出力して終了します。
rem net user %UsrID%>>%COMPUTERNAME%_%DATE:/=%.txt
goto end

:end
set UsrID=
rem echo 処理を終了します。
--------------------------------------------------------------

判定行で処理をするかどうか振り分けて、何もしないほうも判定だけしてバッチファイルを終了させます。
最終的に、どっちにも当てはまらなかった場合のrem文だけ残しておきました。

実行方法

これを権限代行が可能なソリューションを利用してネットワーク内のPCに展開します。
サードパーティー製のソリューションを使ってもいいですし、Active Directory環境ならグループポリシーで展開(その際はLocal SYSTEM権限を使うことになるはず)しても上手くいくと思います。たぶん。