1

In one of my servers we have an program that we need to update each month, this program is running on a terminal server.

My basic script is working (it's very simple):


Get-SmbOpenFile |where {$_.Path -eq "D:\Shares\Programs\test.exe"} |select ClientUserName, path |ft -autosize

pause

But i'am trying to make it more "smarter" so I've tried to use the IF statement:

First test:

$open = Get-SmbOpenFile |where {$_.Path -eq "D:\Shares\Programs\test.exe"} |`
select ClientUserName, path |ft -autosize



if ($open -eq "true")
{ write-host "showing open files"
}

elseif ($open -eq "false")
{ "All cloesd"
}

pause

Second test:

$open = Get-SmbOpenFile |where {$_.Path -eq "D:\Shares\Programs\test.exe"} |`
select ClientUserName, path |ft -autosize


if ($open -eq $true)
{
 write-host "showing open files"
}

elseif ($open -eq $false)
{ 
"All cloesd"
}

I've also tried to define the variable in that way:

$open = Get-SmbOpenFile |where {$_.Path -eq "D:\Shares\Programs\test.exe"} 

I'am not getting actually any output at all when i use the IF statement.

Thanks a lot for your help !

1 Answer 1

2
  • Only ever use Format-* cmdlets such as ft (Format-Table) for display formatting; never use them if data must be programmatically processed. Format-* cmdlets output formatting instructions, not data - see this answer.

  • Even with | ft -autosize removed, you shouldn't compare $open to $true or $false, because such an explicit comparison will not generally work as intended if the LHS isn't already a Boolean (type [bool])[1]; instead, take advantage of PowerShell's implicit to-Boolean conversion - see the bottom section of this answer.

  • Your if branch doesn't actually output $open; it only outputs a Write-Host status message to the display.

To put it all together:

$open = Get-SmbOpenFile | 
          Where-Object {$_.Path -eq "D:\Shares\Programs\test.exe"} |
            Select-Object ClientUserName, Path

if ($open) {
  Write-Host "showing open files"
  $open  # output the result
}
else {
  Write-Host "all closed"
}

Select-Object returns either:

  • a [pscustomobject] instance[2] (a custom object with properties .ClientUserName and .Path)

    • Any [pscustomobject] instance - regardless of its structure - evaluates to $true in a Boolean context.
  • or "nothing" (technically, [System.Management.Automation.Internal.AutomationNull]::Value), if the Where-Object cmdlet didn't find the specified path in Get-SmbOpenFile's output.

    • "Nothing" evaluates to $false in a Boolean context.

Again, see the bottom section of this answer for the complete set of rules of implicit to-Boolean conversion.


[1] Notably, a non-primitive object as the LHS always yields $false when compared to $true (though not with the operands reversed); e.g., (Get-Item /) -eq $true; also, any nonzero number that isn't exactly 1 will indicate $false; e.g.: 2 -eq $true. Additionally, with an array-valued LHS, -eq acts as filter, returns the subarray of matching items (e.g., (1, 2, 1) -eq $true returns 1, 1.

[2] In general, Select-Object can return multiple objects, in which case $open would receive an[object[]]-typed array of [pscustomobject] instances. An array with 2 or more elements is always $true in a Boolean context.

Sign up to request clarification or add additional context in comments.

1 Comment

I appreciate the nice feedback, @RoadRunner.

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.