In this post:

 

Why Are Some Script Repository Scripts Not Showing All Compatible Platforms?

Hey, Scripting Guy! Question

Hey, Scripting Guy! In reference to a script in the Script Repository, it does not show Windows Server 2008 R2 or Windows Server 2008 as being supported platforms, as you can see in the following image.

Image that shows script is not compatible with recent operating systems

It runs on my Windows Server 2008. Did the script simply pre-date the release of the operating system? If so, I think we should be able change the page to a Yes to those platforms.

-- BD

 

Hey, Scripting Guy! AnswerHello BD,

The reason scripts on the Script Repository are not designated as working with Windows Server 2008 R2 or Windows Server 2008 simply means they were written before Windows Server 2008 R2 and Windows Server 2008 were released. It does not necessarily mean they will not work, it means we have not tested them on those platforms. There are thousands of scripts on the Script Repository, and though we test the scripts we post at the time they are posted, we do not have the resources or bandwidth to go back and revisit scripts to update the boxes.

I wish we could allow others to change the boxes, but we cannot open up the permissions like that. So if you find a script that works on another platform, you can post a comment on the script via the Discussions tab. Based on feedback from you and others, we decided to make a change to the “Verified on the following platforms” section of each script’s description. Keep in mind, it does not mean that the Scripting Guys have verified the script works on the checked platforms, but that the person submitting the script thinks it will run on the indicated platforms. The change is shown in the following image.

Image of changed section in script description

 

Addressing a Windows PowerShell Syntax Question

Hey, Scripting Guy! Question

Hey, Scripting Guy! Recently, I was working on a script using Get-Credential, and found an example on the Internet that had this strange syntax:

 

if(!$?) 

{Exit}

It has something to do with clicking Cancel in the Get-Credential window, but what does it actually mean? What would be the correct code without using the symbols?

-- RL

 

Hey, Scripting Guy! AnswerHello RL,

In Windows PowerShell, $? is used to see if the last command completed successfully. If a command completes without error, $? will return True. This is shown here:

 

PS C:\> 1+1

2

PS C:\> $?

True

PS C:\> New-Object foo

New-Object : Cannot find type [foo]: make sure the assembly containing this type is loaded.

At line:1 char:11

+ New-Object <<<<  foo

   
+ CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException

   
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

PS C:\> $?

False

PS C:\>

The ! character, is the not operator. Therefore, the line shown here says if the previous command did not complete successfully, exit.

 

if(!$?) 

{Exit}

What would the code be without the symbols? Well, you could not write this in exactly the same manner. You could write the command without using the ! operator as shown here:

 

if(-not $?) {Exit}

But I am not sure why you would want to do so. Actually, I seldom use $? because it is very rudimentary, and the results can be misleading, as shown here:

 

PS C:\> 1/0

Attempted to divide by zero.

At line:1 char:3

+ 1/ <<<< 0

   
+ CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException

   
+ FullyQualifiedErrorId : RuntimeException

PS C:\> $?

True

PS C:\> New-Object foo

New-Object : Cannot find type [foo]: make sure the assembly containing this type is loaded.

At line:1 char:11

+ New-Object <<<<  foo

   
+ CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException

   
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

PS C:\> $?

False

PS C:\>

Notice that 1/0 does generate an error, but because the command completed, $? reports True. A better indicator of errors is the $error object. The count property will tell you how many errors have occurred. As shown here, there are two errors—not just one. In addition, the $error object contains rich information about the error that was generated. Use the Get-Member cmdlet to examine the error object:

 

PS C:\> $Error

New-Object : Cannot find type [foo]: make sure the assembly containing this type is loaded.

At line:1 char:11

+ New-Object <<<<  foo

   
+ CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException

   
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

Attempted to divide by zero.

PS C:\> $Error.Count

2

PS C:\>

 

Why Is This Script Giving Me so Much Output?

Hey, Scripting Guy! Question

Hey, Scripting Guy! Hope all is going well in scripting world. I'm really liking the new site so far.

