2015-10-02 4 views
2

Я хочу, чтобы 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, но заголовкам в этих файлах могут измениться, и я в конечном итоге с пустой колонной загружаются в систему.

EDIT: Это, как я проверяю, если заголовки совпадают:

$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», который выполнил бы мою работу :). Спасибо за ответы.

+1

Не думайте, что вы можете это сделать, потому что именно так спроектирована Powershell. Если бы это стало возможным, это нарушило бы '$ newobj = '' | Select-Object prop1, prop2' – Kiran

ответ

4

Вы фактически используете то, что some people would call a feature. Это более простая реализация использования Add-Member для всех элементов массива для добавления пустого столбца.

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

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

Я вижу в документации немного misleading when it says for 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 
+0

Оценить полезную ссылку! – RayLuo

4

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' 
0

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

$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 
Смежные вопросы