Powershell if заявление - PullRequest
       30

Powershell if заявление

1 голос
/ 22 апреля 2020

На одном из моих серверов у нас есть программа, которую мы должны обновлять каждый месяц, эта программа работает на терминальном сервере.

Мой скрипт basi c работает (это очень просто):


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

pause

Но я пытаюсь сделать его более "умным", поэтому я попытался использовать выражение IF:

Первый тест:

$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

Второй 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"
}

Я также пытался определить переменную таким образом:

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

Я не получаю вообще никакого вывода, когда использую оператор IF.

Большое спасибо за вашу помощь!

1 Ответ

2 голосов
/ 22 апреля 2020
  • Всегда используйте только Format-* командлеты, такие как ft (Format-Table) для форматирования экрана ; никогда не используйте их, если данные должны программно обрабатываться . Format-* вывод командлетов инструкции по форматированию , а не данные - см. этот ответ .

  • Даже с | ft -autosize удалено, вы не должны сравнивать $open с $true или $false, потому что такое явное сравнение обычно не будет работать, как предполагалось, если LHS не является Boolean (тип [bool]) [1] ; вместо этого использует неявное PowerShell в булево преобразование - см. нижнюю часть этого ответа .

  • Ваша ветка if на самом деле не выводит $open; он выводит только сообщение о состоянии Write-Host на дисплей.

Чтобы сложить все вместе:

$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 возвращает либо:

  • a [pscustomobject] экземпляр [2] (пользовательский объект со свойствами .ClientUserName и .Path)

    • любой [pscustomobject] экземпляр - независимо от его структуры - оценивается в $true в логическом контексте.
  • или "none" (технически, [System.Management.Automation.Internal.AutomationNull]::Value), если командлет Where-Object не сделал Не удалось найти указанный путь в выходных данных Get-SmbOpenFile.

    • "Ничто" оценивается как $false в логическом контексте.

Снова, смотрите нижний раздел этого ответа для полного набора правил неявного преобразования в булево.


[1] Примечательно, что это не примитив объект как LHS всегда дает $false по сравнению с $true (хотя не с обращенными операндами); например, (Get-Item /) -eq $true; также любой ненулевой номер, который не совсем 1 будет указывать $false; например: 2 -eq $true. Кроме того, при значении LHS -eq действует как фильтр , возвращает подмассив соответствующих элементов (например, (1, 2, 1) -eq $true возвращает 1, 1 .

[2] Как правило, Select-Object может возвращать несколько объектов, в этом случае $open получит [object[]] -тип массив из [pscustomobject] экземпляров. Массив с 2 или более элементами равен всегда $true в логическом контексте.

...