How Can I Select Domain Workstations with a WMI Filter?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! Can you confirm that the below WMI filter will select domain workstations?

SELECT * 
FROM Win32_ComputerSystem
WHERE strComputerRole = "Member Workstation"

- IB

SpacerHey, Scripting Guy! Answer

Hi IB,

I can confirm that your command in fact will not work. The command should be written like this:

Select * from WIN32_computersystem where domainrole = 3

The WIN32_ComputerSystem WMI class is documented on MSDN. It is also talked about here on the Script Center. This “Hey, Scripting Guy!” article illustrates using the class.

 

How Can I Use copyFile, fileExists, and Increment a File Number?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I copy a file that always has the same name from one location to another, check whether the file exists, and if so rename it at the second location with a running number. In this way I could copy backup images to an external hard drive and have them “sorted” by name.

- SG

SpacerHey, Scripting Guy! Answer

Hi SG,

Use the fileExists method to see if the file exists. Use the copyFile method to rename the file. Here is an interesting article that talks about creating file names based upon the date.

Here is a sample script that will illustrate some of the concepts we talked about: the fileExists method, the copyFile method, and incrementing a number:

Dim path,file, extension, originalFile
path = "C:\fso"
file = "a"
extension = ".txt"
originalFile = path & "\" & file & extension
copyPath = "C:\fso1"
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(originalFile) Then
 WScript.Echo "Original file exists. Proceeding to copy"
Else
 WScript.Echo "Original file does not exist. Exiting script."
 WScript.Quit
End If

If objFSO.FileExists(copyPath & "\" & file & extension) Then
 WScript.Echo "copy file also exists. Incrementing name"
 file = file & "1"
 copyPath = copyPath & "\" & file & extension
 objFSO.CopyFile originalFile, copyPath
 Else
 WScript.Echo "Copy file does not exist. Copying same"
 copyPath = copyPath & "\" & file & extension
 WScript.Echo copypath
 WScript.Echo originalFile
 objFSO.CopyFile originalFile, copyPath
End If

How Can I Have on Logon a Report of the Software Installed on a Client Computer?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I have a script that reports the software installed on a client machine at logon?

- TA

SpacerHey, Scripting Guy! Answer

Hi TA,

This is one of the things that does not work really well. If a piece of software is installed using MSI, you can use the WIN32_Product WMI class and get a list easily. This WMI class is talked about in this article. Ultimately, the most reliable way to inventory installed software is to use the uninstall key from the registry:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

You will be interested in the following information:

DisplayName

InstallDate

Publisher

Version

If you have SMS installed on your computer, it creates a new WMI class based on the StdRegProv class that is called Win32Reg_AddRemovePrograms. It reads the registry key above, and displays the information.  If not, you can use a script such as InventoryInstalledSoftwareRegKey.vbs that I just wrote especially for you:

'==========================================================================
'
'
' NAME: InventoryInstalledSoftwareRegKey.vbs
'
' AUTHOR: ed wilson, msft 
' DATE  : 1/22/2009
'
' COMMENT: Uses WMI to read the uninstall software registry key.
'
'==========================================================================
SubCheckCscript
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\"&_ 
    strComputer & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
objReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
WScript.Echo "Subkeys under " _
    & "HKEY_LOCAL_MACHINE\SYSTEM\Software\Microsoft\Windows\CurrentVersion\Uninstall"
For Each subkey In arrSubKeys
    WScript.Echo subkey
    objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & subKey, "DisplayName", strDisplayName
    objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & subKey, "Publisher", strPublisher
    objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & subKey, "DisplayVersion", strDisplayVersion
    If Not IsNull(strDisplayName) Then
       WScript.Echo vbTab & "Display Name: " & strDisplayName
    End If 
    If Not IsNull(strDisplayName) Then
       WScript.Echo vbTab & "Publisher: " & strPublisher
    End If 
    If Not IsNull(strDisplayName) Then
       WScript.Echo vbTab & "Display Version: " & strDisplayVersion
    End If 
Next

Sub SubCheckCscript
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
    MsgBox "This script must be run under cscript. 
Open the cmd prompt, type cscript 
InventoryInstalledSoftwareRegKey.vbs"
    WScript.Quit
End If 
End Sub

‘---- end script

 

How Can I Find the Version of Several Executable Files Not Registered in the Registry?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! Good morning. I need your help. I need to know the version of several executable files not registered in the registry. If I use the following lines in a .vbs script, I can obtain the version of a single executable, but I need to scan several directories (or all Drive C:\).:

Set objFSO = CreateObject("Scripting.FileSystemObject")
Wscript.Echo objFSO.GetFileVersion("C:\... nameofexefile")

- UG

SpacerHey, Scripting Guy! Answer

Hi UG,

You will need to recurse to do this. You script will look similar to this RecurseFolderListFileVersion.vbs script:

strTarget = "c:\fso"
Set objFSO = CreateObject("Scripting.FileSystemObject")
subRecursiveFolders objFSO.GetFolder(strTarget)

Sub subRecursiveFolders(Folder)
Set colFiles = Folder.files
  For Each file In colFiles 
      WScript.Echo file.path
      ver = objFSO.GetFileVersion(file.path)
      If Len(ver) Then
          WScript.Echo ver
      Else
      WScript.Echo  "No version information available."
   End If
  Next 'for each file 
  For Each objFolder In Folder.subFolders
      subRecursiveFolders objFolder
  Next
End Sub

 

How Can I Use the Previous Script to Discover Only .Exe Files?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I use the above listed script to discover only .exe files?

- UG

SpacerHey, Scripting Guy! Answer

Hi again UG,

You add this code to it:

intExt = InstrRev(file.path,".")
If Mid(file.path, intExt) = ".exe" Then
   WScript.Echo file.path
End I

When you put it all together, it looks like the following script (because the extension is kept in a separate variable, it is easy to have it find only .dll or whatever types of files):

strTarget = "c:\fso"
fileExtension = ".exe"
Set objFSO = CreateObject("Scripting.FileSystemObject")
subRecursiveFolders objFSO.GetFolder(strTarget)

Sub subRecursiveFolders(Folder)
Set colFiles = Folder.files
  For Each file In colFiles 
      intExt = InstrRev(file.path,".")
         If Mid(file.path, intExt) = fileExtension Then
            WScript.Echo file.path
            ver = objFSO.GetFileVersion(file.path)
              If Len(ver) Then
                WScript.Echo ver
              Else
                WScript.Echo  vbTab & "No version information available."
              End If
         End If 
  Next 'for each file 
  For Each objFolder In Folder.subFolders
      subRecursiveFolders objFolder
  Next
End Sub

 

Well, everyone, that is it for this edition of Quick-Hits Friday. It also draws another week to a close. We hope you have a save and enjoyable weekend (if you are on the other side of the world from us, you already have a head start on the weekend; good on ya mate!). Join us back here on Monday for another exciting week of “Hey, Scripting Guy!” articles. If you want to know what we will be talking about ahead of time, follow us on Twitter. Until Monday, be safe.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys