WMIService file results sometimes give "object does not support this property" - vbscript

I am trying to modify all shortcuts on a computer. The script works fine but every now and then throws an error that the .Target property of an object is not available. Since my query only looks up files with a .lnk extension, this should never be the case. (For more details on this error you can see MS docs here: http://technet.microsoft.com/en-us/library/ff406382.aspx#H25)
The script in question:
strComputer = "."
Set wshShell = WScript.CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery("Select * from CIM_DataFile WHERE Extension = 'lnk' AND Drive = 'C:'")
For Each objFile in colFiles
If InStr(1, ucase(objFile.Target), "METER.EXE") Then
Set objShortcut = wshShell.CreateShortcut(objFile.Name)
Wscript.Echo "FIXING: " & objShortcut.TargetPath
End If
Next
For the curious: The purpose of this script is to fix dozens of shortcuts on our lab machines which were previously modified to support a "home-grown" licensing/metering application. In all cases the original .EXE path was stripped from the target but can still be found from the shortcut's icon path.
Thanks
EDIT: The complete error message. It seems to appear more often after a restart, but not once I have run the script 2-3 times.
Microsoft VBScript runtime error: Object doesn't support this property
or method: 'objFile.Target'

CIM_DataFile doesn't have the Target property.
I believe you meant to use Win32_ShortcutFile instead.

Related

Can I list apps that don't have registry entries?

I've been working on a way to quickly and easily list all of the software installed on my machine. Once complete, I'd like to send it out to my group so that I can have everyone run it. Since the purpose of this exercise is generate a list of all of the applications that we absolutely require access to to our IT administrators, I don't want to miss anything important.
Up to this point, I've used code very similar to this - it looks in the registry at SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ and Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ and gives me all of the software that has been installed. However, a bunch of important programs are conspicuously absent (e.g. R, RStudio, SQL Developer), and I assume it's because they do not use Windows Installers.
This brings me to my question - is there a way I can list all of the programs that can be run on my machine (that have not impacted the registry)? Essentially, I think I want all of the non-system *.exe files, but that is probably oversimplifying things.
Anyone have any ideas? My code is VBS now, but I can muddle my way through most things.
If you want to find them all then you need to search every single file on your machine and check whether or not it has an executable extension. I'm reasonably confident that you are not going to want to do this.
I read your answer and laughed, since I was also "reasonably confident" that I did not want to go through all of the files on my (or anyone else's) machine. Once the laughing stopped, I realized that that's essentially what I had to do...
I've come up with something that works, and it now takes minutes to run (it took seconds to only check the registry), but it does work. I'm putting it here in case it can assist someone else, or maybe someone can find a way to make it more efficient. You need to supply some paths to folders where you want to look for exe files, and a file that you want to output to.
Thanks for reading.
On Error Resume Next
Folders = Array("C:\users\me","C:\SoftwareFolder1","C:\SoftwareFolder2","C:\SoftwareFolder3")
sFile="C:\myExeFiles.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Const ForWriting = 2
Const OverwriteIfExist = -1
Set fFile = objFSO.CreateTextFile(sFile, OverwriteIfExist, OpenAsASCII)
For Each x In Folders
Set objFolder = objFSO.GetFolder(x)
suckTheData objFSO, fFile, objFolder
Set objFolder = Nothing
Next
MsgBox("Done")
Set objFSO = Nothing
Sub suckTheData(objFSO, fFile, objFolder)
' *** STEP 1 *** 'Find files with a partiular extension in this folder
For Each objFile In objFolder.Files
If UCase(objFSO.GetExtensionName(objFile.Name))="EXE" Then
fFile.Write objFile & vbCrLf
If Err.Number <> 0 Then
fFile.Write "Error: " & objFile & " " & Err.Number & Err.Source & " " & Err.Description & vbCrLf
End If
End If
Next
Set objFile = Nothing
' *** STEP 2 *** 'Now that we've processed files, repeat for subdirectories
For Each subf In objFolder.SubFolders
'some folders can't/shouldn't be checked -
'16 is a normal folder, 32 is an archive, 1046 is symbolic, etc
If subf.Attributes ="16" Then
suckTheData objFSO, fFile, subf
End If
Next
Set subf = Nothing
End Sub

Reading From Text File breaks midway

Resolved: All I had to do was add a sleep to the loop.
I have a text file which contains usernames and passwords which need to be logged in. I'm attempting to make a VBScript file to automate this process. The text file's syntax is
username
password
username
password
etc etc
and is a total of 738 lines.
The code I currently have is
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Users\Jacob\Desktop\logins.txt", ForReading)
Set WshShell = WScript.CreateObject("WScript.Shell")
Const ForReading = 1
Dim strUsername
Dim strPassword
wshshell.AppActivate "Notepad"
Do Until objFile.AtEndOfStream
strUsername = objFile.ReadLine
strPassword = objFile.ReadLine
wshshell.sendkeys strUsername
wshshell.sendkeys "~"
wshshell.sendkeys strPassword
wshshell.sendkeys "~"
Loop
which I'm using simply to make sure it works by having it write to a blank text file. (Later notepad will be replaced by the login executable, I already know that part works).
The code works fine until it hits line 221 of the text file, where it breaks. It exports a bunch of random garbage and then stops.
Any help is greatly appreciated.
Edit:
Here is the garbage text which comes at the end of the written text file. You can see that there are still remnants of what should come out.
.[redacted username].22bssddd2222ent000.2wlllkarsstt00....000h8b6b99b88uub2
.....ttttte0000mp00...gh.rrlll00225..gbu
.....0022sdg
[redacted password]
.proeflussssddd
..22le.pu6....225500s.gl.iteee.55.uuu.hmadttn..0dl
tsssssbeeee0000nsssss0000000ssssdssdbuuuz22dddd000buuu.jj2222
b4....3
.j00000000b
y.
bb.ddddssgg.2222ssgg05uuudbeeeeen......hh00222l11.....tdddd.nn
00000
ll0ssssau0s000ssssss
bbddddlll.ttttl......s
be
.o222
b.ddddddutttt
ll000buc11e000000utttt
bbb.eeeeee0000seeeee5
mmssss000000unnnttttnnn
bb000..s.dsssssss.fa000000
2
.....k000.4tnnn
.....bbbseeeu
.n.2te....s
7e9bbmv00000000tttteeee.mttseetnn2222222r0000000000.u.ddd0000000.111ddddge11111ssddddoo000.ssssssnnnn.uutnnn772
.bbg.......66teeb000000ee1114lrd00002222nsp
Two things you can try...
Try adding a call to WScript.Sleep 100 inside your loop after your call to SendKeys.
Instead of using AppActivate and SendKeys, you could try it where the script just writes the usernames and passwords to another file. This would rule out if the problem is being caused by SendKeys. Using SendKeys with this much data is fairly dangerous anyways. If anything at all goes wrong with Notepad getting focus and the keys start getting directed to another application it could have some very, very unintentional results.
Here is a modified copy of your script to write to a text file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("logins.txt", ForReading)
Set objFile2 = objFSO.OpenTextFile("logins2.txt", ForWriting, true)
Set WshShell = WScript.CreateObject("WScript.Shell")
Const ForReading = 1, ForWriting = 2
Dim strUsername
Dim strPassword
Do Until objFile.AtEndOfStream
strUsername = objFile.ReadLine
strPassword = objFile.ReadLine
objFile2.Write strUsername & vbCrLf
objFile2.Write strPassword & vbCrLf
Loop
A couple of stylistic notes as well:
Define constants before you use them, preferably at the very top of the script. This keeps you and other from having to hunt them down later or thinking they haven't already been defined. It's not a big of a problem in a small script like this, but if you scripts starts getting bigger it could cause you headaches down the road.
Be consistent with Dim's. You defined strUsername and strPassword but you didn't define objFSO, objFile, or WshShell. I always recommend using Option Explicit to force you to define variables before using them. It helps you keep from making spelling mistakes and saves you a lot of headache in the long run.

vbscript to check if a process is running, if its not then copy a file from network

I am new to VB scripting and need help on a program to do the following, Can someone please help me out. It would be great if this whole program can be embedded into one vbscript.
Write a script to check
if a process is running or not( example notepad++.exe),
if its running then dont do anything.
If the process is not running, check if a directory is present or not under C:\Program Files(x86)
Say if the directory is not there then copy the .exe file from a network shared location onto a local drive and
then perform the command line installation in silent mode.(example> notepad++.exe -ms)
You can use this example. You need to put an if check and compare with objItem.Name = "notepad.exe" and do whatever you wish to do:
sComputerName = "."
Set objWMIService = GetObject("winmgmts:\\" & sComputerName & "\root\cimv2")
sQuery = "SELECT * FROM Win32_Process"
Set objItems = objWMIService.ExecQuery(sQuery)
'iterate all item(s)
For Each objItem In objItems
WScript.Echo "Process [Name:" & objItem.Name & "]"
Next
Also note you can use WHERE statement in query:
SELECT * FROM Win32_Process WHERE Name LIKE '%notepad%'
Here you can find names of columns for query:

Error : ActiveX component can't create object: 'Word.Application' in Windows XP

Below code is running fine in Windows 7.I am getting the error "ActiveX component can't create object: 'Word.Application'" in Windows XP.
Microsoft Word is not installed in the XP, Is this the cause for the error?
I am new to vbscript.
What is the resolution for this?
Const msoFileDialogOpen = 1
Set fso = CreateObject("Scripting.FileSystemObject")
Set objWord = CreateObject("Word.Application")
Set WshShell = CreateObject("WScript.Shell")
strInitialPath = WshShell.ExpandEnvironmentStrings("%USERPROFILE%") & "\Desktop\"
objWord.ChangeFileOpenDirectory(strInitialPath)
With objWord.FileDialog(msoFileDialogOpen)
.Title = "Select the file to process"
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "All Files", "*.*"
.Filters.Add "Excel Files", "*.xls;*.xlsx"
.Filters.Add "Text Files", "*.txt"
.Filters.Add "Various Files", "*.xls;*.doc;*.vbs"
If .Show = -1 Then 'short form
For Each File in .SelectedItems 'short form
Set objFile = fso.GetFile(File)
WScript.Echo objFile.Path
Next
Else
End If
End With
'Close Word
objWord.Quit
Yes, if MS Word is not installed in the computer no "Word.Application" can be created because it doesn't even exist in your system.
The easiest way to resolve this is installing MSWord in the computer. The hard way involves locating the activeX assemblies and its dependencies and register it in the computer manualy.
You can use http://www.nirsoft.net/utils/axhelper.html to check the list of ActiveX components instaled in a computer.
-- Can Openoffice resolve this instead of MS Word?
Ofcourse, check this link

Run a MATLAB routine when a file is added to a folder

I am currently working on a project where a file, or files, could be dumped to one of several locations on a server. I have a routine set up in MATLAB which processes the files quite nicely and I would like to automate this so that I don't have to waste any more of my time processing the files.
I found a WMI script (from ScriptingGuy Here) that behaves in a way that works for me, except I don't know enough about WMI to alter it to my purposes.
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _
& "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
& "TargetInstance.GroupComponent= " _
& "'Win32_Directory.Name=""c:\\\\scripts""'")
Do
Set objLatestEvent = colMonitoredEvents.NextEvent
Wscript.Echo objLatestEvent.TargetInstance.PartComponent
Loop
I tried using the command line tools for MATLAB replacing the Wscript.Echo line
matlab -automation -r someRoutine(varargin)
which failed miserably.
Could someone please give me some guidance on properly calling MATLAB from WMI and changing the target directory to multiple directories on the server?
You are looking for WScript.Shell and the Run method:
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "matlab -automation -r someRoutine(varargin)"
The documentation describes optional parameters that allow you to control how the process that is created is shown, and whether or not you wait for it to complete.

Resources