Hey, Scripting Guy! Quick-Hits Friday: The Scripting Guys Respond to a Bunch of Questions (8/7/09)

Hey, Scripting Guy! Quick-Hits Friday: The Scripting Guys Respond to a Bunch of Questions (8/7/09)

  • Comments 1
  • Likes

 

Does Windows PowerShell Let Me Trap Errors?

Hey, Scripting Guy! Question

Hey Scripting Guy! Does Windows PowerShell have the ability to trap errors?

-- JP

 

Hey, Scripting Guy! Answer

Hello JP,

Yes, it does. Here is an example of using the trap statement in a script.

DemoTrapSystemException.ps1

# ------------------------------------------------------------------------
# NAME: DemoTrapSystemException.ps1
# AUTHOR: ed wilson, Microsoft
# DATE: 8/6/2009
#
# KEYWORDS: Demo, Error Trap, Trap Error
#
# COMMENTS: This illustrates trapping an error.
# $ErrorActionPreference will control NON-Terminating errors.
# Trap will control Terminiating errors.
# Try the different error action preferences: stop, continue, silentlycontinue, inquire
# [SystemException] is the grand daddy of all exceptions.
# ------------------------------------------------------------------------
Function My-Test( [int]$myinput)
{
 
 "It worked"
} #End my-test function
# *** Entry Point to Script ***

#$ErrorActionPreference = "Stop"
Trap [SystemException] { "error trapped" ; continue }
My-Test -myinput "string"
"After the error"

 

Can I Use the Win32_PingStatus WMI Class with Windows PowerShell?

Hey, Scripting Guy! Question

 

 

Hey Scripting Guy! I have seen VBScripts that use the Win32_PingStatus WMI class, but I cannot find an example using it from Windows PowerShell. Can you hook me up with an example?

-- DD

 

Hey, Scripting Guy! Answer

Hello DD,

SendPing.ps1 is an example of using the Win32_PingStatus WMI class inside a script. Each of the different values of the statuscode is documented on MSDN.

SendPing.ps1

$computer = "Localhost"
$rtn = get-wmiobject -class win32_pingstatus -filter "Address = '$computer'"
If($rtn.StatusCode -ne 0) { "$computer is not reachable" }
ELSE {"Reply from $computer"}

 

Can I Skip Over a WMI Command That Is Generating an Error in a Windows PowerShell Script?

Hey, Scripting Guy! Question

Hey Scripting Guy!

I have a Windows PowerShell script that keeps generating an error when I run it. I would like to be able to skip over the WMI command that is generating the error, but there are two problems. The first is that I do not want to put On Error Resume Next (or the Windows PowerShell equivalent) at the top of my script. The second problem is I do not know the Windows PowerShell equivalent to On Error Resume Next. Can you help me?

-- GG

 

Hey, Scripting Guy! AnswerHello GG,

Of course we can help you. First of all, the Windows PowerShell equivalent to On Error Resume Next is the keyword SilentlyContinue. In Windows PowerShell, there are a couple of places this can be applied. At the top of a script, for example, it can be applied to the automatic variable $ErrorActionPreference. To illustrate this point, perform a directory listing of the root of your HKEY_LOCAL_MACHINE registry hive. On my computer (Windows 7), this command completes by default, but it generates errors. The reason the command completes is that by default the value for $ErrorActionPreference is Continue, which means the errors are displayed, but the command will attempt to complete. The directory listing command is seen here.

ListHKLM.ps1

"Directory listing of HKLM"
dir HKLM:

When I run this ListHKM.ps1 script, the following output is displayed:

Directory listing of HKLM
Get-ChildItem : Requested registry access is not allowed.
At line:3 char:4
+ dir <<<<  HKLM:
    + CategoryInfo          : PermissionDenied: (HKEY_LOCAL_MACHINE\BCD00000000:String) [
   Get-ChildItem], SecurityException
    + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Comm
   ands.GetChildItemCommand
 


    Hive: HKEY_LOCAL_MACHINE


SKC  VC Name                           Property                                          
---  -- ----                           --------                                          
  4   0 HARDWARE                       {}                                                
  1   0 SAM                            {}                                                
Get-ChildItem : Requested registry access is not allowed.
At line:3 char:4
+ dir <<<<  HKLM:
    + CategoryInfo          : PermissionDenied: (HKEY_LOCAL_MACHINE\SECURITY:String) [Get
   -ChildItem], SecurityException
    + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Comm
   ands.GetChildItemCommand
 
 23   1 SOFTWARE                       {(default)}                                       
  8   0 SYSTEM                         {}
 

This output can be rather distracting for a user. To correct this situation, most people coming from a VBScript background will add the $ErrorActionPreference = ”SilentlyContinue” at the top of their script, as seen here.

ErrorActionSilentlyContinue.ps1

$ErrorActionPreference = "SilentlyContinue"
"Directory listing of HKLM"
dir HKLM:

When the ErrorActionSilentlyContinue.ps1 script is run, the following output is seen:

Directory listing of HKLM


    Hive: HKEY_LOCAL_MACHINE


SKC  VC Name                           Property                                          
---  -- ----                           --------                                           
  4   0 HARDWARE                       {}                                                
  1   0 SAM                            {}                                                
 23   1 SOFTWARE                       {(default)}                                       
  8   0 SYSTEM                         {}
        

