Microsoft Virtualization Discussions

format-table error with Get-NaSnapmirror (only in script!)

robert_updegraff
4,144 Views

Explain this one to me... When I run commands at the commandline to gather SnapMirror data into a variable, then display it with Format-Table it works great. If I run the same exact commands in a script, I get an error on the Format-Table command. See the examples below. Any ideas?

*** From the commandline

PS C:\Download> $sm = Get-NaSnapmirror

PS C:\Download> $sm | format-table

Source                               Destination                          Status         State                LagTimeTS

------                               -----------                          ------         -----                ---------

ausap1npsca01_ausad1npsca01_13214... ausad1npsca01:dfm_mirror_ausap1np... idle           snapmirrored          00:49:49

ausap1npsca01_ausad1npsca01_13214... ausad1npsca01:dfm_mirror_ausap1np... idle           snapmirrored          00:49:15

ausap1npsca01_ausad1npsca01_13214... ausad1npsca01:dfm_mirror_ausap1np... idle           snapmirrored          00:50:34

*** The script

# Add the vSphere PowerCLI SnapIn and the DATA ONTAP Module

Import-module DataONTAP

# Use the Show-NaHelp command to show web based documentation on the NetApp Powershell Toolkit

$Filer = "controllername"

# Create a Credential Object for login to the Filer

$Credentials = Get-Credential root

# Connect to NetApp Filer

Connect-NaController $Filer -Credential $Credentials

$SnapMirror = Get-NaSnapmirror

$SnapMirror | format-table

*** Output from the script while running in the Windows Powershell ISE

PS C:\Users\bob.updegraff> C:\Download\SnapMirrorReport.ps1

 

Name                 Address           Ontapi   Version                                                                                                                                                                          

----                 -------           ------   -------

ausad1npsca01        10.1.211.180      1.15     NetApp Release 8.1 7-Mode: Thu Mar 29 13:56:17 PDT 2012                                                                                                                          

The object of type "Microsoft.PowerShell.Commands.Internal.Format.FormatStartData" is not valid or not in the correct sequence. This is likely caused by a user-specified "format-table" command which is conflicting with the defa

ult formatting.

    + CategoryInfo          : InvalidData: (:) [out-lineoutput], InvalidOperationException

    + FullyQualifiedErrorId : ConsoleLineOutputOutOfSequencePacket,Microsoft.PowerShell.Commands.OutLineOutputCommand

1 ACCEPTED SOLUTION

sizemore
4,144 Views

Hey Rob,

Your running into a bug in PowerShell's default formatting. The problem is when you run a script, and don't explicitly handle the scripts output. The first command that emits any object will set the formatting for the remainder of the script. In this case the Connect-NaController cmdlet emits a NaController object to out-host. Since Out-Host was handed an unformatted object it in turn calls out-default. Out-Default determines that the default format for a NaController is to use a table. So Out-Default then hands the NaController object to Format-Table who writes the format objects to out-host. That's a deep dive into the pipeline i know but it's necessary because of what happens next.

Since we're still in a script block the output pipeline stays connected to Format-Table. With the pipeline all setup to take objects and pass them through Format-Table on the way to Out-Host. You're then getting a list of snapmirror object, and formatting them into a table. Again since you’re not explicitly handling the output of the pipeline, all object emitted follow that same path. In this case your passing formatting objects which can only be consumed by the host into the Format-Table cmdlet.

In otherwords PowerShell is doing the following:
Get-NaSnapmirror| Format-Table |  Format-Table | Out-Host

So how do you fix it?  It's actually very easy to fix once you know what's going on.

Option 1.  Only ever write a single object type to the pipeline - this is PowerShell best practice.

# Add the vSphere PowerCLI SnapIn and the DATA ONTAP Module            
Import-module DataONTAP            
$Filer = "controllername"            
# Create a Credential Object for login to the Filer            
$Credentials = Get-Credential root            
# Connect to NetApp Filer            
Connect-NaController $Filer -Credential $Credentials | out-null # silence the output            
$SnapMirror = Get-NaSnapmirror            
$SnapMirror | format-table

Option 2. Call Out-Default again to rewire the pipeline back to out-host.

# Add the vSphere PowerCLI SnapIn and the DATA ONTAP Module            
Import-module DataONTAP            
$Filer = "controllername"            
# Create a Credential Object for login to the Filer            
$Credentials = Get-Credential root            
# Connect to NetApp Filer            
Connect-NaController $Filer -Credential $Credentials             
$SnapMirror = Get-NaSnapmirror            
# Call out default again to remove the implicit Format-Table            
$SnapMirror | format-table | out-default

Hope that helps,

~Glenn

P.S.  They fixed all this in PowerShell V3!!

View solution in original post

2 REPLIES 2

sizemore
4,145 Views

Hey Rob,

Your running into a bug in PowerShell's default formatting. The problem is when you run a script, and don't explicitly handle the scripts output. The first command that emits any object will set the formatting for the remainder of the script. In this case the Connect-NaController cmdlet emits a NaController object to out-host. Since Out-Host was handed an unformatted object it in turn calls out-default. Out-Default determines that the default format for a NaController is to use a table. So Out-Default then hands the NaController object to Format-Table who writes the format objects to out-host. That's a deep dive into the pipeline i know but it's necessary because of what happens next.

Since we're still in a script block the output pipeline stays connected to Format-Table. With the pipeline all setup to take objects and pass them through Format-Table on the way to Out-Host. You're then getting a list of snapmirror object, and formatting them into a table. Again since you’re not explicitly handling the output of the pipeline, all object emitted follow that same path. In this case your passing formatting objects which can only be consumed by the host into the Format-Table cmdlet.

In otherwords PowerShell is doing the following:
Get-NaSnapmirror| Format-Table |  Format-Table | Out-Host

So how do you fix it?  It's actually very easy to fix once you know what's going on.

Option 1.  Only ever write a single object type to the pipeline - this is PowerShell best practice.

# Add the vSphere PowerCLI SnapIn and the DATA ONTAP Module            
Import-module DataONTAP            
$Filer = "controllername"            
# Create a Credential Object for login to the Filer            
$Credentials = Get-Credential root            
# Connect to NetApp Filer            
Connect-NaController $Filer -Credential $Credentials | out-null # silence the output            
$SnapMirror = Get-NaSnapmirror            
$SnapMirror | format-table

Option 2. Call Out-Default again to rewire the pipeline back to out-host.

# Add the vSphere PowerCLI SnapIn and the DATA ONTAP Module            
Import-module DataONTAP            
$Filer = "controllername"            
# Create a Credential Object for login to the Filer            
$Credentials = Get-Credential root            
# Connect to NetApp Filer            
Connect-NaController $Filer -Credential $Credentials             
$SnapMirror = Get-NaSnapmirror            
# Call out default again to remove the implicit Format-Table            
$SnapMirror | format-table | out-default

Hope that helps,

~Glenn

P.S.  They fixed all this in PowerShell V3!!

robert_updegraff
4,144 Views

That was quick and right on the money!

Thanks very much for your help!

Public