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?

3
  • 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. Commented Mar 2, 2018 at 13:56
  • This is my goto dupe for situations like this. stackoverflow.com/questions/36358047/… however I hesitate to use the hammer on this one. Commented Mar 2, 2018 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. Commented Mar 2, 2018 at 14:46

2 Answers 2

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" }
Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.