推定無題

日々調べたこととか

VBScript: Windowsのシャットダウン、リブート

幾通りか方法がある。

  • WMIを使う、成否を取得可能
  • Shutdownコマンドを使う
  • Xpepmコマンドを使う(XPeのみ)

WMIを使う方法

元ネタは「WMIを使用してスクリプトの幅を広げる(044~050)」から。

Dim ws, w
Set ws = GetObject("winmgmts:{(Shutdown)}//./root/cimv2").ExecQuery("Select * from Win32_OperatingSystem where Primary=true")
For Each w in ws
    w.Shutdown()
    ' w.Reboot()にすれば再起動になる
    ' 戻値が0なら成功、0以外は失敗
Next

Win32Shutdownを使えば、ログアウト、強制オプションも付けれる、試してないけど。

Win32ShutdownTrackerならタイムアウト設定も可能だが、サポートはVista以降。

Shutdownコマンドを使う

コマンドの詳細は下記が詳しい。
@IT::コマンドラインから電源オフや休止を実行する

Dim ws
Set ws = WScript.CreateObject("WScript.Shell")
ws.Run "%WINDIR%\system32\shutdown.exe -s -t 00", 0
' -s を -r にすれば再起動。
' -t はタイムアウト(秒)

タイムアウトを設定した場合、警告ダイアログが表示される。
-c オプションで、警告ダイアログにメッセージも表示できる。

Xpepmコマンドを使う

Windows Embedded Standard 2009で、Power Managemet Applicationコンポーネントを追加した時のみ使用可能。

XPePM [-Shutdown | -Restart | -Standby | -Hibernate | /?]

シャットダウン、リブート以外に、スタンバイとハイバネートも出来る。

Shutdownコマンドと同様にwscript.shell runを使って呼び出す。

' 成否を返す
' コマンドが無い場合はFalseを返す
Function Shutdown()
    Dim ws
    Set ws = WScript.CreateObject("WScript.Shell")
    On Error Resume Next
    ws.Run "%WINDIR%\system32\xpepm -Shutdown", 0
    If Err.Number = 0 Then
        Shutdown= True
    Else 
        Shutdown= False
    End If  
End Function

VBScript: WMIを使ったサービスの状態取得、開始、停止

WMIを使ってサービスのオブジェクトを取得する。
クエリはサービス名と一致するものを指定。表示にする時は、DisplayName= にする。

Dim Services
Set Services = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service Where Name='サービス名'")

上記を踏まえて、サービスの状態取得、開始、停止するFunctionプロシージャ。

' WMI, Win32_Serviceのヘルパを提供



' サービスの状態を返す
'   サービス名で検索し、取得できなければ表示名で検索し、最初に見つかったサービスの状態を返す
'   停止:Stopped
'   開始:Running
'   サービスが見つからない:(Empty)
Function GetServiceState(strServiceName)
    Dim Services, Service
    Set Services = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service Where Name='" & strServiceName & "'")
    If Services.Count = 0 Then
        Set Services = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service Where DisplayName='" & StrServiceName & "'")
    End If
   
    For Each Service in Services
        GetServiceState = Service.State
        Exit For
    Next
End Function


' 指定されたサービスを開始し、結果を返す
'   サービス名で検索し、取得できなければ表示名で検索し、最初に見つかったサービスを開始する
Function StartService(strServiceName)
    Dim Services, Service
    Set Services = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service Where Name='" & strServiceName & "'")
    If Services.Count = 0 Then
        Set Services = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service Where DisplayName='" & StrServiceName & "'")
    End If
    
    StartService = False
    Dim RetVal
    For Each Service in Services
        RetVal = Service.StartService()
        If RetVal = 0 Then StartService = True  ' Started
        If RetVal = 10 Then StartService = True ' Running
        Exit For
    Next
End Function


' 指定されたサービスを停止し、結果を返す
'   サービス名で検索し、取得できなければ表示名で検索し、見つかった最初のサービスを停止する
Function StopService(strServiceName)  
    Dim Services, Service
    Set Services = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service Where Name='" & strServiceName & "'")
    If Services.Count = 0 Then
        Set Services = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service Where DisplayName='" & StrServiceName & "'")
    End If
    
    StopService = False
    Dim RetVal
    For Each Service in Services
        RetVal = Service.StopService()
        If RetVal = 0 Then StopService = True  ' Stopped
        If RetVal = 5 Then StopService = True  ' Already Stopped
        Exit For
    Next
End Function

' WMI::StartService, StopServiceの戻値は下記参照。
'	http://www.wmifun.net/library/win32_service.html
'	3 - 実行中のほかのサービスが依存しているので停止できません。


'====================
'Test

