chkconfig.js ― 2008年06月15日 06時19分04秒
またくだらんモノ作ったなぁ
くだらんと思いつつも、chkconfig風にWindowsサービスの起動方法を確認したり変更したりするユーティリティスクリプト作ってみました。
いや、前回のservice.cmdの引数に渡す「サービス名」を確認するのが主な目的だったんだけど、起動方法の変更とかもなんとなくできそうだったのでやってみたらできたってことで。ソース
こんな感じ。例によってNYSLで。ダウンロードはこちらから。
var fso = new ActiveXObject("Scripting.FileSystemObject"); var shell = new ActiveXObject("WScript.Shell"); // コマンドライン引数の取得 var args = new function() { var args = WSH.Arguments, result = []; for(var col = new Enumerator( args ); ! col.atEnd(); col.moveNext()) { result[ result.length ] = String( col.item() ); } var named = {}; for(var col = new Enumerator( args.Named ); ! col.atEnd(); col.moveNext()) { named[ String( col.item() ) ] = String( args.Named.Item( col.item() ) ); } var unnamed = []; for(var col = new Enumerator( args.Unnamed ); ! col.atEnd(); col.moveNext()) { unnamed[ unnamed.length ] = String( col.item() ); } result.named = named; result.unnamed = unnamed; result.toArray = function() { var result = []; for(var i = 0, l = this.length; i < l; i++) { result[ i ] = /((^".*"$)|(^'.*'$))/.test( this[i] ) ? this[i] : [ '"', this[i], '"' ].join(""); } return result; }; result.toString = function() { return this.toArray().join(" "); }; return result; }(); // cscriptで強制起動 if( /wscript\.exe$/i.test( WSH.FullName ) ) { shell.Run( [ "cscript", /((^".*"$)|(^'.*'$))/.test( WSH.ScriptFullName ) ? WSH.ScriptFullName : [ '"', WSH.ScriptFullName, '"' ].join(""), args ].join(" ") ); WSH.Quit(); } // ユーティリティ関数定義 var echo = function(s) { print( [ s, "\n" ].join("") ); } var print = function(s) { WSH.StdOut.Write( s || "" ); } var input = function() { if( arguments[0] ) print( arguments[0] ); print( ">" ); return WSH.StdIn.ReadLine(); } Error.prototype.toString = function() { return this.description || this.message || this.number || this; }; var $break = {}; var $continue = {}; Enumerator.prototype.each = function(iterator) { try { var i = 0; for(this.moveFirst(); ! this.atEnd(); this.moveNext()) { try { iterator( this.item(), i++ ); } catch(e) { if( e != $continue ) throw e; } } } catch(e) { if( e != $break ) throw e; } }; String.prototype.repeat = function(count) { var buf = []; for(var i = 0; i < count; i++) buf[buf.length] = this; return buf.join(""); }; var SvcMgr = function() { this.wmi = new ActiveXObject("WbemScripting.SWbemLocator").ConnectServer(); }; SvcMgr.prototype = { list : function(name) { var query = "SELECT Name, DisplayName, Description, StartMode, State FROM Win32_Service"; if( name ) query += " WHERE Name = '" + name + "'"; return new Enumerator( this.wmi.ExecQuery( query ) ); }, change : function(name, value) { this.list(name).each( function(service) { service.ChangeStartMode( value ); throw $break; } ); }, exec : function(params) { if( params[0] && params[0].toLowerCase() == "--list" ) { // --list var max = 39; this.list( params[1] || false ).each( function(service) { echo( [ service.Name.length < max ? ( service.Name + " ".repeat(max) ).substr(0, max) : service.Name, service.StartMode ].join(" ") ); } ); } else if( params[0] && params[0].toLowerCase() == "--detail" && params[1] ) { // --detail this.list( params[1] ).each( function(service) { echo( "サービス名 : " + service.Name ); echo( "表示名 : " + service.DisplayName ); echo( "スタートアップの種類 : " + ( { "Boot" : "ブート", "System" : "システム", "Auto" : "自動", "Manual" : "手動", "Disabled" : "無効" }[ service.StartMode ] || service.StartMode ) ); echo( "状態 : " + ( { "Running" : "実行中", "Stopped" : "停止中" }[ service.State ] || service.State ) ); echo( "説明 : " ); echo( " " + ( service.Description || "(no description)" ) ); echo( "" ); throw $break; } ); } else if( params[0] && ! /^--/.test(params[0]) && params[1] ) { // change startmode var mode = { "auto" : "automatic", "sys" : "system", "man" : "manual", "dis" : "disabled" }[ params[1] ] || params[1]; this.change(params[0], mode); this.exec( [ "--list", params[0] ] ); } else { echo( "使い方 : [cscript | wscript] chkconfig.js --list [サービス名]" ); echo( " [cscript | wscript] chkconfig.js --detail サービス名" ); echo( " [cscript | wscript] chkconfig.js サービス名 [ Boot |" ); echo( " System |" ); echo( " Automatic |" ); echo( " Manual |" ); echo( " Disabled ]" ); echo(); } } }; new SvcMgr().exec( args.unnamed );これをcscript経由で起動するバッチファイルを%SystemRoot%にでも入れておけばよいかと。
使い方
そのまま起動すると使い方は表示されるのでだいたいわかると思いますが、以下の3種類の引数を受け付けます。
- --list [サービス名]
- <サービス名> <起動方法>
- --detail <サービス名>
--list [サービス名]
「--list」はサービスの起動方法を確認します。こんな感じ。
C:\Documents and Settings\dara-j>cscript chkconfig.js --list AcPrfMgrSvc Auto AcSvc Disabled Alerter Disabled ALG Disabled AppMgmt Manual aspnet_state Manual AudioSrv Auto : (中略) : WudfSvc Manual WZCSVC Auto xmlprov Manual C:\Documents and Settings\dara-j>各行はサービス名と起動方法が出力されます。
ここに表示されるサービス名は管理ツールの「サービス」で表示される「表示名」ではなく、内部のサービス名で、前回のservice.cmdに(というか、net startやnet stopに)渡すサービス名はこれになります。
--listの後ろにサービス名をつけると、そのサービスの情報のみが表示されます。
C:\Documents and Settings\dara-j>cscript chkconfig.js --list iisadmin IISADMIN Auto C:\Documents and Settings\dara-j>また、パイプでfindstrにつないでもいいかもしれません。
C:\Documents and Settings\dara-j>cscript chkconfig.js --list | findstr -i vnc winvnc Auto C:\Documents and Settings\dara-j>findstrは-i(Ignore Case)がよいでしょう。サービス名うろ覚え時にぜひ。
<サービス名> <起動方法>
サービスの起動方法を変更します。Linuxのようなランレベルの概念はないため、--level <levels>のようなパラメータは必要なく、on/off/resetの代わりに「Boot」「System」「Automatic」「Manual」「Disabled」の5種類の指定が可能です(が、「Boot」と「System」はよくわかりません。指定しても反映されてるやらされてないやら)。
実行すると、設定反映後の状態を出力します。
C:\Documents and Settings\dara-j>cscript chkconfig.js w3svc disabled W3SVC Disabled C:\Documents and Settings\dara-j>cscript chkconfig.js w3svc automatic W3SVC Auto C:\Documents and Settings\dara-j>ちなみに大文字小文字は区別されません。
--detail <サービス名>
これは本家chkconfigには相当する機能はないのですが、オマケで実装してみました。指定サービスの詳細を表示します。
C:\Documents and Settings\dara-j>cscript chkconfig.js --detail iisadmin サービス名 : IISADMIN 表示名 : IIS Admin スタートアップの種類 : 自動 状態 : 実行中 説明 : インターネット インフォメーション サービスのスナップインを使用した Web と FTP サービスの管理を提供します。 Enter キーで終了します> C:\Documents and Settings\dara-j>
ちょっとした解説
たいしたことはしてないのですが、WMIでWin32_Serviceクラスを扱っています。サービスの列挙は
SELECT * FROM Win32_Serviceってのが基本で(実際は取得するプロパティを限定してますが)、WHERE句でサービスを限定したり、返ってきたインスタンスに対してChangeStartModeメソッドを実行して起動方法を変えたりしています。
参考リンク
最近のコメント