我正在寻找以下列表
基于最终用户想要这 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"
}
Run Code Online (Sandbox Code Playgroud)
当我尝试运行脚本时收到以下错误,您知道出了什么问题吗?
调用表达式:
行:1 字符:210
+ ... stWriteTimeUtc -UFormat %s}},@{e={$_.Length}} -AutoSize | 出弦宽度 5000
+ ~~~~~~~~~
表达式或语句中出现意外的标记“-UFormat”。
行:1 字符:219
+ ... meUtc -UFormat %s}},@{e={$_.Length}} -AutoSize | 出弦宽度 5000
+ ~~
表达式或语句中有意外的标记“%s”。
在 E:\299955427760_GetData.ps1:114 字符:5
+ 调用表达式“$BaseCmd $Hidden | 格式表 -HideTableHeaders -Proper ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Invoke-Expression], ParseException
+FullyQualifiedErrorId:UnexpectedToken、Microsoft.PowerShell.Commands.InvokeExpressionCommand
As Ansgar Wiechers soundly advises, Invoke-Expression should be avoided, because there are almost always better solutionsand it comes with security risks.
Generally, for iteratively constructing commands with varying arguments, argument splatting is the best solution, though in your case that's not strictly necessary - see bottom section.
However, your problem is unrelated to the use of Invoke-Expression, because it is the following expression that causes your problem:
$_.LastWriteTimeUtc -UFormat %s # !! Syntax error
Run Code Online (Sandbox Code Playgroud)
You can only pass -UFormat to the Get-Date cmdlet, not to a variable or expression:
Get-Date -Date $_.LastWriteTimeUtc -UFormat %s # OK
Run Code Online (Sandbox Code Playgroud)
Additionally, due to a bug in Windows PowerShell v.5.1 (since corrected in PowerShell Core), Get-Date -UFormat %s outputs fractional seconds too, which is incorrect; you can fix this by simply casting to [int]:
[int] (Get-Date -Date $_.LastWriteTimeUtc -UFormat %s)
Run Code Online (Sandbox Code Playgroud)
(Even without the bug present you may want to do this in order to receive a numeric result, given that Get-Date -UFormat always outputs strings).
As an aside: Another bug causes the result to be based on local times by default, whereas Unix time stamps are required to be UTC-based; since you're using property .LastWriteTimeUtc, your code is not affected.
Here's a solution that avoids Invoke-Expression and is much shorter too:
# 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
Run Code Online (Sandbox Code Playgroud)
Note how switch is used to implicitly iterate over the elements of the array that $CustomMetaList -split ',' returns.
The branch handlers of a switch statement are all tested for by default, so continue is used to short-circuit that, once a match has been found. Caveat: Do not use break, as it stops iterating over further array elements.
The output from the iterations of the switch statement is implicitly collected in an array stored in $props, which is later passed to Format-Table.
-Force:$force is a way to mimic the effects of passing / not passing switch parameter -Force: if $force is $true, it is the same as if just -Force had been passed; otherwise, it is treated as if -Force had not been passed.
This will yield something like:
FullName Length LastWriteTimeUtc
-------- ------ ----------------
C:\path\to\sample.txt 51 1543853694
# ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1027 次 |
| 最近记录: |