MR2オーナー吉田貴幸のブログ

MR2(SW20)オーナー吉田貴幸のブログ。仕事はITインフラエンジニア。愛車の記事とIT関連の情報を発信しています

【Windows】[VBScript] WQL (WMI Query Language) は ODRY BY が使えない。ADOを使って解決しましょう。

 

はじめに

VBScriptから、WQL (WMI Query Language) を使用した際、結果の並び順をソートしたいので、SQL分に 'oder by' をつけて実行すると、エラーになってしまいます。
なんと、WQLでは'oder by'がサポートされていないんです。
結果を並び替えるこなんて普通にあると思うのですが、すごく使いずらい。

そこで、ADO(ActiveX Data Objects)を使用したソートのサンプルを掲載します。

また、フィルターのサンプルも掲載します。
WQLで'WHERE'条件を指定せず、あとからADOでフィルターすることが出来るので、if文を多用したり、再度WQLを実行せず条件抽出が可能です。

  • WQLで使用できるキーワードはこちら

docs.microsoft.com

 

ADOを使用して、WQLの結果をソートする

拡張子に「.vbs」つけて下記のコードを保存してください。
使い方は、ソースにコメントを記載しているので、そちらを参照してください。

'//変数宣言
Option Explicit

Dim oClassSet
Dim oClass
Dim oLocator
Dim oService
Dim sMesStr
Dim oDataset

'////////////////////////////////////////////////////////////////////////////
'//WQLサンプルコード
'//こちらのサイトを使用させていただきました → http://www.wmifun.net/sample/win32_useraccount.html

'ローカルコンピュータに接続する。
Set oLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set oService = oLocator.ConnectServer
'クエリー条件を WQL にて指定する。
Set oClassSet = oService.ExecQuery("Select * From Win32_UserAccount")

'////////////////////////////////////////////////////////////////////////////
'//ここからがADOを使用したソートのサンプルです
'//ADOのプロパティ '//https://docs.microsoft.com/ja-jp/sql/ado/reference/ado-api/ado-properties?view=sql-server-2017 '//DataTypeEnum '//https://docs.microsoft.com/ja-jp/sql/ado/reference/ado-api/datatypeenum?view=sql-server-2017 '//ADO定数 const adVarChar = 200
'//結果を保存するためのテーブルに、項目名、データ型を設定します '//項目名は英字のみです Set oDataset = CreateObject("ADOR.Recordset") oDataset.Fields.Append "Name",adVarChar,255 oDataset.Fields.Append "SID",adVarChar,255 oDataset.Open '//テーブルにWQL結果データをテーブルに格納 For Each oClass In oClassSet oDataset.AddNew oDataset("Name") = oClass.Name oDataset("SID") = oClass.SID oDataset.Update Next '//データの並び替え '//Sort プロパティ (ADO) '//https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/sort-property-ado '//項目名 ASC | DESC '//SIDを降順で並び替える場合
oDataset.Sort = "SID DESC" '//データの抽出のサンプルです。これはソートとは関係ないので省略可です。 '//Filter プロパティ (ADO) '//https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/filter-property-ado '//フィルターを解除するにはクリアする '//oDataset.Filter = ""
'//名前をワイルドカードでフィルターする場合
oDataset.Filter = "Name like 'a%'" '//結果出力
'//並び替えは終わっているので最初からレコードを取得すればOKです。
oDataset.MoveFirst Do Until oDataset.EOF WScript.Echo oDataset.Fields.Item("Name") & vbTab & _ oDataset.Fields.Item("SID") oDataset.MoveNext Loop oDataset.close '///////////////////////////////////////////////////////////////////////////// '使用した各種オブジェクトを後片付けする。 Set oClassSet = Nothing Set oClass = Nothing Set oService = Nothing Set oLocator = Nothing Set oDataset = Nothing

 

参考記事

サンプルコードの一部は、こちらのサイトから引用させていただきました。

www.wmifun.net


 

【Windows】[VBScript] CDO(Collaboration Data Objects)でメールを送信する

 

はじめに

CDO.Messageを使用して、VBScriptでメール送信を行う方法です。Windows標準機能のみでメールを送信できるので、OS環境に依存せず使用することが出来ます。

※メール送信に使用するSMTPサーバーは別途必要になります。

 

VBScriptでメールを送信する

  • mailsend.vbs
Set oMessage = CreateObject("CDO.Message")

