提问人:Greg 提问时间:8/2/2023 最后编辑:mklement0Greg 更新时间:8/2/2023 访问量:103
在 Powershell 的 Select-Object 中使用变量
Using variable in Select-Object in Powershell
问:
我有一个表,它是使用时间作为列名创建的。但是,如果第一行在某些 Hours(列) 中没有数据,则该列不会显示表其余部分的列。因此,我正在尝试创建一个动态选择语句,该语句将从午夜开始每小时获取一次,并将这些时间用作搜索变量。我已经完成了创建Select语句,但它没有调用/执行查询。
任何返回数据并构建 HTML 表格的建议将不胜感激。
法典:
$UniversalCurrTime = ((Get-Date).ToUniversalTime()).ToString('h tt')
$UniversalMidnight = ((Get-Date).ToUniversalTime().Date).ToString('h tt')
$hoursBetween = $UniversalMidnight
Write-host 'This is midnight: ' $UniversalMidnight
Write-host 'This is Current time: ' $UniversalTime
$HourSpan = @()
$HourSpan += 'VaultName'
$HourSpan += $UniversalMidnight #($hoursBetween).ToString('h tt')
Do{
$HourSpan += "'" + ($hoursBetween).ToString('h tt') + "'"
$hoursBetween = (Get-date $hoursBetween).AddHours(1)
Write-host 'This is time being added to collection: ' $hoursBetween
}while($hoursBetween -le $UniversalCurrTime)
$HourSpan += 'TotalMessages'
$selectObject = '$reportList |Select-Object ' + (($HourSpan -split '\n') -join ",") + '| ConvertTo-Html -Fragment -ErrorAction SilentlyContinue'
$html = Invoke-Command -ScriptBlock {$selectObject}
在屏幕上输出,但未执行以返回数据。
$reportList |Select VaultName,'12 AM','1 AM','2 AM','3 AM','4 AM','5 AM','6 AM','7 AM','8 AM', '9 AM','10 AM','11 AM','12 PM','1 PM','2 PM','3 PM','4 PM','5 PM','6 PM','7 PM', '8 PM', '9PM', '10 PM', '11 PM', 'TotalMessages' |Where-Object { -Not [String]::IsNullOrWhiteSpace($_) }| ConvertTo-Html -Fragment -ErrorAction SilentlyContinue
应执行此语句。
答:
$selectObject = '$reportList |Select-Object ' + (($HourSpan -split '\n') -join ",") + '| ConvertTo-Html -Fragment -ErrorAction SilentlyContinue'
上面创建了一个字符串值。
$html = Invoke-Command -ScriptBlock {$selectObject}
上面的内容 - 可以简化为并最终 - 输出存储在 $selectObject
中的字符串,这解释了您所看到的内容。$html = & { $selectObject }
$html = $selectObject
撇开存储在 (a) 中是否有效构造,[1] (b) 预期的时间顺序比较是否有效,以及 (c) 假设 和 被删除,您可能正在寻找以下内容:$HourSpan
$HourSpan += 'VaultName'
$HourSpan += 'TotalMessages'
$html =
$reportList |
Select-Object (@('VaultName') + $HourSpan + 'TotalMessages') |
ConvertTo-Html -Fragment -ErrorAction SilentlyContinue
也就是说,可以将动态构造的属性名称数组直接传递给 Select-Object
的(位置隐含的)-Property
参数。
使用数组作为 LHS - 使用 ,array-subexpression 运算符确保 - 运算符执行(平面)数组连接。@(...)
+
PowerShell 很少要求将命令动态构造为字符串,并且由于固有的安全风险,通常应避免这样做,但在必要时,您有两种选择:
对于调用方作用域中的一次性调用,请使用
Invoke-Expression
;例如:$commandString = 'Get-Date' Invoke-Expression $commandString
对于可重复的调用,请使用
[scriptblock]::Create()
从字符串构造一个脚本块,您可以根据需要重复调用它,通过 调用运算符 - 在子作用域中 - 或通过 ,点源运算符 - 直接在调用方的作用域中:&
.
$commandString = 'Get-Date' $scriptBlock = [scriptblock]::Create($commandString) # Invoke the script block on demand, in a child scope. # To invoke it directly in the caller's scope, use: # . $scriptBlock & $scriptBlock
[1] 在循环中使用 +=
扩展数组是低效的,因为鉴于数组的大小是固定的,因此每次迭代都必须在后台创建一个新数组;更有效的方法是使用 do { ... } while (...) 或 foreach 循环等语句作为表达式,并让 PowerShell 本身在数组中收集输出:[array] $outputs = foreach (...) { ... }
- 请参阅此答案。
如果您需要手动创建数组,例如要创建多个数组,请使用高效可扩展的列表类型 - 请参阅此处。
评论