If/Else Question

by Lery at 2013-04-17 10:59:57

Does anyone know why this is executing the elseif statement and not the IF statement? I have notepad running and $path does contain notepad. I’ve tried it a few different ways, but no luck.


[system.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’) | Out-Null
$balloon = New-Object System.Windows.Forms.NotifyIcon
$path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

if ($path -contains ‘Notepad’) {
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}
elseif ($path -notcontains ‘Notepad’) {
$currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}
by DonJ at 2013-04-17 11:05:06
You’re using the wrong operator. -Contains is not a string-matching operator - read about_comparison_operators.

You probably meant -like ‘Notepad*’ instead.

One of the top 10 PowerShell gotchas.
by Lery at 2013-04-17 11:11:10
[quote="DonJ"]You’re using the wrong operator. -Contains is not a string-matching operator - read about_comparison_operators.

You probably meant -like ‘Notepad*’ instead.

One of the top 10 PowerShell gotchas.[/quote]

That worked. I also just got it working using -f. So this also works

#$ErrorActionPreference = "silentlycontinue"
[system.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’) | Out-Null
$balloon = New-Object System.Windows.Forms.NotifyIcon
$path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

if ($path -f ‘Notepad*’) {
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}
elseif ($path -notcontains ‘Notepad’) {
$currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
$currentproc
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}


I got excited when I thought I fixed it myself and rushed here to post it quick. :slight_smile:
by Lery at 2013-04-17 11:12:51
Actually, I stand corrected. -like does not work. It skips over the if. I have to use -f. Then it works.
by DonJ at 2013-04-17 11:16:29
Uh, no… -f is the format operator. That’s not doing what you think it’s doing. Use -like. Gotta read up on those operators, man ;).
by Lery at 2013-04-17 11:48:00
[quote="DonJ"]Uh, no… -f is the format operator. That’s not doing what you think it’s doing. Use -like. Gotta read up on those operators, man ;).[/quote]

I understand what you’re saying. But -like is not working. The only way I can get it working is with -f.

This does not work

[system.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’) | Out-Null
$balloon = New-Object System.Windows.Forms.NotifyIcon
$path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

if ($path -like ‘Notepad*’) {
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}
elseif ($path -notlike ‘Notepad*’) {
$currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}


This does work

[system.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’) | Out-Null
$balloon = New-Object System.Windows.Forms.NotifyIcon
$path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

if ($path -f ‘Notepad’) {
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}
elseif ($path -notcontains ‘Notepad’) {
$currentproc = Get-Process -id $pid | Select-Object -ExpandProperty Path
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($currentproc)
$balloon.Icon = $icon
$balloon.BalloonTipIcon = ‘Info’
$balloon.BalloonTipText = "Hello this is the text"
$balloon.BalloonTipTitle = "This is the title"
$balloon.Visible = $true
$balloon.ShowBalloonTip(10000)
}


If I take the balloon thing out of the script, I tested this in a simple if/elseif script.

This works

$path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path
if ($path -f ‘Notepad*’) {
Write-Host "Notepad is running"
}
elseif ($path -notcontains ‘Notepad*’)
{
Write-Host "Notepad is not running"
}


This does not work

$path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path
if ($path -like ‘Notepad*’) {
Write-Host "Notepad is running"
}
elseif ($path -notcontains ‘Notepad*’)
{
Write-Host "Notepad is not running"
}


When I say does not work, I mean specifically the script seems to ignore the if part, and goes right to the elseif. So if Notepad was open and I ran the script with the -like, it would say Notepad is not running.

No idea why it’s this way, just that is what is happening for me.
by DonJ at 2013-04-17 11:53:35
You need to get into your data a little. I’m telling you, -f isn’t a comparison operator. Trust me on this. You’re getting a spurious result because you’re using it in a way it isn’t intended to be used.

For example, if $Path contains a COMPLETE path, then $path -like ‘notepad would be the way to go. I’ve no idea what’s in $path.
by Lery at 2013-04-17 12:06:33
[quote="DonJ"]I’ve no idea what’s in $path.[/quote]

I’m launching Notepad and running this $path = Get-Process -Name Notepad | Select-Object -ExpandProperty Path

Running $path gets me C:\Windows\system32\notepad.exe

Oh, and I fully trust you and what you’re saying. I’m just going off the results I’m getting.
by DonJ at 2013-04-17 12:23:18
Ok. So, let’s talk about how -like works. It’s a wildcard match.

$path -like ‘notepad*’ will match "notepad.exe" but will not match "c:\windows\system32\notepad.exe" because there’s no wildcard at the front of the string - it expects the string to start with "n".

$path -like ‘notepad’ will match "c:\windows\system32\notepad.exe" because there’s a wildcard at the front of the string.

I gotta say - if you’re just trying to see if Notepad is running, you’re taking the long way around.

If ((Get-Process -Name Notepad -EA SilentlyContinue).Count -eq 0) { # not running }

I know I’‘m only seeing a piece of your code, so you might be after something else, but just offering that. PowerShell being object-oriented, you don’t really have to do a text comparison. In fact, the existing logic really relies on an odd design in PowerShell. If Notepad isn’t running, "Get-Process -Name Notepad" returns nothing. It’s an oddity that Select-Object can do anything with nothing.

For that matter…

if (Get-Process -name notepad -EA silentlycontinue) { ‘running’ } else { ‘not running’}

Works. I had to add -EA in both cases to suppress the error you get from querying a process that doesn’t exist. I’m presuming you did something with $ErrorActionPreference in your script to account for that?
by Lery at 2013-04-17 12:42:50
[quote="DonJ"]Ok. So, let’s talk about how -like works. It’s a wildcard match.

$path -like ‘notepad*’ will match "notepad.exe" but will not match "c:\windows\system32\notepad.exe" because there’s no wildcard at the front of the string - it expects the string to start with "n".

$path -like ‘notepad’ will match "c:\windows\system32\notepad.exe" because there’s a wildcard at the front of the string.
[/quote]

DOH! As Homer would say. I’m looking at this stuff too much since I overlooked an asterisk! Thanks Don.

[quote]
I gotta say - if you’re just trying to see if Notepad is running, you’re taking the long way around.

If ((Get-Process -Name Notepad -EA SilentlyContinue).Count -eq 0) { # not running }

I know I’'m only seeing a piece of your code, so you might be after something else, but just offering that. PowerShell being object-oriented, you don’t really have to do a text comparison. In fact, the existing logic really relies on an odd design in PowerShell. If Notepad isn’t running, "Get-Process -Name Notepad" returns nothing. It’s an oddity that Select-Object can do anything with nothing.

For that matter…

if (Get-Process -name notepad -EA silentlycontinue) { ‘running’ } else { ‘not running’}

Works. I had to add -EA in both cases to suppress the error you get from querying a process that doesn’t exist. I’m presuming you did something with $ErrorActionPreference in your script to account for that?[/quote]

Yes, I have the ErrorActionPreference set to suppress that error. I am doing more than the code I put in here. Notepad is just used for testing, because it’s simple. Believe it or not I’m playing around with the System.Windows.Forms. I learn by working through examples and applying what is applicable in my world to the lesson. I also have access to all of your CBT Nuggets. Unfortunately for me, I must have a bad case of ADD. I keep learning something new and my mind wonders in a million different directions on what I can do with that data. I need to focus a little more.

Thanks again!
by DonJ at 2013-04-17 12:46:19
Be aware that ErrorActionPreference will suppress everything. It’s one reason you’ll see behavior like you were with -f, in some cases. Things that would normally toss an error will muddle through with weird results.