Hello all.

Consider the following script, used for Monitoring Entry-Level Events,
from: http://www.microsoft.com/technet/scriptcenter/guide/sas_reg_teyz.mspx?mfr=true

strComputer = "."
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
_
strComputer & "\root\default")
Set wmiSink = WScript.CreateObject("WbemScripting.SWbemSink", "SINK_")

wmiServices.ExecNotificationQueryAsync wmiSink, _
"SELECT * FROM RegistryValueChangeEvent WHERE Hive= " _
& "'HKEY_LOCAL_MACHINE' AND KeyPath= " _
& "'SOFTWARE\\Microsoft\\Windows NT\
\RegisteredOwner' AND " _
& "ValueName='CSDVersion'"
Wscript.Echo "Listening for Registry Change Events ..." & vbCrLf
Do While(1)
WScript.Sleep 1000
Loop

Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
Wscript.Echo "Received Registry Change Event" & vbCrLf & _
"------------------------------" & vbCrLf & _
wmiObject.GetObjectText_()
End Sub

I'm trying to understand how the script works. As for the the WMI Sink
Event portion, I think I have a handle on it:

(1) You instantiate a connector and a Sink:
strComputer = "."
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
_
strComputer & "\root\default")
Set wmiSink = WScript.CreateObject("WbemScripting.SWbemSink", "SINK_")

(2) You hook the connector to the Sink via an Asynchronous query:
wmiServices.ExecNotificationQueryAsync wmiSink, _
"SELECT * FROM RegistryValueChangeEvent WHERE Hive= " _
& "'HKEY_LOCAL_MACHINE' AND KeyPath= " _
& "'SOFTWARE\\Microsoft\\Windows NT\
\RegisteredOwner' AND " _
& "ValueName='CSDVersion'"

(3) You set up Event handlers:
Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
Wscript.Echo "Received Registry Change Event" & vbCrLf & _
"------------------------------" & vbCrLf & _
wmiObject.GetObjectText_()
End Sub

What I can't understand exactly is the Do...Loop:
Do While(1)
WScript.Sleep 1000
Loop

What is going on in the Loop other than sleeping for 1 second?
Is the Subroutine SINK_OnObjectReady being called within the loop? If
so, how?

Any help with clarifying this would be greatly appreciated. Thanks.

- Dave

Re: WBemScripting.SWbemSink and Do Loop - Explained by Richard

Richard
Wed May 09 12:47:08 CDT 2007


"Highlander" <tron9901@msn.com> wrote in message
news:1178726625.086829.327020@y5g2000hsa.googlegroups.com...
> Hello all.
>
> Consider the following script, used for Monitoring Entry-Level Events,
> from:
> http://www.microsoft.com/technet/scriptcenter/guide/sas_reg_teyz.mspx?mfr=true
>
> strComputer = "."
> Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
> _
> strComputer & "\root\default")
> Set wmiSink = WScript.CreateObject("WbemScripting.SWbemSink", "SINK_")
>
> wmiServices.ExecNotificationQueryAsync wmiSink, _
> "SELECT * FROM RegistryValueChangeEvent WHERE Hive= " _
> & "'HKEY_LOCAL_MACHINE' AND KeyPath= " _
> & "'SOFTWARE\\Microsoft\\Windows NT\
> \RegisteredOwner' AND " _
> & "ValueName='CSDVersion'"
> Wscript.Echo "Listening for Registry Change Events ..." & vbCrLf
> Do While(1)
> WScript.Sleep 1000
> Loop
>
> Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
> Wscript.Echo "Received Registry Change Event" & vbCrLf & _
> "------------------------------" & vbCrLf & _
> wmiObject.GetObjectText_()
> End Sub
>
> I'm trying to understand how the script works. As for the the WMI Sink
> Event portion, I think I have a handle on it:
>
> (1) You instantiate a connector and a Sink:
> strComputer = "."
> Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
> _
> strComputer & "\root\default")
> Set wmiSink = WScript.CreateObject("WbemScripting.SWbemSink", "SINK_")
>
> (2) You hook the connector to the Sink via an Asynchronous query:
> wmiServices.ExecNotificationQueryAsync wmiSink, _
> "SELECT * FROM RegistryValueChangeEvent WHERE Hive= " _
> & "'HKEY_LOCAL_MACHINE' AND KeyPath= " _
> & "'SOFTWARE\\Microsoft\\Windows NT\
> \RegisteredOwner' AND " _
> & "ValueName='CSDVersion'"
>
> (3) You set up Event handlers:
> Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
> Wscript.Echo "Received Registry Change Event" & vbCrLf & _
> "------------------------------" & vbCrLf & _
> wmiObject.GetObjectText_()
> End Sub
>
> What I can't understand exactly is the Do...Loop:
> Do While(1)
> WScript.Sleep 1000
> Loop
>
> What is going on in the Loop other than sleeping for 1 second?
> Is the Subroutine SINK_OnObjectReady being called within the loop? If
> so, how?
>
> Any help with clarifying this would be greatly appreciated. Thanks.
>
> - Dave
>