'//差出人 oMessage.From = "username@test.com" '//宛先 複数の場合はセミコロンで区切る
oMessage.To = "username@test.com"
oMessage.CC = "username@test.com"
oMessage.BCC = "username@test.com"
'//添付ファイル
oMessage.AddAttachment = "添付するファイルをフルパスで指定"
'///件名
oMessage.Subject = "テストメールです" '//本文(テキスト形式)
oMessage.TextBody = "テストメールです。"& vbCRLF & "改行は vbCRLFを使用します"
'//メール送信設定
'//1:ローカルSMTPサービスのピックアップ・ディレクトリにメールを配置する(デフォルトの動作)
'//2:SMTPポートに接続して送信する
'//3:OLE DBを利用してローカルのExchangeに接続する oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 '//SMTPサーバー名
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtpservername"
'//ポート番号
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
'//設定更新
oMessage.Configuration.Fields.Update

'//メールヘッダーの設定

'//設定は省略可能です。
'//メーラー
oMessage.Fields("urn:schemas:mailheader:X-Mailer") = "vbscript mail"
'//重要度
oMessage.objMail.Fields("urn:schemas:mailheader:Importance") = "High"
oMessage.objMail.Fields("urn:schemas:mailheader:Priority") = 1
oMessage.Fields("urn:schemas:mailheader:X-Priority") = 1
oMessage.Fields("urn:schemas:mailheader:X-MsMail-Priority") = "High"
oMessage.Fields.update

'//メール送信実行
oMessage.Send Set oMessage = Nothing

その他設定

添付ファイル

  • 添付ファイルは以下を追加する

'//添付ファイル
oMessage.AddAttachment "C:\Scripts\Output.txt"

 

HTML形式

  • メールをHTML形式で作成する場合は、oMessage.TextBody の部分をoMessage.HTMLBody にしてHTML形式で記載する
  • 暗号化通信(SSL)を使用する場合は、メール送信設定に以下を追加する
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl")  = True or Flase

 

SMTPサーバー認証

  • SMTPサーバー認証は、メール送信設定に以下を追加する
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1(Basic認証) or 2(NTLM認証)
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "ユーザー名"
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "パスワード"
oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 180

 

 

参考記事

gallery.technet.microsoft.com

 

www.atmarkit.co.jp

 

【SCCM】[VBScript] [WMI] デバイスのオンライン状態を取得する | Microsoft System Center Configuration Manager(SCCM)

f:id:takayuki-yoshida:20190421222641p:plain

 

はじめに

SCCMのSMS_CollectionMemberClientBaselineStatusクラスを使用して、デバイスのオンライン状態をVBScriptから取得します。

 

以下の記事で使用している「Connect」Functionプロシージャを使用する前提で記載します。

www.startpassion.life

デバイスコレクション内のデバイスのオンライン状態を取得する 

  • 実行行方法

set Connection = Connect("サーバー名","ユーザー名"."パスワード")
call SCCM_CollectionMemberClientBaselineStatus_Query(connection,CollectionID)

 

Sub SCCM_CollectionMemberClientBaselineStatus_Query(connection,CollectionID)

'Query WMI for SMS_CollectionMemberClientBaselineStatus
'baselinetype 1:実稼働 2:実稼働前
Set oResults = connection.ExecQuery("Select * from SMS_CollectionMemberClientBaselineStatus Where CollectionID='" & CollectionID &"' and baselinetype=1")

For Each oResourceID In oResults
Wscript.echo oResouceID.ResourceID & "," & oResouceID.Name & "," & oResouceID.CNIsOnline
Next

if err.number<>0 then
Wscript.echo "取得できませんでした"
Exit Sub
End If

If oResults.count = 0 then
Wscript.echo "クエリ結果は0件です"
End If

End Sub

 

 このスクリプトでは、SCCM Configration Manager コンソールのデバイスに表示されるアイコンと同じ状態になります

クライアントのオンライン状態アイコン デバイスはオンラインです
クライアントのオフライン状態アイコン デバイスはオフラインです
クライアントの不明な状態アイコン オンライン状態は不明です
クライアントがインストールされていない デバイスにクライアントがインストールされていません

 

参考記事

docs.microsoft.com

 

【SCCM】[VBScript] [WMI] 対象のコンピュータのパッチ適用状況を取得する | Microsoft System Center Configuration Manager(SCCM)

f:id:takayuki-yoshida:20190421222641p:plain

 

はじめに

SCCMのQUICK_FIX_ENGINEERINGクラスを使用して、パッチ適用状況をVBScriptから取得します。