'MsgBox GetServiceState("Telephony")    ' 表示名
'MsgBox GetServiceState("TapiSrv")    ' サービス名
'MsgBox GetServiceState("Alerter")
'StopService("Security Center")
'StopService("Security Center")


WMI Libraryについては下記が詳しいです。

WMI::StartService, StopServiceの戻値はだいたい以下の感じ。

0 - 要求が受け入れられました。
1 - 要求がサポートされない。
2 - ユーザーに必要なアクセスがありません。
3 - そのサービスは、実行中のほかのサービスが依存しているので停止できません。
4 - 要求された制御コードは有効でないか、またはサービスを受け入れ可能ではありません。
5 - サービスの状態 (Win32_BaseService:State) が 0、1、または 2 と等しいので、要求された制御コードはサービスに送信されませんでした。
6 - サービスは開始されていません。
7 - サービスは適切な時間内に開始要求に応答しませんでした。
8 - サービスの開始時に不明なエラーが発生しました。
9 - サービス実行可能ファイルへのディレクトリ パスが見つかりませんでした。
10 - サービスは既に実行しています。
11 - 新しいサービスを追加するデータベースはロックされています。
12 - このサービスが依存する依存関係はシステムから削除されました。
13 - サービスは依存関係のあるサービスから必要なサービスを見つけられませんでした。
14 - サービスはシステムから無効になっています。
15 - サービスにはシステムで実行するための正しい承認がありません。
16 - このサービスはシステムから削除されているところです。
17 - サービスに実行スレッドがありません。
18 - サービスの開始時に循環依存があります。
19 - 同じ名前で実行中のサービスがあります。
20 - サービスの名前に無効な文字があります。
21 - 無効なパラメーターがサービスに渡されました。
22 - このサービスが実行するアカウントは、無効か、またはサービスを実行するアクセス許可がロックされています。
23 - サービスは、システムから利用できるサービスのデータベースにあります。
24 - サービスは現在システムで一時停止されています。
その他 - 上の一覧以外の整数値については Win32 エラー コードのドキュメントを参照してください。

VBScript: Visual Studio を使って VBScript をデバッグ実行する

外部ツールに登録して、実行する事で、一行ずつステップ実行が出来る様になる。

[ツール]>[外部ツール]で登録する
タイトル:VBScriptデバッグ実行(&D)
コマンド:C:\Windows\System32\CScript.exe
引数://X $(ItemPath)

VBScript: コンピュータ名、ユーザー名の取得

Dim ws, strComputerName, strUserName

Set ws = WScript.CreateObject("WScript.Shell")

strComputerName = ws.ExpandEnvironmentStrings("%COMPUTERNAME%")
strUserName = ws.ExpandEnvironmentStrings("%USERNAME%")

WScript.Echo strComputerName
WScript.Echo strUserName

VBScript: 基本文法

下記を読めばばっちり。

VBScript 基礎文法最速マスター
http://vbscript.g.hatena.ne.jp/cx20/20100131/1264906231

忘却録

大/小文字を区別しない

Sub、Functionプロシージャの違い

  • Sub 戻値なし
  • Function 戻値あり

引数がない場合は()が必要。
引数がある場合、Callを省略すると()も省略しなければならない。

コメント

コメントは行頭に「'」か「Rem」、複数行コメントはない。

変数宣言と代入割当て

' 宣言の強制
Option Explicit

' 宣言
Dim 変数名

' 割当て
変数名 =' クラスオブジェクトの割当てにはSetが必要
Set 変数名 = クラスオブジェクト

XPe: CHKDISKを利用する

レジストリ不足で実行されない。

http://www.unidux.co.jp/embedded/faq/microsoft/000421.php

FAT/NTFS Common Format/Tools Files コンポーネントを追加した上で下記レジストリを追加します。

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager BootExecute REG_MULTI_SZ autocheck autochk *


ターゲットで

c:\>chkdsk /?
c:\>chkntfs /?

をご確認ください。


c:\>chkntfs /c c:

を実行すると次回起動時、ディスクにエラーがあればCHKDSKを実行します。
ただしNTFSの場合は電源を切っただけではエラーとなりません。
FAT32などの場合、シャットダウン処理を行わず電源を切ると次回起動時CHKDSKが実行されます。
Windows XPフラッグ画面の後実行され、終了後ようこそ画面となります。

/noguiboot を追加すると黒い画面のままChkdskが実行されるこをの回避方法として

/noguiboot /bootlogoとし
Windows¥にboot.bmp ファイルを置くことで任意画面を表示した状態で(裏で)chkdskが動作します。
起動画面は640x480ドット、16色で作成します。

逆にとらえると、上記レジストリが無ければ、エラーが起きてもチェックディスクは行われない