In VBScript, boolean True converts to integer -1, while boolean False
converts to 0. Integer 0 converts to boolean False and any non-zero integer
converts to boolean True. The Do While statement loops while the boolean
expression (in parentheses) is True. In this case, the integer 1 is always
True. The Do While loops forever. The host is instructed to sleep for one
second per loop, so that other processes see little impact. When the event
fires, the Sub runs, but the program stays in memory forever, until you end
it (perhaps in Task Manager) or the computer shuts down. The loop keeps the
program from terminating.

I've never seen this method. I use the NextEvent method in an infinite loop
to wait for the event. The NextEvent method waits for the event so no Sleep
is required. However, this method looks like it should work as well.
However, shouldn't the statement:

Set ojbReg =

be the following:

Set wmiServices =

--
Richard Mueller
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net
--



Re: WBemScripting.SWbemSink and Do Loop - Explained by Highlander

Highlander
Thu May 10 13:18:47 CDT 2007

On May 9, 12:47 pm, "Richard Mueller [MVP]" <rlmueller-
nos...@ameritech.nospam.net> wrote:
> "Highlander" <tron9...@msn.com> wrote in message
>
> news:1178726625.086829.327020@y5g2000hsa.googlegroups.com...
>
>
>
>
>
> > Hello all.
>
> > Consider the following script, used for Monitoring Entry-Level Events,
> > from:
> >http://www.microsoft.com/technet/scriptcenter/guide/sas_reg_teyz.mspx...
>
> > strComputer = "."
> > Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
> > _
> > strComputer & "\root\default")
> > Set wmiSink = WScript.CreateObject("WbemScripting.SWbemSink", "SINK_")
>
> > wmiServices.ExecNotificationQueryAsync wmiSink, _
> > "SELECT * FROM RegistryValueChangeEvent WHERE Hive= " _
> > & "'HKEY_LOCAL_MACHINE' AND KeyPath= " _
> > & "'SOFTWARE\\Microsoft\\Windows NT\
> > \RegisteredOwner' AND " _
> > & "ValueName='CSDVersion'"
> > Wscript.Echo "Listening for Registry Change Events ..." & vbCrLf
> > Do While(1)
> > WScript.Sleep 1000
> > Loop
>
> > Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
> > Wscript.Echo "Received Registry Change Event" & vbCrLf & _
> > "------------------------------" & vbCrLf & _
> > wmiObject.GetObjectText_()
> > End Sub
>
> > I'm trying to understand how the script works. As for the the WMI Sink
> > Event portion, I think I have a handle on it:
>
> > (1) You instantiate a connector and a Sink:
> > strComputer = "."
> > Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
> > _
> > strComputer & "\root\default")
> > Set wmiSink = WScript.CreateObject("WbemScripting.SWbemSink", "SINK_")
>
> > (2) You hook the connector to the Sink via an Asynchronous query:
> > wmiServices.ExecNotificationQueryAsync wmiSink, _
> > "SELECT * FROM RegistryValueChangeEvent WHERE Hive= " _
> > & "'HKEY_LOCAL_MACHINE' AND KeyPath= " _
> > & "'SOFTWARE\\Microsoft\\Windows NT\
> > \RegisteredOwner' AND " _
> > & "ValueName='CSDVersion'"
>
> > (3) You set up Event handlers:
> > Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
> > Wscript.Echo "Received Registry Change Event" & vbCrLf & _
> > "------------------------------" & vbCrLf & _
> > wmiObject.GetObjectText_()
> > End Sub
>
> > What I can't understand exactly is the Do...Loop:
> > Do While(1)
> > WScript.Sleep 1000
> > Loop
>
> > What is going on in the Loop other than sleeping for 1 second?
> > Is the Subroutine SINK_OnObjectReady being called within the loop? If
> > so, how?
>
> > Any help with clarifying this would be greatly appreciated. Thanks.
>
> > - Dave
>
> In VBScript, boolean True converts to integer -1, while boolean False
> converts to 0. Integer 0 converts to boolean False and any non-zero integer
> converts to boolean True. The Do While statement loops while the boolean
> expression (in parentheses) is True. In this case, the integer 1 is always
> True. The Do While loops forever. The host is instructed to sleep for one
> second per loop, so that other processes see little impact. When the event
> fires, the Sub runs, but the program stays in memory forever, until you end
> it (perhaps in Task Manager) or the computer shuts down. The loop keeps the
> program from terminating.
>
> I've never seen this method. I use the NextEvent method in an infinite loop
> to wait for the event. The NextEvent method waits for the event so no Sleep
> is required. However, this method looks like it should work as well.
> However, shouldn't the statement:
>
> Set ojbReg =
>
> be the following:
>
> Set wmiServices =
>
> --
> Richard Mueller
> Microsoft MVP Scripting and ADSI
> Hilltop Lab -http://www.rlmueller.net
> --- Hide quoted text -
>
> - Show quoted text -

