Link to home
Start Free TrialLog in
Avatar of alexianit
alexianitFlag for United States of America

asked on

Powershell, working with if statements

I am working on learning Powershell and I'm working through a booklet I found on technet.  I'm having difficulty with the if statements.  The task is to return a list of services on the system along with their status, then color on screen report text red for stopped and green for running.

I've attached the code that gives me the following error ......

PS C:\Documents and Settings\user> C:\Documents and Settings\user\Desktop\test.ps1
You must provide a value expression on the right-hand side of the '-match' operator.
At C:\Documents and Settings\user\Desktop\test.ps1:1 char:71
+ get-service | Sort-Object Status | ForEach-Object if ($_.Status -match <<<<  Running) {write-host $_.ServiceName $_.Status -foregroundcolor green}
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedValueExpression


...what am I doing wrong?
get-service | Sort-Object Status | ForEach-Object if ($_.Status -match Running) {write-host $_.ServiceName $_.Status -foregroundcolor green}

Open in new window

Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image


Hey there :)

It's missing a couple pair of curly braces and pair of quotes.

If we take this and break it up into separate lines:

Get-Service | `
  Sort-Object Status | `
  ForEach-Object
    if ($_.Status -match Running)
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor green
    }

We have braces to enclose the if statement, nothing wrong there, but none to enclose the ForEach-Object statement. Those are what we need to add, turning it into this:

Get-Service | `
  Sort-Object Status | `
  ForEach-Object
  {
    if ($_.Status -match Running)
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor green
    }
  }

So far so good, it raises another problem though, a complaint about the usage of the match operator. This is where the quotes come in.

Get-Service | `
  Sort-Object Status | `
  ForEach-Object
  {
    if ($_.Status -match "Running")
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor green
    }
  }

Now $_.Status is tested against the string "Running" and the code should finally work.

HTH

Chris
Avatar of alexianit

ASKER

Ok I think I see .. so if on 1 line then:
Get-Service | Sort-Object Status | ForEach-Object {if ($_.Status -match "Running"){Write-Host $_.ServiceName $_.Status -foregroundcolor green}}

breaking this into several lines does point out some things, what it looks liek on a single line however is that I needed to include a curly-brace before 'if', quotes around the -match Operator and a second curly-brace at the end.
How do I add and else statement to return the other status text in red?

Once I can see the structure I think I'll have a better handle on it.

Do remember that in PowerShell you don't have to stuff everything onto one line as you might have done with batch files.

If, elseif and else work have this format in PowerShell:

if (Condition)
{
  # Code
}
elseif (SecondCondition)
{
  # Code
}
else
{
  # Code
}

You only wanted Else, so we have this modification to the code above:

Get-Service | `
  Sort-Object Status | `
  ForEach-Object
  {
    if ($_.Status -match "Running")
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor green
    }
    else
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor red
    }
  }

As before, you can compress that onto a single line, or leave it spread out.

Chris
ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok I think I get it now.  Thank you for your valuable assistance, it is much appreciated!
oops

when I run this I get:

cmdlet ForEach-Object at command pipeline position 3
Supply values for the following parameters:
Process[0]:

ForEach-Object needs an input pipeline. Can you show me your current code?

Chris
Just as you had listed above
Get-Service | `
  Sort-Object Status | `
  ForEach-Object
  {
    if ($_.Status -match "Running")
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor green
    }
    else
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor red
    }
  }

Open in new window


Ah okay, it either needs ` or a line break removing. Examples of both below :)

Chris
# With ` to escape the line-break

Get-Service | `
  Sort-Object Status | `
  ForEach-Object `
  {
    if ($_.Status -match "Running")
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor green
    }
    else
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor red
    }
  }


# Without the line break

Get-Service | `
  Sort-Object Status | `
  ForEach-Object {
    if ($_.Status -match "Running")
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor green
    }
    else
    {
      Write-Host $_.ServiceName $_.Status -foregroundcolor red
    }
  }

Open in new window

OH!  So that's what that accent mark is for.  Thanks again!