Author Posts

January 1, 2012 at 12:00 am

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. 🙂

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.