How Can I Determine if a Particular Windows Feature Is Installed?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I am new to Windows PowerShell scripting and have a little experience with WMI thanks to your Windows PowerShell Scriptomatic tool.  I'm trying to determine whether a particular optional Windows component or feature is installed (Freecell, for example). I am actually looking for a series of IIS components, but I think Freecell would be easier. Does this information exist in WMI or anywhere that can be accessed from a script?

- TW

SpacerHey, Scripting Guy! Answer

Hi TW,

You are gonna love this on Windows 7. There is a new WMI class named WIN32_OptionalFeature. You can use Windows PowerShell to access it in this manner. The output is truncated because it reports more than five pages of optional features. If the value is 1, it means that it is installed; if it is 2, it is available for install, but currently not installed.


Get-WmiObject WIN32_OptionalFeature | 
Format-table name, installState –autosize
name                                        installState
----                                        ------------
OEMHelpCustomization                                   2
CorporationHelpCustomization                           2
SimpleTCP                                              2
SNMP                                                   2
WMISnmpProvider                                        2
TelnetServer                                           2
TelnetClient                                           2
WindowsGadgetPlatform                                  1
InboxGames                                             1
More Games                                             1
Solitaire                                              1
SpiderSolitaire                                        1
Hearts                                                 1
FreeCell                                               1
Minesweeper                                            1
PurblePlace                                            1
Chess                                                  1
Shanghai                                               1
Internet Games                                         1
Internet Checkers                                      1
Internet Backgammon                                    1
Internet Spades                                        1
IIS-WebServerRole                                      2
IIS-WebServer                                          2
IIS-CommonHttpFeatures                                 2
IIS-HttpErrors                                         2
 

How Can I Scan a Directory or Drive for Files Created or Accessed by User Account?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! Is there a way to scan a directory structure or a whole drive for files that were created or last accessed by a specific user account?

- TA

SpacerHey, Scripting Guy! Answer

Hi TA,

For the first part of your question, you may be able to find information from the owner attribute, which is documented in this "Hey, Scripting Guy!" article. For the second part of your question, you have to enable auditing. As soon as auditing is enabled, you will be able to query the Security log to find when a specific user has last accessed a folder.

 

How Can I Get VBScript to Run on Multiple Operating Systems?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have been working on a script problem for the past several days and I am encountering problems. I have an array of computers of varying operating systems: Windows Server 2008 R2, Windows Server 2003, Windows Vista, and Windows XP. My script queries a list of computers. I first look for simple information such as operating system, language, locale, and operating system version, and then I delve into the registry for some more interesting things such as specific software that is installed.

So my big question is how do I get VBScript to run on multiple operating systems. Or is there a better way to do this? Maybe with Windows PowerShell?

I really like your Web site and all,  and am wondering when you will go on NPR and compete with Click and Clack.

- JM

SpacerHey, Scripting Guy! Answer

Hi JM,

We thought at one time about doing a radio program, I do not think there is any special magic for running on multiple operating systems. This is where learning about what you are doing comes into being (not that you do not).

For example, I know whether I am going to use the WIN32_Volume WMI class, it only exists on Windows Server 2003 and later. If I decide to use the NetDiag WMI class, it only exists on Windows XP (a shame really; it was a cool class). When I use something that I know only exists on a particular version of Windows, I do an operating system check in my code. Generally, I only need the major version. Therefore, I will do something such as this by using Windows PowerShell:

Get-OperatingSystemVersion.ps1

# ------------------------------------------------------------------------
# NAME: Get-OperatingSystemVersion.ps1
# AUTHOR: ed wilson, Microsoft
# DATE: 2/2/2009
#
# KEYWORDS: Function, Get-WmiObject, 
# Win32_OperatingSystem
#
# COMMENTS: This script returns the OS version number
# to the calling script. 
#
# Windows PowerShell Best Practices
#
# ------------------------------------------------------------------------
Function Get-OperatingSystemVersion
{
 (Get-WmiObject -Class Win32_OperatingSystem).Version
} #end Get-OperatingSystemVersion

"This OS is version $(Get-OperatingSystemVersion)"

Using VBScript, you can do something such as this:

OneLineOperatingSystemVersion.vbs

'==========================================================================
'
' NAME: OneLineOperatingSystemVersion.vbs
'
' AUTHOR:  ed wilson , MSFT
' DATE  : 4/8/2009
'
' COMMENT: Uses a one line technique to report the OS Version. This only works On
' Vista and above due to the change in the win32_OperatingSystem class being a 
' singleton
'
'==========================================================================

wscript.echo GetObject("winmgmts:win32_OperatingSystem=@").Version

