'****************************************************************
' Filename..: xml_scheduled_tasks.vbs
' Author....: David M. Stein
' Date......: 03/18/2010
' Purpose...: query Scheduled Tasks (not WMI/Jobs/AT) --> XML out
'****************************************************************
Const tempfile = "c:\temp\schtasks.txt"
Const computer = ""
Const ForReading = 1
Const ForWriting = 2
Set objShell = CreateObject("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
If computer <> "" Then
cmdstr = "cmd /c schtasks /query /s \\" & computer & " /v /fo list >" & tempfile
Else
cmdstr = "cmd /c schtasks /query /v /fo list >" & tempfile
End If
retval = objShell.Run(cmdstr, 1, True)
If objFSO.FileExists(tempfile) Then
Dim linecount, objFSO, objFile, ln, strLine
linecount = 0
wscript.echo "" "
Set objFile = objFSO.OpenTextFile(tempfile, ForReading)
Do Until objFile.AtEndOfStream
strLine = Trim(objFile.Readline)
If Left(strLine, 9) = "HostName:" Then
hostname = Mid(strLine, 39)
wscript.echo vbTab & "" "
ElseIf Left(strLine, 9) = "TaskName:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
wscript.echo vbTab & vbTab & "" & hostname & " "
ElseIf Left(strLine, 15) = "Scheduled Type:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
ElseIf Left(strLine, 9) = "Schedule:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
ElseIf Left(strLine, 12) = "Task To Run:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
ElseIf Left(strLine, 8) = "Comment:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
ElseIf Left(strLine, 12) = "Run As User:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
ElseIf Left(strLine, 11) = "Start Time:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
ElseIf Left(strLine, 11) = "Start Date:" Then
wscript.echo vbTab & vbTab & "" & Mid(strLine, 39) & " "
ElseIf Left(strLine, 17) = "Power Management:" Then
wscript.echo vbTab & "
End If
linecount = linecount + 1
Loop
objFile.Close
Set objFSO = Nothing
wscript.echo "
Else
wscript.echo "fail: file not found"
End If
Thursday, March 18, 2010
Query Scheduled Tasks The Hard Way
Thursday, March 4, 2010
VBScript: Enumerate Start Menu Shortcuts into XML
'****************************************************************
' Filename..: enum_allusers_shortcuts.vbs
' Author....: skatterbrainz
' Date......: 02/03/2010
' Purpose...: enumerate shortcuts under all-users start menu (xml)
'****************************************************************
Dim objShell, allUsers, allStart, objFSO, oFolder, s
Set objShell = CreateObject("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
allUsers = objShell.ExpandEnvironmentStrings("%AllUsersProfile%")
allStart = allUsers & "\Start Menu\Programs"
Set oFolder = objFSO.GetFolder(allStart)
wscript.echo "<shortcuts>" "
For each s in oFolder.SubFolders
ListShortcuts objFSO.GetFolder(allStart & "\" & s.Name)
Next
wscript.echo "</shortcuts>
Sub ListShortcuts(objFolder)
Dim objFile, filename
For each objFile in objFolder.Files
filename = objFile.Name
If Right(Lcase(filename),4) = ".lnk" Then
filepath = objFolder.Path & "\" & filename
wscript.echo vbTab & "<shortcut>" "
ShortcutProps filepath
wscript.echo vbTab & "</shortcut>
End If
Next
End Sub
Sub ShortcutProps(scName)
Dim objShortcut
If objFSO.FileExists(scName) Then
Set objShortcut = objShell.CreateShortcut(scName)
WScript.Echo vbTab & vbTab & "<fullname>" & objShortcut.FullName & "</fullname> "
WScript.Echo vbTab & vbTab & "<arguments>" & objShortcut.Arguments & "</arguments> "
WScript.Echo vbTab & vbTab & "<workingpath>" & objShortcut.WorkingDirectory & "</workingpath> "
WScript.Echo vbTab & vbTab & "<target>" & objShortcut.TargetPath & "</target> "
WScript.Echo vbTab & vbTab & "<icon>" & objShortcut.IconLocation & "</icon> "
WScript.Echo vbTab & vbTab & "<hotkey>" & objShortcut.Hotkey & "</hotkey> "
WScript.Echo vbTab & vbTab & "<windowstyle>" & objShortcut.WindowStyle & "</windowstyle> "
WScript.Echo vbTab & vbTab & "<comment>" & objShortcut.Description & "</comment> "
Set objShortcut = Nothing
Else
wscript.echo "unable to find shortcut"
End If
End Sub
Set oFolder = Nothing
Set objFSO = Nothing
Set objShell = Nothing
Thursday, December 31, 2009
VBScript ADO with XML and CSV Data Files
I was poking around to find a way to read CSV, TXT (various delimiters) through VBScript for use in scripted data migrations, as well as to render the data in ASP, and found some interesting things. I have to give credit to [http://www.mombu.com/microsoft/scripting-wsh/t-query-xml-file-with-ado-in-wsh-131431.html] for the XML example. I only modified it slightly to fit in with how I tend to code ADO processes. I also would like to applaud the efforts of Connection Strings.com for their fantastic reference site for connection information for almost anything that can possibly store information.
Reading XML Data
Const dsn = "Provider=MSDAOSP;Data Source=MSXML2.DSOControl;"
Const adChapter = 136
Dim conn, rs
Dim iLevel : iLevel = 0
Set conn = CreateObject( "ADODB.Connection" )
Set rs = CreateObject( "ADODB.Recordset" )
conn.Open dsn
rs.Open CreateObject( "WScript.Shell" ).CurrentDirectory + _
"\test.xml", conn
WalkHier iLevel, rs
rs.Close
conn.Close
Sub WalkHier(ByVal iLevel, ByVal rs)
iLevel = iLevel + 1
Dim PriorLevel : PriorLevel = iLevel
Dim i, adoChildRS
While Not rs.EOF
For i = 0 To rs.Fields.Count - 1
If rs.Fields(i).Name <> "$Text" Then
If rs.Fields(i).Type = adChapter Then
Set adoChildRS = rs.Fields(i).Value
WalkHier iLevel, adoChildRS
Else
wscript.echo iLevel & ": rs.Fields(" & i & ") = " & _
rs.Fields(i).Name & " = " & rs.Fields(i).Value
End If
End If
Next
rs.MoveNext
Wend
iLevel = PriorLevel
End Sub
Reading CSV Data
dsn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='s:\scripts\';Extended Properties=""text;HDR=Yes;FMT=Delimited(,);"""
query = "SELECT * FROM test.csv"
Set conn = CreateObject("ADODB.Connection")
Set cmd = CreateObject("ADODB.Command")
Set rs = CreateObject("ADODB.Recordset")
conn.Open dsn
rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.LockType = adLockReadOnly
Set cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = query
rs.Open cmd
If Not(rs.BOF And rs.EOF) Then
Do Until rs.EOF
For i = 0 to rs.Fields.Count - 1
wscript.echo rs(i).name & " = " & rs(i).value
Next
rs.MoveNext
Loop
Else
wscript.echo "error: no records found"
End If
rs.Close
conn.Close
Set rs = Nothing
Set cmd = Nothing
Set conn = Nothing
Friday, December 25, 2009
Convert INI to XML with KiXtart
Sometimes you may want/need to read a standard INI data file and output it to an XML format. There are several ways to do this, but here is just one. You’ll need KiXtart 4.61 in order to use the Replace() function. Enjoy (and Merry Christmas!)
KiXtart Code
Break ON
; requires KiXtart 4.61 or later!!!
If @kix <= "4.60"
? "this script requires 4.61 or later!"
Exit
EndIf
$strFileName = "s:\scripts\test.ini"
$quote = Chr(34)
$tab = Chr(9)
Dim $linecount, $fHandle, $strLine, $outer, $keyset, $subkeyformat
Dim $name, $value
$subkeyFormat = 1
$fHandle = FreeFileHandle()
$outer = ""
If Open($fHandle, $strFileName) = 0
$strLine = ReadLine($fHandle)
While @error = 0
Select
Case Left($strLine,1) = "["
$outer = Replace(Replace($strLine, "]", ""), "[", "")
? "<$outer>"
Case InStr($strLine, "=") <> 0
$keyset = Split($strLine, "=")
$name = $keyset[0]
$value = $keyset[1]
If $subkeyFormat == 1
? "$tab- "
Else
? "$tab<$name>$value</$NAME>"
EndIf
Case 1
If $outer <> ""
? "</$OUTER>"
$outer = ""
EndIf
EndSelect
$strLine = ReadLine($fHandle)
Loop
$=Close($fHandle)
EndIf
Saturday, October 17, 2009
Using Twitter to Control Your Computer
I’ve blogged about this before, but not with a lot of detail. So here goes.
In my previous post, I explained how to setup a “system” that has your computer sending a DM (Direct Message) Tweet to your Twitter account. But in this scenario I’m turning it around, so that you will Tweet your computer and have it perform actions based on what you Tweet.
What you do with this is up to you. Anything you can do with a script is fair game. Anything. The script will reside on your computer. You will send a DM to a Twitter account, which your computer will monitor on a scheduled recurrence. Your script will read and parse the DM container and look for specific phrases that it is set to recognize and will execute a task accordingly. Simple enough? Good. I thought so.
Ingredients:
- A Twitter Account
- Another Twitter Account
- A List of Things You Intend to Ask Your Computer To Do
- A Script
- A Scheduled Task
A Twitter Account
This is YOUR Twitter account actually. You will need this in order to send a DM (Direct Message) Tweet to your computer, which requires…
Another Twitter Account
This is the account your computer will monitor. Remember to lock it down so only your “other” Twitter account can access it.
A List of Things for Your Computer To Do
You need to sit down and make a list of what specific tasks you want to be able to request of your computer. Yes, you COULD make it so you Tweet any shell operation and have it blindly execute that, but trust me: THAT IS DANGEROUSLY STUPID. In fact, so stupid, you should have your balls stomped with ice climbing boots in a rowdy Irish pub just for thinking it. Need some pointers? Here’s a simple list to get you started:
- Reboot or Shutdown a computer
- Disable a User Account
- Add/Remove A User to/from a Group
- Start/Stop a Service
- Start a Batch or Backup Job
For the first example, I’m going to simply have the computer tweet me back. That way I know the plumbing is working and the toilets flush properly. To do this, I’m going to make a script that reads my DM list and parses it for a specific phrase. When that phrase is found, it will simply tweet me back (by DM) to let me know it got it.
A Script
The script I’m using for this example is written in VBscript, but any language/platform will work fine as long as it can invoke the Twitter API. This script will access my Computer Twitter account, fetch the DM queue, iterate through it for messages containing a specific phrase of “TWEET_ME_BACK @userid” and then simply turn around and send a DM to the “@userid” that sent it (which, in this situation, is me).
'----------------------------------------------
' filename: twitter_monitor.vbs
' author: skatterbrainz
' http://scriptzilla.blogspot.com
' give props, don't rip me off please?
'----------------------------------------------
Const username = "Computer_TwitterName"
Const password = "Computer_TwitterPassword"
Const replyTo = "My_Twitter_Account"
Function Twitter_Get_Direct(strUser,strPass)
wscript.echo "querying for direct messages..."
Dim oXml, strTwitterURL : strTwitterURL = "http://twitter.com/direct_messages.xml"
Set oXml = CreateObject("MSXML2.ServerXMLHTTP.3.0")
oXml.Open "GET", strTwitterURL, False, strUser, strPass
oXml.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oXml.Send()
Twitter_Get_Direct = oXml.responseText
Set oXml = Nothing
End Function
result = Twitter_Get_Direct(username, password)
'----------------------------------------------
' if direct messages were found, iterate them
'----------------------------------------------
If Trim(result) <> "" Then
wscript.echo "direct messages were found!"
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = "false"
xmlDoc.loadXML(result)
For each x in xmlDoc.documentElement.childNodes
msg = x.Text
If InStr(1, Ucase(msg), "TWEET ME BACK") <> 0 Then
id = Left(msg, 9)
wscript.echo id, ": ", Mid(Msg, 20)
wscript.echo "sending tweet-dm..."
TweetBack()
DeleteDM id
End If
Next
End If
'----------------------------------------------
' send tweet via direct-message
'----------------------------------------------
Sub TweetBack()
Dim retval, strMsg : strMsg = "I got your message!"
Dim oXml, strTwitterURL : strTwitterURL = "http://twitter.com/direct_messages/new.xml"
Set oXml = CreateObject("MSXML2.ServerXMLHTTP.3.0")
oXml.Open "POST", strTwitterURL, False, username, password
oXml.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oXml.Send "text=" & strMsg & "&user=" & replyTo
retval = oXml.responseText
Set oXml = Nothing
End Sub
'----------------------------------------------
' delete a direct-message using the id number
'----------------------------------------------
Sub DeleteDM(id)
Dim retval
Dim oXml, strTwitterURL : strTwitterURL = "http://twitter.com/direct_messages/destroy/" & id & ".xml"
Set oXml = CreateObject("MSXML2.ServerXMLHTTP.3.0")
oXml.Open "POST", strTwitterURL, False, username, password
oXml.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oXml.Send()
retval = oXml.responseText
Set oXml = Nothing
End Sub
Note that in the iteration section of code above I invoke the XMLDOM object to parse the direct_message result. This is because it returns a single XML stream that contains all of the direct messages.
A Scheduled Task
Because your computer needs to read the Twitter account DM queue, it needs to “poll” for it using a recurrent task. The easiest way to do this is by creating a scheduled task. Each time the task is initiated, it will execute the script and go back to sleep until it’s scheduled to run again. I’m using Windows 7 for this example, so here goes…
- Click on the Windows button (formerly “Start” button)
- Type in SCHED and as soon as “Task Scheduler” appears at the top, press Enter.
- Click on Task Scheduler Library in the left-hand panel
- Right-click on Task Scheduler Library and select “Create Task”
- In the Name box, enter “Monitor Twitter Account”
- In the Description box, enter “Monitor Twitter account ___ for Direct Messages to parse” (fill-in your computer Twitter account name).
- Select “Run whether user is logged on or not”
- Click “Change User or Group” button, enter “SYSTEM” and click “Check Names”
- Once the name is underlined, click OK. You should see “NT AUTHORITY\SYSTEM” in the user account name box. (see Fig. 1)
- Click the Triggers tab.
- Change the “Repeat task every:” to “15 Minutes”
- Check “Stop task if it runs longer than:” and set it to “14 Minutes” (see Fig. 2)
- Click OK, to return to the Create Task form.
- Click the Actions tab, click the New button
- Enter “cscript” for the program. Enter “/nologo c:\scripts\monitor_twitter.vbs” in the arguments box (see Fig. 3, and 4)
- Click OK to save the new Task
Sunday, July 12, 2009
LDAP Query for User Accounts Created Since a Specific Date
(&(objectCategory=user)(whenCreated>=20090601000000.0Z))
LDAP Query for Printers = HP DesignJet Plotters
(&(&
(uncName=*)
(objectCategory=printQueue)
(objectCategory=printQueue)
(driverName=*DesignJet*)
))
LDAP Query for Windows Server 2003 SP1 Computers in AD
(&(&(&(&(&(&(&(&(&(&
(objectCategory=Computer)
(operatingSystem=Windows Server 2003*)
(operatingSystemServicePack=Service Pack 1)
))))))))))