PowerShellを使って、ADユーザーをローカルグループから削除する
リモートデスクトップで仮想サーバに接続させてアプリを使ってもらおう、第三弾
Remote Desttop Usersに追加すれば、サーバに乗っているアプリを使用することはできます。
ところが、ライセンス管理上ユーザがいつからいつまで利用したかの履歴を取りたいとのこと。
GUIを使うと、ログが残りません。Active Directory UserはあくまでADサーバーで管理しているので、ADドメインにログオンした履歴くらいしか残らないようです。さて、どうするか…
しょうがないので、スクリプトでLocal Groupに追加してスクリプトの中でLogを吐き出すことにしました。
VBやC#を使えばできるんじゃないの、と言われましたけど多分自分しか使わないものをプログラム化しなくてもと思いPowerShellでスクリプト化。
PowerShellを使って、ADユーザーをローカルグループに追加する
まずは、ユーザーを追加するところから。これは検索すればすぐに出てきます。
ADユーザーをローカルグループに追加する ーMicrosoft Script解説ブログ
1 2 3 4 5 6 7 8 9 10 11 12 |
$hostname = HOSTNAME #対象のサーバ名 $groupname ="Remote Desktop Users" #対象のグループ名 $group = [ADSI]("WinNT://$hostname/$groupname") #[ADSI]オブジェクトとして、対象グループオブジェクトを作成 #追加したいユーザを管理しているADの名前 $ADname = "ad01.local" #追加したいユーザ $argsはスクリプトの引数が入ります。 $User = [ADSI]("WinNT://$ADname/$args") $group.PSBase.Invoke("Add",$user.PSBase.Path) #groupに追加 |
…ここまでは出来たけど、削除コマンドが検索しても出てこない…
PSBaseオブジェクトで調べてもADSIオブジェクトを調べても出てこない。
PSBaseオブジェクトのInvokeメソッドを呼び出して、”Add”パラメータを指定して実行、と解説されているんですが、パラメータ一覧が見当たらない。
(Invoke自体は、呼び出し位の意味の英単語)
.netFrameworkのオブジェクトを呼び出しているだけ、というのは分かるんですが.netFrameworkを調べ始めても埒あかないし。
探しているうちに素敵なページがヒットしました。
こちらのサイトではLocalGroupオブジェクトにRemoveメソッドを使っていました。「Removeメソッドなんだ」ということで、おなじ文法に違いないと下記に変更
1 |
$group.PSBase.Invoke("Remove",$user.PSBase.Path) #group削除 |
できたヽ(^。^)ノ
ログを追記する。
1 2 3 4 5 6 7 8 9 |
$mode ="Add" "追加モードを指定" $history = New-Object System.Collections.ArrayList #履歴用のオブジェクトを追加 $group.PSBase.Invoke($mode,$user.PSBase.Path) $history.add( $Date+","+$hostname+","+$mode+","+$groupname+","+$user.name+","""+$user.FullName+"`"" $history >> "C:\log\hogehoge.csv" #履歴をファイルに追記 |
最初はhistoryオブジェクトに各項目をAddしてExport-CSVを使おうとしたんですが、上手く吐き出されないので断念
エラー制御を入れる。
groupに追加/削除しようとした時、ちゃんとチェックしてエラーを返してくれます。例えば:
- 既にユーザがグループに居る場合
1 2 3 4 5 6 7 |
"2" 個の引数を指定して "Invoke" を呼び出し中に例外が発生しました: "指定されたアカウント名は既にグループのメンバーです。 " 発生場所 C:\script\AddUser.ps1:24 文字:9 + $group.PSBase.Invoke($mode,$user.PSBase.Path) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodTargetInvocation |
- ユーザ名が間違っている場合
1 2 3 4 5 6 7 |
"2" 個の引数を指定して "Invoke" を呼び出し中に例外が発生しました: "このメンバーは存在しないため、ローカル グループに追加したり、ローカル グループから削除したりすることができませんでした。 " 発生場所 C:\script\AddUser.ps1:24 文字:9 + $group.PSBase.Invoke($mode,$user.PSBase.Path) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodTargetInvocation |
エラー自体は読めばわかるので、追加が成功した時にだけログを吐いてほしい。
またエラー自体は、ちゃんと画面に出してほしい。
ということで、エラーハンドリングを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
" $returnCode = 0 try{ $group.PSBase.Invoke($mode,$user.PSBase.Path) }catch{ $returnCode = 1 $error[0] }finally{ #登録に成功したら、ログを出力する if($returnCode -eq 0){ $history.add( $Date+","+$hostname+","+$mode+","+$groupname+","+$user.name+","""+$user.FullName+"`"" ) } } } |
これをコマンドラインから実行して、ログを吐いていけば管理台帳を手で記載しなくていいはず!
ここまでやったら「ユーザに自分で登録させられない?」って言われました。
管理者権限が要るので、そのままではできません。
Webで申請させてWeb上にリストorデータベース作ってそれを元に管理者権限でバッチ処理を定期的に走らせる、とかですかねぇ…。ちょっと難易度があがるのでまた次の機会に。