One of the cool things about working with Windows PowerShell is that it is very flexible. If you do not want to add the $ErrorActionPreference command at the top of your script, you are not required to do so. You can apply it at the cmdlet level. The Dir command in Windows PowerShell is an alias for the Get-ChildItem cmdlet. As a general rule, I do not like to use aliases in a script because it is not guaranteed that the alias will be present. In addition, using aliases actually makes learning Windows PowerShell more difficult. If you think of the Dir command as the Dir command from the old DOS days, you might not be too inquisitive about what it is able to do. In fact, you will become frustrated with the fact that it does not always behave like the DOS DIR command. If you realize that it is in fact an alias for the Get-ChildItem cmdlet, you may become curious as to what you can do with the Get-ChildItem cmdlet and look it up by using the following command:

Help Get-ChildItem –full

When you look up the parameters for the Get-ChildItem cmdlet, you will find there is an erroraction parameter. This allows you to specify the erroractionpreference value for each cmdlet. Because the erroraction is available for all of the cmdlets, it is called a common parameter. You can find out about all of the common parameters by using Help. This is seen here:

Help *commonparameter*

To use the common parameter erroraction in your script, you specify the parameter and supply the value. This is seen here.

CommonParameter.ps1

"Directory listing of HKLM"

Get-ChildItem -Path HKLM: -ErrorAction SilentlyContinue

Keep in mind that all the extra typing is not really required. You can type this command as seen here by using dir as an alias for the Get-ChildItem cmdlet, and the first position as the default parameter for the path parameter. The ea works because it is an alias for the erroraction parameter.

dir HKLM: -ea silentlycontinue

One thing to keep in mind about error action is that it is for non-terminating errors. For terminating errors, you will need to use the trap statement we looked at earlier.


 

Can I Read a PDF File with VBScript Automation Testing?

Hey, Scripting Guy! Question

Hey Scripting Guy! I am trying to do some automation testing using VBScript, and I need to be able to read the contents of a PDF file. I have found many examples of reading text files, Office Word files, Excel files, PowerPoint files, and even Access databases, but I do not see how to read a PDF file. Please help me soon. This project is falling behind.

-- MK

 

Hey, Scripting Guy! Answer

Hello MK,

Your project just took a turn for the worse, I am afraid. The PDF format is a proprietary format created by Adobe. If they do not provide an API to read the file, we cannot do so for you. If they have an API, it would be documented on their Web site. If they have an API and if it is scriptable, it is as simple as using the CreateObject command to create the object, and calling the appropriate method to read the file, storing the results in a variable, and walking through the collection. However, if they don’t have an API, you will be completely stuck.

 

Can I Determine the Last User to Log On to a Windows Vista Computer?

Hey, Scripting Guy! Question

Hey Scripting Guy! I find your site to be a very good resource for my scripting career.  I’m looking at your script you provided in the How Can I Get the Name of the Last User to Log on to a Computer? article, but this script does not seem to apply to a Windows Vista workstation. I get a result of a blank value for both the DefaultUserName and the DefaultDomainName registry keys. Do you have any way around that? I’m checking the load of information through WMI on Windows Vista computers in our organization, but cannot locate a similar field that would contain the same information.

--LG

 

 

 

Hey, Scripting Guy! Answer

Hello LG,

The script you refer to was written before Windows Vista came out, so it is not surprising that the values in the registry are not updated. But it was worth a shot because lots of things in the registry from Windows XP and before still apply in Windows Vista and later. We try very hard to maintain backward compatibility.

On my Windows 7 computer, the DefaultUserName registry key you refer to reports Administrator. (I cannot tell you when the last time I logged on to my computer using the Administrator account.) This is seen here:

Image of the DefaultUserName registry key reporting Administrator

Therefore, you are correct. The DefaultUserName value is not updated on Windows Vista or on Windows 7. Unfortunately, there is no WMI class that will provide you “the last person” to log on to the computer. You can get the current person, but not the last person.

All is not lost, however. Take a look at the How Can I Tell When I last Logged On? article I wrote last year. The script uses Windows PowerShell, but if you need to use VBScript it could be easily adapted. What I did was create my own registry key. This way I know what is stored, and when it gets stored in the registry key. You could use such a thing to write the username and time if you wish. Keep in mind that in my scenario I am using the HKCU hive, which, will of course, change for each user. If you want to write to the HKLM hive, you will, of course, need to modify the rights to the registry key to allow your authenticated users to write to it. Hope this helps.

 

Well, LG, yours is the last e-mail we will get to this week. Join the Scripting Guys on Monday as we begin the 2009 Summer Scripting Games wrap-up sessions. If you want to know in advance what that article will be about, follow us on Twitter or on Facebook. If you run into problems with your scripts, you can always shoot us e-mail at scripter@microsoft.com, or you can post questions to the Official Scripting Guys Forum. We hope you have an awesome weekend. (Personally, I [Ed Wilson] will be finishing chapter 15 of my Windows PowerShell Best Practices book that I am writing for MSPress. If you want to know all the details, you can friend me on Facebook. Craig’s daughter will be in the first three of nine performances of The Music Man, so that’s what he’s up to this weekend.) Until Monday, take care.


Ed Wilson and Craig Liebendorfer, Scripting Guys

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • man, i really wish you'd mentioned how not to get registry permission errors in the first place. i can't for the life of me figure that out today.