Нет ошибки при выборе несуществующего свойства

Я хочу, чтобы PowerShell выдавал ошибку при попытке выбрать несуществующие свойства, но вместо этого я получаю пустой столбец в качестве вывода. Пример:

$ErrorActionPreference=[System.Management.Automation.ActionPreference]::Stop;
Set-StrictMode -Version 'Latest'
Get-Process *ex* | Select-Object Id,ProcessName,xxx

   Id ProcessName   xxx
   -- -----------   ---
 9084 explorer
11404 procexp

Я написал скрипт, который импортирует несколько текстовых файлов Import-Csv, но заголовки в этом файле могут измениться, и я получу пустые столбцы, загружаемые в систему.

РЕДАКТИРОВАТЬ: Вот как я проверяю, совпадают ли заголовки:

$csv = Import-Csv -Delimiter ';' -Path $file.FullName 
$FileHeaders = @(($csv | Get-Member -MemberType NoteProperty).Name) 
if (Compare-Object $ProperHeaders $FileHeaders) {'err'} else {'ok'}

Я знаю, что так работает PowerShell, но Set-StrictMode документация действительно немного вводит меня в заблуждение, как упоминал @Matt. Я просто желаю Select-Object был какой-то переключатель "-NoNewImplicitProps" или "-ReadOnlyPipeline", который сделал бы эту работу за меня:). Спасибо за ответы.

4 ответа

Решение

Вы на самом деле используете то, что некоторые люди называют функцию. Это более простое представление использования Add-Member на всех членах массива добавить пустой столбец.

В случае Import-CSV в этом случае вы проверяете имена свойств перед Select где вы их называете

$data = Import-csv C:\Temp\file.csv 
$props = $data | Get-member -MemberType 'NoteProperty'  | Select-Object -ExpandProperty Name

Я вижу, что документация немного вводит в заблуждение, когда говорится Set-StrictMode:

Запрещает ссылки на несуществующие свойства объекта.

Но в этом случае вы не пытаетесь получить ссылку на свойство, а используете функцию Select-Object Командлет. Следующее произвело бы ошибку, хотя

PS C:\Users\mcameron> Set-StrictMode -Version 'Latest'
(Get-Process *ex*).Bagels
The property 'Bagels' cannot be found on this object. Verify that the property exists.
At line:2 char:1
+ (Get-Process *ex*).Bagels
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

PowerShell расширяет несуществующие свойства до $null ведет себя как задумано. AFAICS, единственное, что вы можете сделать, это явно проверить, существуют ли все свойства:

$props = 'Id', 'ProcessName', 'xxx'

$p = Get-Process *ex*
$missing = $p | Get-Member -Type *property |
           Select-Object -Expand Name |
           Compare-Object -Reference $props |
           Where-Object { $_.SideIndicator -eq '<=' } |
           Select-Object -Expand InputObject

if ($missing) {
  throw "missing property $missing."
} else {
  $p | Select-Object $props
}

Конечно, вы можете обернуть это в пользовательскую функцию:

function Select-ObjectStrict {
  [CmdletBinding()]
  Param(
    [Parameter(
      Position=0,
      Mandatory=$true,
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true
    )]$InputObject,

    [Parameter(
      Position=1,
      Mandatory=$true
    )][string[]]$Property
  )

  Process {
    $missing = $InputObject | Get-Member -Type *property |
               Select-Object -Expand Name |
               Compare-Object -Reference $Property |
               Where-Object { $_.SideIndicator -eq '<=' } |
               Select-Object -Expand InputObject

    if ($missing) {
      throw "missing property $missing."
    } else {
      $InputObject | Select-Object $Property
    }
  }
}

так что это можно использовать так:

Get-Process *ex* | Select-ObjectStrict -Property 'Id', 'ProcessName', 'xxx'

Если вы хотите получить ошибку при выборе несуществующего свойства
Используйте:

      Set-StrictMode -Version Latest<br>
$Global:ErrorActionPreference = 'Stop'<br>

Что-то вроде этого...?

$props = 'Id','ProcessName','xxx'
$availableProps = Get-Process *ex*|Get-Member -MemberType Properties | Select -ExpandProperty Name
$missingProps = $props | Where-Object {-not ($availableProps -contains $_)}
if ($missingProps) {
  Write-Error "invalid property(s) $missingProps"
  throw { [System.Management.Automation.PropertyNotFoundException] }
}

Get-Process *ex* | Select-Object $props
Другие вопросы по тегам