Learn about Windows PowerShell
In this post:
How Can I Get a List of All Drivers Available to a Computer?
Hey, Scripting Guy! I liked your articles about how to get a list of the installed device drivers. However, I want to get a list of all drivers available for installation in the Windows Vista driver store (in other words, a list of hardware supported, which might be several per driver). All I can find is a WMI class that does this on a Systems Management Server. Is it possible to make this information available to other computers?
-- DV
Hello DV,
Microsoft Scripting Guy Ed Wilson here. All drivers that are available to a computer are in the system root folder. Printer drivers all begin with the letters “prn”. Using this information, I can easily get a list of the available printer drivers by using the Get-ChildItem cmdlet and piping the results to the Where-Object cmdlet. This is shown here.
Get-AvailablePrinterDrivers.ps1
Get-ChildItem ((Get-Item Env:\systemroot).value+"\inf") -Exclude *.pnf | Where-Object { $_.name -match "prn" }
Can I Query IIS Via WMI?
Hey Scripting Guy! I found that you can query Internet Information Server (IIS) via WMI, but you must install something separate. I have seen some of the basic things that people have asked you about IIS, but I am looking to see if webDAV is enabled. I could not find anything on Web service extensions.
-- PJ
Hello PJ,
Actually, IIS has long been queriable via WMI. For IIS in Windows Server 2008 R2, there are four options:
1. You can use the “classic” WMI. They are the same WMI classes that were available in Windows Server 2003. When you add the IIS role, you choose IIS 6 management compatibility.
2. In Windows Server 2008, there are new WMI classes. These are an additional check box, and are called IIS management Scripts and Tools.
3. There are IIS cmdlets. The IIS page has extensive information about using these.
4. There is a WinRM IIS Extension that can be added as a feature.
These options are configured via the Server Manager utility, as seen here:
If you are interested in using Windows PowerShell and WMI to manage your IIS Server, I have a chapter in the Microsoft Press Windows PowerShell Scripting Guide book that covers this topic.
Tell Me More About Querying WMI Objects
Hey, Scripting Guy! I have noticed that there are multiple ways to query a WMI object. I can use filter, query, where, and select. What is the difference? Does it depend on what you are querying, and is one faster than the other?
-- EJ
Hello EJ,
There are many ways of querying a WMI object. The one I use is the one that pops to mind at the time. If I am working interactively at the Windows PowerShell console, I will often use the alias for the Get-WmiObject cmdlet and the class parameter in the first position without naming the parameter. This is shown here:
Gwmi WIN32_bios
Using the gwmi alias and the WMI class name is faster than spelling out the gwmi alias with the –query parameter. This is seen here:
gwmi –query “Select * from WIN32_bios”
From a results standpoint, both the –query parameter and the -class parameter return the same objects.
The two commands are a lot faster than VBScript (even faster than Scriptomatic). Keep in mind the methods are the same. You may want to look at the WMI Week of Hey, Scripting Guy! articles.
At times, however, I need to use a particular method or functionality because of what I am doing. In general, I would say you should use the syntax that feels natural. When working at the Windows PowerShell command line, I almost never use the –query parameter anymore. I instead use –class filter. I seldom use –property to filter out properties; instead, I generally return the entire object and deal with it in the output in the pipeline. Here are examples of that:
Get-Wmiobject –class WIN32_process –property namePS C:\> Get-Wmiobject -class WIN32_process -property name__GENUS : 2__CLASS : Win32_Process__SUPERCLASS :__DYNASTY :__RELPATH :__PROPERTY_COUNT : 1__DERIVATION : {}__SERVER :__NAMESPACE :__PATH :Name : System Idle Process__GENUS : 2__CLASS : Win32_Process__SUPERCLASS :__DYNASTY :__RELPATH :__PROPERTY_COUNT : 1__DERIVATION : {}__SERVER :__NAMESPACE :__PATH :Name : System__GENUS : 2__CLASS : Win32_Process__SUPERCLASS :__DYNASTY :__RELPATH :__PROPERTY_COUNT : 1__DERIVATION : {}__SERVER :__NAMESPACE :__PATH :<output truncated …>Get-WmiObject –Class WIN32_Process | Select namename----System Idle ProcessSystemsmss.execsrss.exewininit.execsrss.exeservices.exe<output truncated …>
As you can see from the two commands above, the second output is much cleaner. Because of the way that Windows PowerShell returns the system properties as well as the specific property requested in the –property parameter, I always use the second syntax.
Tell Me More About the WMI Shadow Copy Class
Hey Scripting Guy! I need to collect the Volume Shadow Copy configuration status for more than 500 servers. My requirement is to find out which disk has Visual Source Safe (VSS) enabled. Could you help me? I have tried the List All Shadow Copies on a Computer script, and it is giving the output seen here:
ID: {22eb30e2-5c49-4364-bdea-e2149f04524f}Client accessible: TrueCount: 1Device object: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1Differential: TrueExposed locally: FalseExposed name:Exposed remotely: FalseHardware assisted: FalseImported: FalseNo auto release: TrueNot surfaced: FalseNo writers: TrueOriginating machine: css.nwtraders.comPersistent: TruePlex: FalseProvider ID: {b5946137-7b9f-4925-af80-51abd60b20d5}Service machine: css.nwtraders.comSet ID: {6378b765-4392-44a8-8d25-e4faa6ac8250}State: 12Transportable: FalseVolume name: \\?\Volume{e0eb9433-beca-11dd-8163-806e6f6e6963}\
By using the above output, I see that one drive has VSS enabled. However, it does not clearly tell me which drive has VSS enabled. Can you help me?
-- GK
Hello GK,
MSDN documents the WMI shadow copy class. If your volume name is not visible, due to it being hidden, you will need to query the Win32_ShadowVolumeSupport association class.
Troubleshooting an HTA Script
Hey, Scripting Guy! I am trying to create an HTA script that will allow me to use standard Open/Save dialog boxes, so that the client computer can browse for a file or folder and select it, passing the selected item back to my HTA script for processing. This project sounded simple enough. I know that this could be done under Windows XP, but all our machines are currently running Windows Vista.
The first bit of code I tried is seen here:
'Opens Common file dialog allowing file selectionSub fileSelect set objShell = createobject("wscript.shell") strDir = objShell.CurrentDirectory Set ObjFSO = CreateObject("UserAccounts.CommonDialog") ObjFSO.Filter = "All Files|*.*" ObjFSO.InitialDir = strDir InitFSO = ObjFSO.ShowOpen If InitFSO = False Then exit sub Else strFileName.value = ObjFSO.FileName objOpenButton.disabled = "False" objResetButton.disabled = "False" End IfEnd Sub
The script does not work on Windows Vista. I have since found out that the UserAccounts.CommonDialog no longer exists in Windows Vista. Any assistance on this one would be greatly appreciated. By the way, I don’t know if you wrote the extreme makeover HTA tutorial, but it is absolutely fantastic.
-- KA
Hello KA,
I am sorry I do not know of a workaround for your problem. That object was removed because of security issues. But all is not completely lost. The first thing you need to do is to make sure that MSComDlg.CommonDialog progid is registered via MSCOMDLG32.OCX. After this object is registered, you can use the technique shown here. This object does not, however, seem to be available on all systems. It might come via Visual Studio. I am not sure.
'==========================================================================' Function to create a Browse for File Dialog'=========================================================================='Example: BrowseForFile "d:","*.vbs"Function BrowseForFile(pstrPath, pstrFilter) Set objDialog = CreateObject("MSComDlg.CommonDialog") objDialog.Filter = pstrFilter objDialog.InitDir = pstrPath objDialog.MaxFileSize = 256 objDialog.Flags = &H80000 + &H4 + &H8 intResult = objDialog.ShowOpen() BrowseForFile = objDialog.FileNameEnd Function
If you do not have access to MSCOMDLG32.OCX, you still have access to the shell.application object, which has a large number of methods. An example of using BrowseForFolder can be found in our Hey, Scripting Guy! archives.
How Can I Deploy a Windows Service Pack and Ignore Those Computers That Already Have It?
Hey, Scripting Guy! I am looking to deploy Windows XP Service Pack 3. Is there a script that will bypass and ignore machines that already have Service Pack 3? This would be very helpful.
-- AF
Hello AF,
You can do this using WMI. Here are two Windows PowerShell examples.
DetectXP-SP3.ps1
# ------------------------------------------------------------------------# NAME: DetectXP-SP3.ps1# AUTHOR: ed wilson, Microsoft# DATE: 3/31/2009## KEYWORDS: Get-WmiObject## COMMENTS: This script uses the Win32_Operatingsystem# wmi class to detect OS version and SP version### ------------------------------------------------------------------------$os = Get-WmiObject -Class Win32_Operatingsystemif($os.Version -eq "5.1.2600") { if($os.CSDVersion -eq "Service Pack 3") { "XP Service Pack 3 detected" } ELSE { "XP is not Service Pack 3" }exit }"Operating system is not XP"
GetXP-SP3OneLine.ps1
# ------------------------------------------------------------------------# NAME: GetXP-SP3OneLine.ps1# AUTHOR: ed wilson, Microsoft# DATE: 5/31/2009## KEYWORDS: Get-WmiObject## COMMENTS: This script uses a compound wmi query# to return only XP sp3#### ------------------------------------------------------------------------$osVersion = Get-WmiObject -Class Win32_OperatingSystem -Filter "CSDVersion = 'Service Pack 3' AND Version = '5.1.2600'"if($osVersion) {"XP SP3" }ELSE { "XP SP3 not detected" }
Both of these techniques could easily be adapted to VBScript.
Well, this concludes another edition of Quick-Hits Friday. It also concludes another exciting week on the Script Center. Join us next week. Heck, we’re even publishing on Christmas Eve Day and Christmas Day. We’re insane for scripting!
If you want to know exactly what we will be covering next week, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you on Monday. Until then, have an awesome weekend.
Ed Wilson and Craig Liebendorfer, Scripting Guys
I must say you guys have been hard at work!!! I'm still 6 months behind reading the scripts posted here.