Windows Vista Forums
Vista Forums Home Join Vista Forums Donate Vista Tutorials Tags

Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > PowerShell

Error Handling

Closed Thread
 
Thread Tools Display Modes
Old 10-01-2007   #1 (permalink)
Jacob
Guest
 
Posts: n/a

Error Handling

Hi all,
I am having some trouble understanding how to use error control in Powershell.

In VBSCript I use to do something like:
If Err Then
Wscript.Echo Err.Description
Exit Function
End If

In Powershell I am trying to do this:
function Get-RemotePNP ([string]$computer=$(throw "You must specifiy list of
computers to query computer to query")){

trap {
#Some code do write error to a file.
break;
}

#attempt to ping this first.
$PNPEntity = Get-WmiObject "Win32_PnPEntity" -ComputerName $computer
-ErrorAction "silentlycontinue"

#More statements below

}

For some reason my script continue to execute even when there is an error
with the Get-WmiObject. Should the break in the trap statement stop the
function from proceeding.

How do I achieve what the vbscript sample achieves?

--
**********************
Jacob

 
Old 10-01-2007   #2 (permalink)
Jeff
Guest
 
Posts: n/a

Re: Error Handling

On Oct 2, 8:25 am, Jacob <jacob(AT)hfws.net.nospam> wrote:
Quote:

> Hi all,
> I am having some trouble understanding how to use error control in Powershell.
>
> In VBSCript I use to do something like:
> If Err Then
> Wscript.Echo Err.Description
> Exit Function
> End If
>
> In Powershell I am trying to do this:
> function Get-RemotePNP ([string]$computer=$(throw "You must specifiy list of
> computers to query computer to query")){
>
> trap {
> #Some code do write error to a file.
> break;
> }
>
> #attempt to ping this first.
> $PNPEntity = Get-WmiObject "Win32_PnPEntity" -ComputerName $computer
> -ErrorAction "silentlycontinue"
>
> #More statements below
>
> }
>
> For some reason my script continue to execute even when there is an error
> with the Get-WmiObject. Should the break in the trap statement stop the
> function from proceeding.
>
> How do I achieve what the vbscript sample achieves?
>
> --
> **********************
> Jacob
Control is only transferred to the body of a trap statement when a
terminating error occurs, which isn't what you get from your call to
Get-WmiObject. There are probably many ways to do what you want to
do; this is one:

# your statements...

if ( $? )
{
# all is well
}
else
{
# an error occurred
}

$? is a Boolean value that holds the status of the last operation:
success or failure. You might also want to look at $LASTEXITCODE; it
actually contains the exit code of the last command.

For more information about these and other automatic variables, type
"Get-Help about_automatic_variables".

Good luck.

Jeff

 
Old 10-01-2007   #3 (permalink)
Jacob
Guest
 
Posts: n/a

Re: Error Handling

Hi Jeff,
Thanks for your reply.

I'm still struggling with this. I have it sort of working for Get-WmiObject
but when i run this line:
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',
$computer)

It just outputs the red text.

In VBScript I've always had a logging class that I used to make log file of
errors when i script is running.

Is there a way to do this in powershell. Intercept the error, Don't display
it to the console, and write it to a log file.

Sure there is a powershell equivalent to:
If Err Then
LogEntrySub "Something went wrong."
Exit Function
End If

Thanks for your help.


--
**********************
Jacob



"Jeff" wrote:
Quote:

> On Oct 2, 8:25 am, Jacob <jacob(AT)hfws.net.nospam> wrote:
Quote:

> > Hi all,
> > I am having some trouble understanding how to use error control in Powershell.
> >
> > In VBSCript I use to do something like:
> > If Err Then
> > Wscript.Echo Err.Description
> > Exit Function
> > End If
> >
> > In Powershell I am trying to do this:
> > function Get-RemotePNP ([string]$computer=$(throw "You must specifiy list of
> > computers to query computer to query")){
> >
> > trap {
> > #Some code do write error to a file.
> > break;
> > }
> >
> > #attempt to ping this first.
> > $PNPEntity = Get-WmiObject "Win32_PnPEntity" -ComputerName $computer
> > -ErrorAction "silentlycontinue"
> >
> > #More statements below
> >
> > }
> >
> > For some reason my script continue to execute even when there is an error
> > with the Get-WmiObject. Should the break in the trap statement stop the
> > function from proceeding.
> >
> > How do I achieve what the vbscript sample achieves?
> >
> > --
> > **********************
> > Jacob
>
> Control is only transferred to the body of a trap statement when a
> terminating error occurs, which isn't what you get from your call to
> Get-WmiObject. There are probably many ways to do what you want to
> do; this is one:
>
> # your statements...
>
> if ( $? )
> {
> # all is well
> }
> else
> {
> # an error occurred
> }
>
> $? is a Boolean value that holds the status of the last operation:
> success or failure. You might also want to look at $LASTEXITCODE; it
> actually contains the exit code of the last command.
>
> For more information about these and other automatic variables, type
> "Get-Help about_automatic_variables".
>
> Good luck.
>
> Jeff
>
>
 
Old 10-01-2007   #4 (permalink)
Brandon Shell
Guest
 
Posts: n/a

Re: Error Handling

In your trap try this

Trap { Write-Ouput $_ | out-file Error.log -app -enc ascii ; continue}

"Jacob" <jacob(AT)hfws.net.nospam> wrote in message
news:4BFB3036-91EB-4EEE-9707-0D47A7A74715@xxxxxx
Quote:

> Hi Jeff,
> Thanks for your reply.
>
> I'm still struggling with this. I have it sort of working for
> Get-WmiObject
> but when i run this line:
> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',
> $computer)
>
> It just outputs the red text.
>
> In VBScript I've always had a logging class that I used to make log file
> of
> errors when i script is running.
>
> Is there a way to do this in powershell. Intercept the error, Don't
> display
> it to the console, and write it to a log file.
>
> Sure there is a powershell equivalent to:
> If Err Then
> LogEntrySub "Something went wrong."
> Exit Function
> End If
>
> Thanks for your help.
>
>
> --
> **********************
> Jacob
>
>
>
> "Jeff" wrote:
>
Quote:

>> On Oct 2, 8:25 am, Jacob <jacob(AT)hfws.net.nospam> wrote:
Quote:

>> > Hi all,
>> > I am having some trouble understanding how to use error control in
>> > Powershell.
>> >
>> > In VBSCript I use to do something like:
>> > If Err Then
>> > Wscript.Echo Err.Description
>> > Exit Function
>> > End If
>> >
>> > In Powershell I am trying to do this:
>> > function Get-RemotePNP ([string]$computer=$(throw "You must specifiy
>> > list of
>> > computers to query computer to query")){
>> >
>> > trap {
>> > #Some code do write error to a file.
>> > break;
>> > }
>> >
>> > #attempt to ping this first.
>> > $PNPEntity = Get-WmiObject "Win32_PnPEntity" -ComputerName
>> > $computer
>> > -ErrorAction "silentlycontinue"
>> >
>> > #More statements below
>> >
>> > }
>> >
>> > For some reason my script continue to execute even when there is an
>> > error
>> > with the Get-WmiObject. Should the break in the trap statement stop the
>> > function from proceeding.
>> >
>> > How do I achieve what the vbscript sample achieves?
>> >
>> > --
>> > **********************
>> > Jacob
>>
>> Control is only transferred to the body of a trap statement when a
>> terminating error occurs, which isn't what you get from your call to
>> Get-WmiObject. There are probably many ways to do what you want to
>> do; this is one:
>>
>> # your statements...
>>
>> if ( $? )
>> {
>> # all is well
>> }
>> else
>> {
>> # an error occurred
>> }
>>
>> $? is a Boolean value that holds the status of the last operation:
>> success or failure. You might also want to look at $LASTEXITCODE; it
>> actually contains the exit code of the last command.
>>
>> For more information about these and other automatic variables, type
>> "Get-Help about_automatic_variables".
>>
>> Good luck.
>>
>> Jeff
>>
>>
 
Old 10-01-2007   #5 (permalink)
Jeff
Guest
 
Posts: n/a

Re: Error Handling

On Oct 2, 9:46 am, Jacob <jacob(AT)hfws.net.nospam> wrote:
Quote:

> Hi Jeff,
> Thanks for your reply.
>
> I'm still struggling with this. I have it sort of working for Get-WmiObject
> but when i run this line:
> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',
> $computer)
>
> It just outputs the red text.
>
> In VBScript I've always had a logging class that I used to make log file of
> errors when i script is running.
>
> Is there a way to do this in powershell. Intercept the error, Don't display
> it to the console, and write it to a log file.
>
> Sure there is a powershell equivalent to:
> If Err Then
> LogEntrySub "Something went wrong."
> Exit Function
> End If
>
> Thanks for your help.
I don't think I'm familiar enough with VBScript to give you a
PowerShell example that is exactly equivalent to your VBScript
example. If you don't want to see the red error messages in the
console while your script is running, but you want the errors written
to a file, you can use redirection:

PS$ .\SomeScriptWithErrors.ps1 "argument1" "argument2" 2> "errors.log"

Normal output from your script will still go to the console, but the
'>2' operator redirects errors to "errors.log". For other
combinations of regular results and errors, see the "Redirection
Operators" section in "about_operators".

Jeff

 
Old 10-01-2007   #6 (permalink)
Jeff
Guest
 
Posts: n/a

Re: Error Handling

On Oct 2, 9:46 am, Jacob <jacob(AT)hfws.net.nospam> wrote:
Quote:

> Hi Jeff,
> Thanks for your reply.
>
> I'm still struggling with this. I have it sort of working for Get-WmiObject
> but when i run this line:
> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',
> $computer)
>
> It just outputs the red text.
>
> In VBScript I've always had a logging class that I used to make log file of
> errors when i script is running.
>
> Is there a way to do this in powershell. Intercept the error, Don't display
> it to the console, and write it to a log file.
>
> Sure there is a powershell equivalent to:
> If Err Then
> LogEntrySub "Something went wrong."
> Exit Function
> End If
>
> Thanks for your help.
>
One more thing that might get you closer to what you want with your
last example:

& {
$ErrorActionPreference = "SilentlyContinue"

trap
{
"Error!"
# log your error, exit, or whatever
}

$hive = "LocalMachine"
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, `
$computer)
}

OpenRemoteBaseKey does throw an exception, so you can use a trap
statement here. I am setting the $ErrorActionPreference variable in a
scriptblock so its old value will be restored outside of the
scriptblock's scope.

Good luck.

Jeff

 
Old 10-02-2007   #7 (permalink)
Jacob
Guest
 
Posts: n/a

Re: Error Handling

My Script is below. It seems to work but I don't get an xml file at the end???


#
//***************************************************************************
# // ***** Script Header *****
# //
# // File: Get-PNPInfo.ps1
# //
# // Purpose: Given a list of Computers will query for PNP Device IDS
# //
# // Usage: powershell .\Get-PNPInfo.ps1 [collection of computers]
# //
# // Notes:
#
//***************************************************************************
Param
(
[array]$computers =$(throw "You must specify an array of computers")
)
$ErrorActionPreference="SilentlyContinue"

for ($i=0;$i -le $computers.length; $i++) {
[int]$progress = ($i * 100) / $computers.Length
Write-Progress -activity "Querying Remote PNP Information" -Status
"Currently Querying $($computers[$i])" -perc $progress

#Attempt to ping the machine
Write-Progress -activity "Details for $($computers[$i])" -id 1 -status
"Trying to ping workstation." -perc 16
$response = Get-WmiObject -query "Select * From Win32_PingStatus Where
Address='$($computers[$i])'"

if( ($response -eq $null) -or ($response.StatusCode -ne 0)) {
Write-Progress -activity "Details for $($computers[$i])" -id 1 -status
"Could not ping workstation" -perc 100
} else {
Write-Progress -activity "Details for $($computers[$i])" -id 1 -status
"Getting remote WMI and Registry" -perc 32
$PNPEntity = Get-WmiObject "Win32_PnPEntity" -ComputerName $computers[$i]
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',
$computer)

#if $reg or wmi action action failed then don't continue.
if ($?)
{
#Create the XML File
$XMLFile = [xml]'<?xml version="1.0"
encoding="utf-8"?><SystemAudit><Devices></Devices></SystemAudit>'
$XMLDevices = $XMLFile.PSBase.SelectSingleNode("//Devices")

foreach ( $device in $PNPEntity) {
$deviceID = $device.PNPDeviceID
Write-Progress -activity "Details for $($computers[$i])" -id 1
-status "Found Key: $deviceID" -perc 48
#create a new entry in the xml file.
$XMLDevice = $XMLFile.CreateElement("Device")
$id = $XMLFile.CreateAttribute("Id")
$id.psbase.Value = $deviceID
$return = $XMLDevice.SetAttributeNode($id)

Write-Progress -activity "Details for $($computers[$i])" -id 1
-status "Getting hardware IDs" -perc 64
#Get HardwareIds and Compatible IDS
#trap{continue}
$devEnum = $reg.OpenSubKey("SYSTEM\CurrentControlSet\Enum\$deviceID")
$hwids = $devEnum.GetValue("HardwareID")
$compatIDs = $devEnum.GetValue("CompatibleIDs")

#List HardwareIDs
if ( -not ($hwids -eq $null) ) {
foreach ($hwid in $hwids) {
$XMLHwid = $XMLFile.CreateElement("HwId")
$attribute = $XMLFile.CreateAttribute("Id")
$attribute.psbase.Value = $hwid
$return = $XMLHwid.SetAttributeNode($attribute)
$return = $XMLDevice.AppendChild($XMLHwid)
}
}

Write-Progress -activity "Details for $($computers[$i])" -id 1
-status "Getting Driver Information" -perc 80
#Get Driver Information
$driver =
$reg.OpenSubKey("SYSTEM\CurrentControlSet\Control\Class\$($devEnum.GetValue('Driver'))")

#XML Element and Attributes for Driver Information
$installedDriver = $XMLFile.CreateElement("InstalledDriver")

$MatchingDeviceId = $XMLFile.CreateAttribute("MatchingDeviceId")
$MatchingDeviceId.psbase.Value = $driver.GetValue("MatchingDeviceId")
$return = $installedDriver.SetAttributeNode($MatchingDeviceId)

$DriverDesc = $XMLFile.CreateAttribute("DriverDesc")
$DriverDesc.psbase.Value = $driver.GetValue("DriverDesc")
$return = $installedDriver.SetAttributeNode($DriverDesc)

$DriverVerDate = $XMLFile.CreateAttribute("DriverVerDate")
$DriverVerDate.psbase.Value = $driver.GetValue("DriverDate")
$return = $installedDriver.SetAttributeNode($DriverVerDate)

$DriverVerVersion =$XMLFile.CreateAttribute("DriverVerVersion")
$DriverVerVersion.psbase.Value = $driver.GetValue("DriverVersion")
$return = $installedDriver.SetAttributeNode($DriverVerVersion)

$Class = $XMLFile.CreateAttribute("Class")
$Class.psbase.Value = $devEnum.GetValue("Class")
$return = $installedDriver.SetAttributeNode($Class)

$Manufacturer = $XMLFile.CreateAttribute("Manufacturer")
$Manufacturer.psbase.Value = $devEnum.GetValue("Mfg")
$return = $installedDriver.SetAttributeNode($Manufacturer)

$Provider = $XMLFile.CreateAttribute("Provider")
$Provider.psbase.Value = $driver.GetValue("ProviderName")
$return = $installedDriver.SetAttributeNode($Provider)

$Model = $XMLFile.CreateAttribute("Model")
$Model.psbase.Value = $driver.GetValue("DriverDesc")
$return = $installedDriver.SetAttributeNode($Model)

#Add the installedDrivers to the Device Node
$return = $XMLDevice.AppendChild($installedDriver)

#add this device to the XML File
$return = $XMLDevices.AppendChild($XMLDevice)
}
Write-Progress -activity "Details for $($computers[$i])" -id 1 -status
"Writing XML File" -perc 100
$XMLFile.Save("output.xml")
}
}
}




--
**********************
Jacob



"Jeff" wrote:
Quote:

> On Oct 2, 9:46 am, Jacob <jacob(AT)hfws.net.nospam> wrote:
Quote:

> > Hi Jeff,
> > Thanks for your reply.
> >
> > I'm still struggling with this. I have it sort of working for Get-WmiObject
> > but when i run this line:
> > $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',
> > $computer)
> >
> > It just outputs the red text.
> >
> > In VBScript I've always had a logging class that I used to make log file of
> > errors when i script is running.
> >
> > Is there a way to do this in powershell. Intercept the error, Don't display
> > it to the console, and write it to a log file.
> >
> > Sure there is a powershell equivalent to:
> > If Err Then
> > LogEntrySub "Something went wrong."
> > Exit Function
> > End If
> >
> > Thanks for your help.
> >
>
> One more thing that might get you closer to what you want with your
> last example:
>
> & {
> $ErrorActionPreference = "SilentlyContinue"
>
> trap
> {
> "Error!"
> # log your error, exit, or whatever
> }
>
> $hive = "LocalMachine"
> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, `
> $computer)
> }
>
> OpenRemoteBaseKey does throw an exception, so you can use a trap
> statement here. I am setting the $ErrorActionPreference variable in a
> scriptblock so its old value will be restored outside of the
> scriptblock's scope.
>
> Good luck.
>
> Jeff
>
>
 
