Нет ошибки при выборе несуществующего свойства
Я хочу, чтобы 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