如果证书的到期时间是在当前日期的30天之内,我遇到了打印输出的脚本问题。但是我发现如果现在找到了expiry-epoch字符串,那么我会得到一条错误消息"无法索引到数组"这弄乱了我的输出。
请告诉我如何仅在包含expiry-epoch字符串
的文件上运行此脚本$c = Get-Date (Get-Date).ToUniversalTime() -UFormat %s
$epochroundedtimes = [math]::Round($c)
$epochtimes = $epochroundedtimes + 2592000
Get-ChildItem -Path "C:\scripts\PALO" -File -Recurse |
ForEach-Object { $epochtimes } {
$certexp =
[double] ($_ | Select-String -pattern "expiry-epoch (\d+)$").Matches.Groups[1].Value
if ($certexp -le $epochtimes) {
$_.FullName
}
}
答案 0 :(得分:2)
试试这个:
$c = Get-Date (Get-Date).ToUniversalTime() -UFormat %s
$epochroundedtimes=[math]::Round($c)
$epochtimes=$epochroundedtimes + 2592000
Get-ChildItem -Path "C:\scripts\PALO" -File -Recurse |
ForEach-Object {
$epochMatch = $_ | Select-String -pattern "expiry-epoch (\d+)$"
if($epochMatch)
{
$certexp = ([double]($epochMatch.Matches.Groups[1].Value))
if($certexp -le $epochtimes)
{
$_.FullName
}
}
}
编辑:根据评论添加简要说明
原始代码示例中的这一行生成了错误:
$certexp =
[double] ($_ | Select-String -pattern "expiry-epoch (\d+)$").Matches.Groups[1].Value
这是有问题的,因为如果目标文件不包含预期的字符串,Select-String
不会产生输出,因此不需要Matches
或Group
属性进行询问。将此行拆分为多个步骤,可以在尝试访问其属性之前检查是否有对象可以使用。也就是说,我们尝试字符串匹配:
$epochMatch = $_ | Select-String -pattern "expiry-epoch (\d+)$"
然后检查$epochMatch
是否为实际对象:
if($epochMatch)
如果是,我们然后检索匹配的值:
$certexp = ([double]($epochMatch.Matches.Groups[1].Value))
答案 1 :(得分:0)
boxdog's helpful answer很好地解释了问题并提供了有效的解决方案。
让我补充一个简化的,更加PowerShell惯用的解决方案,在避免原始问题的同时提高效率:
Get-ChildItem -LiteralPath "C:\scripts\PALO" -File -Recurse |
Select-String -Pattern "expiry-epoch (\d+)$" |
ForEach-Object {
# Extract the capture-group value from the [Microsoft.PowerShell.Commands.MatchInfo]
# instance that Select-String output.
$certexp = [double] $_.Matches[0].Groups[1].Value
if ($certexp -le $epochtimes) {
# The .Path property of the [Microsoft.PowerShell.Commands.MatchInfo]
# instance contains the input file's full filename.
$_.Path
}
}
直接将Get-ChildItem
的输出汇总到Select-String
意味着只有匹配才会通过管道传递,然后ForEach-Object
调用可以安全地执行。