PowerShell:如果未找到字符串,则出现不需要的错误



如果证书的到期期限在当前日期的 30 天内,我遇到了一个脚本问题,该脚本应该打印出输出。 但是我发现,如果现在找到到期纪元字符串,那么我会收到一条错误消息"无法索引到数组中",这会弄乱我的输出。

请让我知道如何仅在包含到期纪元字符串的文件上运行此脚本

$c = Get-Date (Get-Date).ToUniversalTime() -UFormat %s
$epochroundedtimes = [math]::Round($c)
$epochtimes = $epochroundedtimes + 2592000
Get-ChildItem -Path "C:scriptsPALO" -File -Recurse | 
  ForEach-Object { $epochtimes } {
    $certexp = 
      [double] ($_ | Select-String -pattern "expiry-epoch (d+)$").Matches.Groups[1].Value
    if ($certexp -le $epochtimes) {
      $_.FullName
    }
  }

试试这个:

$c = Get-Date (Get-Date).ToUniversalTime() -UFormat %s
$epochroundedtimes=[math]::Round($c)
$epochtimes=$epochroundedtimes + 2592000
Get-ChildItem -Path "C:scriptsPALO" -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不会产生任何输出,因此没有要查询的MatchesGroup属性。将此行拆分为多个步骤,可以在尝试访问其属性之前检查我们是否有要使用的对象。 也就是说,我们尝试字符串匹配:

$epochMatch = $_ | Select-String -pattern "expiry-epoch (d+)$"

然后检查$epochMatch是实际对象:

if($epochMatch)

如果是这样,我们然后检索匹配的值:

$certexp = ([double]($epochMatch.Matches.Groups[1].Value))

Boxdog的有用答案很好地解释了这个问题,并提供了一个有效的解决方案。

让我补充一个简化的、更 PowerShell 惯用的解决方案,该解决方案在避免原始问题的同时更有效:

Get-ChildItem -LiteralPath "C:scriptsPALO" -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调用可以安全地在其上执行操作。

相关内容

最新更新