If  you are talking about remoting, VBScript has the WSHController object, if you can make it work. It is documented here and here.

Windows PowerShell 2.0 has great remoting features that solve the firewall problem, security problem, and other issues encountered with WSHController because it is built upon WinRM. Windows PowerShell is currently in beta and can be downloaded from our Windows PowerShell Scripting Hub.

The only way to retrieve a good list of installed software is to troll the registry. There is a WIN32_Product WMI class. However, it only works with software that was installed through MSI.

 

With Windows PowerShell, How Can I Log Information to the Event Log on Windows Server 2008 R2?

Hey, Scripting Guy! Question

Hey, Scripting Guy! What is the best way of logging information to the event log on Windows Server 2008 R2 with Windows PowerShell 2.0 CTP3?

- DS

SpacerHey, Scripting Guy! Answer

Hi DS,

You want to use the Write-EventLog cmdlet on Windows PowerShell 2.0. There is also the New-EventLog cmdlet that will enable you to create a new event log and register event sources.

 

How Can I Install a Local Printer and Attach It to a Server Print Queue?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a question, or rather a request. I want to script the installation of a local printer and attach the printer to a local port that is a server print queue ( i.e \\server\printqueue ). 

I have found many articles on scripting printers and attaching them to TCP\IP ports. Is there a way to script a printer to a print queue? We use a third-party product that tracks printing on print queues that are set up on a print server. Therefore, using the TCP\IP port is not an option for us because the TCP\IP port bypasses the print queue. Your assistance would be greatly appreciated.

- GM

SpacerHey, Scripting Guy! Answer

Hi GM,

This may help:

AddPrinterConnection.vbs

Set WshNetwork = WScript.CreateObject("WScript.Network")
WshNetwork.AddPrinterConnection "LPT1", file://server/Print1

You may also be interested in the Printing section of the Script Center Script Repository. Also try the Printers and Printing section of the Community-Submitted Scripts Repository, and the “Hey, Scripting Guy!” Printing archive. Here is the Printing section of the Scripting guide.

 

How Can I Use WMI to Retrieve Open Ports?

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have tried to write a script to retrieve open ports by using WMI, but unfortunately, I could not do it. Do you know whether it is possible to do? Which class do I have to use?

- JV

SpacerHey, Scripting Guy! Answer

Hi JV,

I do not think this can be directly done by using WMI. It can be done indirectly, by using a WMI class that only exists on Windows XP. This is seen here:

PingTestAndConnectToRangeOfPorts.vbs

'==========================================================================
'
'
' NAME: <PingTestAndConnectToRangeOfPorts.vbs>
'
' AUTHOR: Ed Wilson , MS
' DATE  : 1/18/2006
'
' COMMENT: <Uses netDiagnostics class from the netdiagProv>
'1. Uses two methods from the netdiagProv in the cimv2 namespace
'2. The methods are: ping and connectToPort. Each will return a -1 or 0
'3. a -1 is true (success) a 0 is false (failure)
'4. It MUST run on a Windows XP machine, but can target Windows 2003. 
'==========================================================================

Option Explicit 
'On Error Resume Next
dim strComputer
dim wmiNS
dim wmiQuery
dim objWMIService
dim colItems
dim objItem
Dim IP, strPorts, arrPorts, size, errRTN, errRTN1
Dim aPort 'single port at a time
Dim strOUT 'output string. 
IP = "London"
size = "32"
strPorts = "53,88,135,389,445,464,593,636,1025,1026,1028,1051,1110,3268,3269"
arrPorts = Split(strPorts,",")
strComputer = "." 'The machine where we RUN the script FROM
wmiNS = "\root\cimv2"
wmiQuery = "Select * from netDiagnostics"
strOUT = "Testing " & IP & vbcrlf 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & wmiNS)
Set colItems = objWMIService.ExecQuery(wmiQuery)

For Each objItem in colItems
errRTN = objItem.ping(IP, size)
strOUT = strOUT & "Ping test: " & errRTN & vbcrlf & "PORT TEST: " & vbcrlf
                For Each aPort In arrPorts
                    errRTN1 = objItem.connectToPort(IP, aPort)
                    strOUT = strOUT & vbtab & "port:" & aPort & " " & errRTN1 & vbcrlf
    next
Next

WScript.Echo(strOUT)

That is it for another Quick-Hits Friday. We hope that you have enjoyed this week and will join us next week for more exciting scripting fun. We are hard at work on the Scripting Games, and if you want to know all the details first, follow us on Twitter. Next week Ed heads to Redmond from South Carolina to teach a class to a group of Microsoft engineers. He is looking forward to the opportunity to sit down with Craig and work on last-minute Scripting Games stuff. Take care, and have a great weekend.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys