PowerShell for Failover Clustering: Understanding Error Codes
Published Mar 15 2019 02:02 PM 1,335 Views
Microsoft
First published on MSDN on Apr 27, 2010

Hi,

This blog is about how to handle error codes returned by PowerShell Failover Clustering CMDlets. For an introduction to this topic you can take a look at http://blogs.msdn.com/clustering/archive/2009/05/23/9636665.aspx .  Cluster CMDlets can fail for various different reasons, such as passing non-existent entities as parameters (try to delete a group using a name that is not present in the cluster); mismatching types (try to pass a string but when a cluster object is required); or when the passed parameter breaks because of some cluster business logic. This blog focuses on how to get error codes from the third type of failure.

Imagine that you are trying to add a cluster node using the Add-ClusterNode CMDlet:

Add-ClusterNode -Name "node1"

If “node1” is not part of any cluster this operation will succeed, otherwise it will fail and you will get the error message:

Add-ClusterNode : The computer 'node1.domain' is joined to a cluster.

At line:1 char:16

+ Add-ClusterNode <<<<  -Name "node1"

+ CategoryInfo          : NotSpecified: (:) [Add-ClusterNode], ClusterCMDletException

+ FullyQualifiedErrorId : Add-ClusterNode,Microsoft.FailoverClusters.PowerShell.AddClusterNodeCommand

Let’s run:

$error[0].Exception | get-Member

This will give us the type of the exception contained in the latest error record.  In this case it will be Microsoft.FailoverClusters.PowerShell.ClusterCMDletException.  When this kind of exception occurs we have a non-terminating error, which means that the CMDlet itself finished its execution properly, however there was some problem with the operation completing successfully.  If the node did not get added to the cluster, since the passed name breaks some cluster business logic.

When writing PowerhShell scripts, one often needs to know not only that the CMDlet finished, but also if its result are as expected.  In order to verify this, an extra step is needed to get the error code embedded on the returned exception.

You can collect the error information with:

$error[0].Exception.ErrorCode

error[0] contains an Exception object (Microsoft.FailoverClusters.PowerShell.ClusterCMDletException), which contains the error code.  For the given example this will return:

$error[0].Exception.ErrorCode

-2147024809

If you want to have the error code in a more readable format you can run:

$error[0].Exception.ErrorCode –band 0xffff

87

So we see this is error code 87.

PowerShell can also be used with managed code.  The error codes can be captured similarly to the console approach described erlier.  Here is an example of code that does that:

System.Management.Automation.PowerShell _powershell = PowerShell.Create();

….

ErrorRecord errRec = _powershell.Streams.Error[0];

PropertyInfo errCodeInfo = null;

int retErrorCode = 0;

Try {

// if the exception is a ClusterCMDletException object we

// should have a property with error code

errCodeInfo = errRec.Exception.GetType().GetProperty("ErrorCode");

} catch (Exception) {

// Handle other type of exceptions differently

}

if (errCodeInfo != null) {

object propValue = errCodeInfo.GetValue(errRec.Exception, null);

retErrorCode = Convert.ToInt32(propValue); // thats and hr Value

retErrorCode = retErrorCode & 0xFFFF;   // this would give the int error code

}

I hope this information is useful for all of you writing PowerShell scripts or C# code.

Thanks,

Emanoel Xavier

Software Development Engineer in Test

Clustering & High-Availability

Microsoft

Version history
Last update:
‎Mar 15 2019 02:02 PM
Updated by: