我想获取列表
基于最终用户想要的3条信息中的哪条。 我希望扩展我的此功能,以根据提供的输入来容纳更多属性。下面给出的是我的代码片段及其后面的错误。
$Path
是路径,它是输入$CustomMetaList
是一个属性数组,它是一个输入。 $BaseCmd = "Get-ChildItem $Path -Recurse"
$Hidden = ""
$FullName = ""
$LastWriteTime = ""
$Size = ""
$PropList = ""
$CustomMetaList = $CustomMetaList.split(",")
foreach ($Meta in $CustomMetaList) {
if ($Meta -eq "'Hidden'") {
$Hidden = "-Force"
}
if ($Meta -eq "'FullName'") {
$PropList = [String]::Join(",","@{e={`$_.FullName};width=250}")
}
if ($Meta -eq "'LastWriteTimeUtc'") {
$PropList = [String]::Join(",",$PropList,"@{e={`$_.LastWriteTimeUtc -UFormat %s}}")
}
if ($Meta -eq "'Size'") {
$PropList = [String]::Join(",",$PropList,"@{e={`$_.Length}}")
}
}
Invoke-Expression "$BaseCmd $Hidden | Format-Table -HideTableHeaders -Property $PropList -AutoSize | Out-String -Width 5000"
}
当我尝试运行脚本时收到以下错误, 您对出什么问题有任何想法吗?
Invoke-Expression : At line:1 char:210 + ... stWriteTimeUtc -UFormat %s}},@{e={$_.Length}} -AutoSize | Out-String -Width 5000 + ~~~~~~~~ Unexpected token '-UFormat' in expression or statement. At line:1 char:219 + ... meUtc -UFormat %s}},@{e={$_.Length}} -AutoSize | Out-String -Width 5000 + ~~ Unexpected token '%s' in expression or statement. At E:\299955427760_GetData.ps1:114 char:5 + Invoke-Expression "$BaseCmd $Hidden | Format-Table -HideTableHeaders -Proper ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ParserError: (:) [Invoke-Expression], ParseException + FullyQualifiedErrorId : UnexpectedToken,Microsoft.PowerShell.Commands.InvokeExpressionCommand
答案 0 :(得分:4)
Ansgar Wiechers忠实地建议,Invoke-Expression should be avoided,因为几乎总是有更好的解决方案,并且存在安全风险。
通常,对于迭代构造具有不同参数的命令,参数splatting是最佳解决方案,尽管在您的情况下这不是绝对必要的-请参阅底部。
但是,您的问题与Invoke-Expression
的使用无关,因为它是由以下表达式引起的:
$_.LastWriteTimeUtc -UFormat %s # !! Syntax error
您只能将-UFormat
传递给Get-Date
cmdlet,而不能传递给变量或表达式:
Get-Date -Date $_.LastWriteTimeUtc -UFormat %s # OK
此外,由于Windows PowerShell v.5.1中的错误(自从在PowerShell Core 中得到纠正),Get-Date -UFormat %s
也会输出 fractional 秒,这是不正确的;您可以通过强制转换为[int]
来解决此问题:
[int] (Get-Date -Date $_.LastWriteTimeUtc -UFormat %s)
(考虑到Get-Date -UFormat
总是输出 strings ,即使没有错误,您可能也想这样做以接收数字结果。)< / p>
顺便说一句:另一个错误导致默认情况下结果基于 local 时间,而Unix时间戳要求基于 UTC ;由于您使用的是属性.LastWriteTimeUtc
,因此您的代码不会受到影响。
这是一种避免使用Invoke-Expression
并且也更短的解决方案:
# Sample input values.
$Path = $env:TEMP
$CustomMetaList = 'FullName,Size,LastWriteTimeUtc'
# Construct the array of property definitions to pass to Select-Object
# based on the custom list, and record in $force whether hidden items
# should be included.
$props = switch ($CustomMetaList -split ',') {
'Hidden' { $force = $True; continue } # save in Boolean var.
'FullName' { $_; continue } # same name as property
'Size' { 'Length'; continue } # map 'Size' to 'Length'
'LastWriteTimeUtc' { # calculated property
@{ n=$_; e = { [int] (Get-Date -Date $_.LastWriteTimeUtc -UFormat %s) } }
}
}
Get-ChildItem $Path -Recurse -Force:$force |
Format-Table -Property $props -HideTableHeaders -AutoSize |
Out-String -Width 5000
请注意如何使用switch
隐式迭代$CustomMetaList -split ','
返回的数组元素。
switch
语句的分支处理程序默认情况下都经过 all 测试,因此一旦找到匹配项,就使用continue
来使其短路。注意:不要使用break
,因为它会停止遍历其他数组元素。
switch
语句迭代的输出隐式收集在存储在$props
中的 array 中,该数组随后传递给Format-Table
。>
-Force:$force
是一种模拟传递/不传递开关参数-Force
的效果的方法:如果$force
为$true
,则与{{ 1}}已通过;否则,将视为未通过-Force
。
这将产生如下内容:
-Force