Thanks for the reply Richard.

So if I understand you correctly, as long as you instantiate a WMI
connector and a Sink; and then you hook the connector to the Sink via
an Asynchronous query; the subroutine containing your event handler
will fire any time an event occurs. That there is no need for a line
in the script to call the subroutine.

And therefore the function of the Loop is to merely keep the script
running - with a one second pause repeating itself.

But you're saying that the program stays in memory forever, until you
end it manually or the computer shuts down. That's strange. I would
think that the memory is released once you terminate the script?

As for your question about the Set ojbReg = statement, this is a
script copied verbatim from the Micro$oft website. You'd have to ask
Bill Gates if you want an answer to that one. I'll see if I can get
you his cell number.

- Dave


Re: WBemScripting.SWbemSink and Do Loop - Explained by Richard

Richard
Thu May 10 19:17:07 CDT 2007

> Thanks for the reply Richard.
>
> So if I understand you correctly, as long as you instantiate a WMI
> connector and a Sink; and then you hook the connector to the Sink via
> an Asynchronous query; the subroutine containing your event handler
> will fire any time an event occurs. That there is no need for a line
> in the script to call the subroutine.

I believe so, although the method I've used in the past to monitor events is
different. See this link:

http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_kzcp.mspx

A similar script that does not exit when the event first, but continues to
wait for more events is shown in this link:

http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_tjin.mspx

>
> And therefore the function of the Loop is to merely keep the script
> running - with a one second pause repeating itself.

Yes

>
> But you're saying that the program stays in memory forever, until you
> end it manually or the computer shuts down. That's strange. I would
> think that the memory is released once you terminate the script?

Yes, the memory is released and the event no longer is monitored once the
script terminates. The loop makes sure the script never terminates.

>
> As for your question about the Set ojbReg = statement, this is a
> script copied verbatim from the Micro$oft website. You'd have to ask
> Bill Gates if you want an answer to that one. I'll see if I can get
> you his cell number.
>
> - Dave
>

Certainly not the first time I (or others) have found mistakes in code
posted on the Microsoft web site. Bill hires smart people, but even they can
make mistakes. However, I cannot find the script you reference.

--
Richard Mueller
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net
--




Re: WBemScripting.SWbemSink and Do Loop - Explained by Highlander

Highlander
Fri May 11 08:57:18 CDT 2007

On May 10, 7:17 pm, "Richard Mueller [MVP]" <rlmueller-
nos...@ameritech.nospam.net> wrote:
> > Thanks for the reply Richard.
>
> > So if I understand you correctly, as long as you instantiate a WMI
> > connector and a Sink; and then you hook the connector to the Sink via
> > an Asynchronous query; the subroutine containing your event handler
> > will fire any time an event occurs. That there is no need for a line
> > in the script to call the subroutine.
>
> I believe so, although the method I've used in the past to monitor events is
> different. See this link:
>
> http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_kzcp.mspx
>
> A similar script that does not exit when the event first, but continues to
> wait for more events is shown in this link:
>
> http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_tjin.mspx
>
>
>
> > And therefore the function of the Loop is to merely keep the script
> > running - with a one second pause repeating itself.
>
> Yes
>
>
>
> > But you're saying that the program stays in memory forever, until you
> > end it manually or the computer shuts down. That's strange. I would
> > think that the memory is released once you terminate the script?
>
> Yes, the memory is released and the event no longer is monitored once the
> script terminates. The loop makes sure the script never terminates.
>
>
>
> > As for your question about the Set ojbReg = statement, this is a
> > script copied verbatim from the Micro$oft website. You'd have to ask
> > Bill Gates if you want an answer to that one. I'll see if I can get
> > you his cell number.
>
> > - Dave
>
> Certainly not the first time I (or others) have found mistakes in code
> posted on the Microsoft web site. Bill hires smart people, but even they can
> make mistakes. However, I cannot find the script you reference.
>
> --
> Richard Mueller
> Microsoft MVP Scripting and ADSI
> Hilltop Lab -http://www.rlmueller.net
> --


Thanks again for the clarification Richard.

You can't find the script I'm referencing? Did you click the link I
had in my original post?

http://www.microsoft.com/technet/scriptcenter/guide/sas_reg_teyz.mspx?mfr=true

- Dave