事前にクライアント規則のハードウェアでQUICK_FIX_ENGINEERINGクラスを取得するように設定してください。

以下の2つの記事で使用している「Connect」Functionプロシージャ、「FindResourceID」プロシージャを使用する前提で記載します。

www.startpassion.life

www.startpassion.life

 

デバイス名(コンピュータ名)からパッチ適用状況を取得する 

  • 実行行方法

set Connection = Connect("サーバー名","ユーザー名"."パスワード")
ResourceID = FindResourceID('対象のコンピュータ名')
call SCCM_QFE_Query(connection,ResourceID)

 

Sub SCCM_QFE_Query(connection,ResourceID)

'Query WMI for QFE
Set oResults = connection.ExecQuery("Select * from SMS_G_System_QUICK_FIX_ENGINEERING Where SMS_G_System_QUICK_FIX_ENGINEERING.ResourceID='" & ResourceID &"')

For Each oResourceID In oResults
Wscript.echo oResouceID.ResourceID & "," & oResouceID.HotFixID & "," & oResouceID.InstallDate
Next

if err.number<>0 then
Wscript.echo "取得できませんでした"
Exit Sub
End If

If oResults.count = 0 then
Wscript.echo "クエリ結果は0件です"
End If

End Sub

 

 

【SCCM】[VBScript] [WMI] デバイス名(コンピュータ名)からResourceIDを取得する | Microsoft System Center Configuration Manager(SCCM)

f:id:takayuki-yoshida:20190421222641p:plain

 

はじめに

SCCMでデバイスのResourceIDをコンピュータ名から取得するFunctionプロシージャですです。

こちらの記事のSCCM接続のFunctionプロシージャを使用する前提で記載します。

www.startpassion.life

 

デバイス名(コンピュータ名)からResourceIDを取得する 

  • 実行行方法

VBScript内でSCCM接続のFunctionプロシジャーを含めてください。

set Connection = Connect("サーバー名","ユーザー名"."パスワード")
SCCM_ResourceID = FindResourceID(Connection,DeviceName)

 

Sub FindResourceID(Connection,DeviceName)

'Query WMI for find ResourceID from netBiosName
Set oResults = connection.ExecQuery("Select * from SMS_R_System Where Name = '" & DeviceName & "')

End Sub

 

 

【SCCM】[VBScript] [WMI] ダイレクト規則のデバイスコレクションにデバイスを追加・削除する | Microsoft System Center Configuration Manager(SCCM)

f:id:takayuki-yoshida:20190421222641p:plain

 

はじめに

SCCMでデバイスコレクションのメンバー追加、削除するサブルーチンです。

こちらの記事のSCCM接続のFunctionプロシージャを使用する前提で記載します。

www.startpassion.life

 

デバイスコレクション(ダイレクト規則)にメンバーを追加する

ダイレクト規則のデバイスコレクションのメンバーに、デバイスを追加します。ResourceIDは、SCCMでデバイスを一意を表すIDです。事前に取得している前提です。

コレクションIDは事前にSCCM管理コンソールから調べておいてください。

※デバイスコレクションに追加するデバイスがいないことを事前に確認してください。重複した場合は、無効状態で登録されてしまうようです。

 

  • 実行行方法

VBScript内でSCCM接続のFunctionプロシジャーを含めてください。

set Connection = Connect("サーバー名","ユーザー名"."パスワード")
call DeviceCollection_AddComputer(Connection,ResourceID,collectionID)

 

Sub DeviceCollection_AddComputer(Connection,ResourceID,collectionID)

Dim collection
Dim collectionRule

Set collection = connection.Get("SMS_Collection.CollectionID='" & collectionID & "'")
Set collectionRule = connection.Get("SMS_CollectionRuleDirect").SpawnInstance_
collectionRule.ResourceClassName="SMS_R_System"
collectionRule.ResourceID=ResourceID

'Add CollectionMember
collection.AddMembershipRule collectionRule

End Sub

 

デバイスコレクション(ダイレクト規則)にメンバーから削除する

ダイレクト規則のデバイスコレクションのメンバーからデバイスを削除します。

サンプルスクリプトは追加する場合とほぼ同じで、削除する際に使用するメゾットが違う程度です。

事前に削除するデバイスのResourceIDを取得している前提です。

また、コレクションIDは事前にSCCM管理コンソールから調べておいてください。

 

  • 実行方法

VBScript内でSCCM接続のFunctionプロシジャーを含めてください。

set connection = Connect("サーバー名","ユーザー名"."パスワード")
call DeviceCollection_DeleteComputer(connection,ResourceID,collectionID)

 

Sub DeviceCollection_DeleteComputer(connection,ResourceID,collectionID)

Dim collection
Dim collectionRule

Set collection = connection.Get("SMS_Collection.CollectionID='" & collectionID & "'")
Set collectionRule = connection.Get("SMS_CollectionRuleDirect").SpawnInstance_
collectionRule.ResourceClassName="SMS_R_System"
collectionRule.ResourceID=ResourceID

'Delete CollectionMember
collection.DeleteMembershipRule collectionRule

End Sub

参考)

devblogs.microsoft.com

 

 

【SCCM】[VBScript] [WMI] デバイスコレクションのメンバーを取得する | Microsoft System Center Configuration Manager(SCCM)

f:id:takayuki-yoshida:20190421222641p:plain

 

はじめに 

Microsoft System Center Configuration Manager(SCCM) は、WMI(Windows Management Instrumentation)から操作ができます。特にデバイスコレクションでダイレクト規則のメンバーを、PowerShell、VBScriptから一括登録・削除できると作業を省力化できますし、大規模環境でのSCCM管理者は必要になると思います。

また、ワークフローシステムと組み合わせて、アプリケーション配信を自動化するなどで運用自動化にも応用できると思います。

ここではVBScriptから操作する方法を記載します。

 

SCCMサーバーへ接続する

ここではSCCMサーバーへ接続するためのFunctionプロシージャのみです。実際の操作時にプロシージャをコールして使用します。

Function Connect(server, userName, userPassword) 
On Error Resume Next
Dim net Dim localConnection Dim swbemLocator Dim swbemServices Dim providerLoc Dim location
Set swbemLocator = CreateObject("WbemScripting.SWbemLocator") swbemLocator.Security_.AuthenticationLevel = 6 'Packet Privacy. ' If the server is local, do not supply credentials. Set net = CreateObject("WScript.NetWork") If UCase(net.ComputerName) = UCase(server) Then  localConnection = true userName = "" userPassword = "" server = "." End If
' Connect to the server. Set swbemServices= swbemLocator.ConnectServer _ (server, "root\sms",userName,userPassword) If Err.Number<>0 Then Wscript.Echo "Couldn't connect: " + Err.Description Connect = null Exit Function End If
' Determine where the provider is and connect. Set providerLoc = swbemServices.InstancesOf("SMS_ProviderLocation") For Each location In providerLoc If location.ProviderForLocalSite = True Then Set swbemServices = swbemLocator.ConnectServer _ (location.Machine, "root\sms\site_" + _ location.SiteCode,userName,userPassword) If Err.Number<>0 Then Wscript.Echo "Couldn't connect:" + Err.Description Connect = Null Exit Function End If Set Connect = swbemServices Exit Function End If Next Set Connect = null ' Failed to connect. End Function

参考)

 