Old 10-02-2007   #8 (permalink)
Jeff
Guest
 
Posts: n/a

Re: Error Handling

On Oct 2, 12:24 pm, Jacob <jacob(AT)hfws.net.nospam> wrote:
Quote:

> My Script is below. It seems to work but I don't get an xml file at the end???
Try this, if you want output.xml to end up in your current directory:

$XMLFile.Save("$(Get-Location)\output.xml")

Your file is likely ending up in your $home directory. Type "Set-
Location $HOME", and you will probably find your XML file.

Jeff

 
Old 10-02-2007   #9 (permalink)
Keith Hill [MVP]
Guest
 
Posts: n/a

Re: Error Handling

"Jacob" <jacob(AT)hfws.net.nospam> wrote in message
news9E432AF-B7C5-4D01-AA99-0F71CFAE3E82@xxxxxx
Quote:

> Hi all,
> I am having some trouble understanding how to use error control in
> Powershell.
>
> In VBSCript I use to do something like:
> If Err Then
> Wscript.Echo Err.Description
> Exit Function
> End If
>
> In Powershell I am trying to do this:
> function Get-RemotePNP ([string]$computer=$(throw "You must specifiy list
> of
> computers to query computer to query")){
>
> trap {
> #Some code do write error to a file.
> break;
> }
>
> #attempt to ping this first.
> $PNPEntity = Get-WmiObject "Win32_PnPEntity" -ComputerName $computer
> -ErrorAction "silentlycontinue"
>
> #More statements below
>
> }
>
> For some reason my script continue to execute even when there is an error
> with the Get-WmiObject. Should the break in the trap statement stop the
> function from proceeding.
That is because Get-WmiObject errors are normally "non-terminating".
PowerShell has the concept of terminating errors (usually program logic
errors like deferencing $null in a .NET method call or integer divide by
zero or you use the throw statemement) and non-terminating errors
Get-WmiObject failed to complete for some reason. The trap statement only
traps terminating errors to get Get-WmiObject to throw a terminating error
do either:

Get-WmiObject -errorAction Stop ...

or

Get-WmiObject -errorAction SilentlyContinue ...
if (!$?) {
# If previous command failed, throw the last error
throw $error[0]
}

Of course the second version is essentially doing the same thing as the
first but I point it out in case you wanted to throw a different type of
error or perhaps your own error message e.g.:

if (!$?) { throw "Errored finding WMI Object" }

--
Keith


 
 
Closed Thread

Thread Tools
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Quick Question about Error Handling greatbarrier86 PowerShell 29 01-25-2008 10:34 PM
error handling MaxMad PowerShell 3 12-18-2007 12:07 AM
Crash Course in Error Handling? greatbarrier86 PowerShell 1 11-12-2007 01:11 PM
VBScript vs. PowerShell error handling Matt PowerShell 3 07-02-2007 12:26 PM
Error handling in scripts question Keith Hill [MVP] PowerShell 2 05-01-2007 12:31 AM








Vistax64.com is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media 2005-2008

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49