Learn about Windows PowerShell
Hey, Scripting Guy! Can you confirm that the below WMI filter will select domain workstations?
SELECT * FROM Win32_ComputerSystem WHERE strComputerRole = "Member Workstation"
- IB
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.
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
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
Hey, Scripting Guy! How can I have a script that reports the software installed on a client machine at logon?
- TA
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
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
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
Hey, Scripting Guy! How can I use the above listed script to discover only .exe files?
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