デバイスコレクションのメンバーを取得する

デバイスコレクションのメンバーを取得するサンプルスクリプトです。MSページでは3種類のクエリ方法が記載されていますが、このサンプルでは1番目のみ記載しています。(基本的には1番目で動作します)

SCCMでは、デバイスが「ResourceID」で管理されていますので、ResoueceIDとデバイス名を出力するようにしています。

なお、コレクションIDは事前にSCCM管理コンソールから調べておいてください。

  • 実行方法

VBScript内で前述の接続Functionプロシジャーを含めてください。

set connection = Connect("サーバー名","ユーザー名"."パスワード")
call EnumerateCollectionMembers(connection,"コレクションID(例)SMS00001")

 

Sub EnumerateCollectionMembers(connection,strCollectionID)
Const wbemFlagReturnImmediately = 16
Const wbemFlagForwardOnly = 32 ' Set required variables. ' Note: Values must be manually added to the queries below. Dim Query1
Dim ListOfResources1
Dim Resource1
' The following example shows how to enumerate the members of the All Systems collection. Query1 = "SELECT ResourceID FROM SMS_FullCollectionMembership WHERE CollectionID = '" & strCollectionID &"'" ' Run query. Set ListOfResources1 = connection.ExecQuery(Query1, , wbemFlagForwardOnly Or wbemFlagReturnImmediately) ' The query returns a collection that needs to be enumerated. Wscript.Echo " " Wscript.Echo "Query: " & Query1 For Each Resource1 In ListOfResources1 'ResourceID,name
Wscript.Echo Resource1.ResourceID & "," & Resource1.name Next End Sub

 参考)