0

I need a powershell script which gets information from another powershell script.

It seems to me the it is an array what I get in my script, so I tried to compare one item or the whole array against a string.

I will execute then this command on our Exchange cluster:

Get-ClusterResource |fl State|.\CheckDAG1.ps1

The first script is an inbuild Exchange script to get the state of a fileshare witness, the second script is mine and looks like this:

Param (
       [parameter(ValueFromPipeline=$True)]
       [string[]]$Status
    )
echo $Input.count
echo $Input
if ($input[2] -contains  "Online") {
    echo "1"}
else {
    echo "0"}

The output is this:

5
State : Online
0

So I can see that the array has 5 items, item 2 is the written line, but the result is 0.

What can I do so that the result is 1 as I expect?

henrycarteruk
  • 12,708
  • 2
  • 36
  • 40
wasserflo
  • 3
  • 1
  • 4
    PowerShell's philosophy is "filter left, format right". In other words, don't use formatting cmdlets until the last possible minute; instead, pass objects through the pipeline and use the objects. Essentially, for your example, don't use `Format-List` in the middle of the pipe; just write your script to use whatever `Get-ClusterResource` returns, and extracts the `State` property for examination and processing. – Jeff Zeitlin Mar 02 '18 at 13:56
  • This is my goto dupe for situations like this. https://stackoverflow.com/questions/36358047/how-can-i-store-output-from-format-table-for-later-use/36358921#36358921 however I hesitate to use the hammer on this one. – Matt Mar 02 '18 at 14:37
  • 1
    Furthermore, `-contains` is the wrong operator to use here. You're comparing two single values; `-contains` is to see if a collection object (e.g., an array) has a particular value as one of its entries. Use `-eq` for a (case-insensitive) exact match, `-like` for a pattern match with simple wildcards, or `-match` for a pattern match using a regular expression. – Jeff Zeitlin Mar 02 '18 at 14:46

2 Answers2

1

Get-ClusterResource returns an object, that PowerShell will display as a table in the Console. The properties of the object are shown as the table headers.

Example:

Get-ClusterResource

(I'm using a single cluster named resource for the examples)

To use these properties you can select them:

Get-ClusterResource -Name "Cluster Disk 1" | Select-Object State

Which will return just the single property:

PS >
State
-----
Online

Then using the ExpandProperty param will return just the value of the property:

Get-ClusterResource -Name "Cluster Disk 1" | Select-Object -ExpandProperty State
PS > Online

So applying the above to your code:

.\CheckDAG1.ps1 -Status (Get-ClusterResource -Name "Cluster Disk 1" | Select-Object -ExpandProperty State)

CheckDAG1.ps1:

Param (
    [parameter(ValueFromPipeline=$True)]
    [string]$Status
)
if ($Status -eq "Online") { echo "1" }
else { echo "0" }
henrycarteruk
  • 12,708
  • 2
  • 36
  • 40
0

Where do we start...

If you Get-Cluster 'foo' | Get-ClusterResource | fl State, you'll get a list looking like

Status : Online

Status : Online

Status : Offline

Try using the following...

$(Get-Cluster 'foo' | get-clusterresource).State

This will give you a neat list of strings, but back to your original script. Are you 100% sure you're getting the value of the property and not a qualified name of the type like Microsoft.PowerShell.Commands.Internal.Format.FormatEndData? I'd double check.

## Returns a single 1 or 0. 1 if there is at least 1 online resource, 0 if not
if ($status -contains 'Online') { 1 } else { 0 }

## Returns a 1 or 0 for each status in the array. 1 if the status is online, otherwise 0
$status | % { if ($_ -eq 'Online') { 1 } else { 0 } } 

Hope this helps.

henrycarteruk
  • 12,708
  • 2
  • 36
  • 40
Adam
  • 3,891
  • 3
  • 19
  • 42