I was wondering if you could help shed some light on why when I run the following script I get back way more than I asked for. I know that I can just pipe the output to a Select-Object and narrow down the results but was just hoping to get some insight on why all of those "__*" properties come through. Thanks for any help you can provide!

 

get-wmiobject -query "Select DeviceID,Size,Freespace from Win32_logicaldisk where drivetype=3" -computer "WIN7"

Results:

__GENUS          : 2
__CLASS          : Win32_LogicalDisk
__SUPERCLASS     : 
__DYNASTY        : 
__RELPATH        : Win32_LogicalDisk.DeviceID="C:"
__PROPERTY_COUNT : 3
__DERIVATION     : {}
__SERVER         : 
__NAMESPACE      : 
__PATH           : 
DeviceID         : C:
FreeSpace        : 8585277440
Size             : 54523850752

Expected Results:

FreeSpace : 8636874752
Size      : 54523850752
DeviceID  : C:

-- AN

 

Hey, Scripting Guy! AnswerHello AN,

Those are the system properties of the WMI object. They actually offer some really cool information (at least for someone who wrote a WMI book, such as yours truly). For example, -relpath can be used by the WMI instance accelerator like this:

 

__RELPATH        : Win32_LogicalDisk.DeviceID="C:"

Here is the cool code. Put WMI in square brackets to retrieve a specific instance of a WMI class:

 

PS C:\> [wmi]'Win32_LogicalDisk.DeviceID="C:"'

DeviceID     : C:

DriveType    : 3

ProviderName :

FreeSpace    : 36409507840

Size         : 158391595008

VolumeName   :

PS C:\>

The __Server property often tells you the name of the machine that is supplying the data. Here, it is not showing up. Note that when you use the –property parameter, you also get the system properties:

 

PS C:\> gwmi win32_logicaldisk -Property deviceID, Size, FreeSpace

__GENUS          : 2

__CLASS          : Win32_LogicalDisk

__SUPERCLASS     :

__DYNASTY        :

__RELPATH        : Win32_LogicalDisk.DeviceID="C:"

__PROPERTY_COUNT : 3

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

DeviceID         : C:

FreeSpace        : 36409585664

Size             : 158391595008

When directly querying without any parameters, we get nice pretty output:

Size         : 158391595008 PS C:\> gwmi win32_logicaldisk

DeviceID     : C:

DriveType    : 3

ProviderName :

FreeSpace    : 36409585664

VolumeName   :

The pretty output is due to the format XML file that controls the output for the win32_logicaldisk WMI class. The Windows PowerShell team has done this for dozens of commonly used WMI classes. What I teach in my various Windows PowerShell books is this:

 

PS C:\> gwmi win32_logicaldisk -Property deviceID, Freespace, Size | Format-List [a-z]*

DeviceID         : C:

FreeSpace        : 36410626048

Size             : 158391595008

Scope            : System.Management.ManagementScope

Path             : Win32_LogicalDisk.DeviceID="C:"

Options          : System.Management.ObjectGetOptions

ClassPath        : Win32_LogicalDisk

Properties       : {DeviceID, FreeSpace, Size}

SystemProperties : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...}

Qualifiers       : {dynamic, Locale, provider, UUID}

Site             :

Container        :

 

However, in Windows PowerShell 2.0 we decided to display additional properties. So now we are down to using wildcard characters as shown here:

 

PS C:\> gwmi win32_logicaldisk -Property deviceID, Freespace, Size | Format-List dev*,fre*,siz*

DeviceID  : C:

FreeSpace : 36410560512

Size      : 158391595008

DeviceID  : D:

FreeSpace :

Size      :

DeviceID  : Q:

FreeSpace :

Size      :

Keep in mind, that choosing the three specific properties does not improve performance because WMI still has to retrieve the entire instance of the classes. You get back a custom object, but that is because of Windows PowerShell, not WMI. You are better off doing your display filtering, rather than the double work of selecting properties, and then reselecting them for format list.

 

Well, this concludes another edition of Quick-Hits Friday. Join us tomorrow for the Weekend Scripter as we delve into the mysteries of…well, we will let that remain a mystery for now.

If you want to know exactly what we will be looking at tomorrow, 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 tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys