【问题标题】:PowerShell - Was A File Created For Each Hour?PowerShell - 是否每小时创建一个文件?
【发布时间】:2020-04-29 19:24:28
【问题描述】:

我正在尝试创建一个 PowerShell 脚本,该脚本将每天早上运行一次(通过任务计划程序)并提醒某人(通过直接发送(我知道如何执行此操作,稍后将实现所述功能)) t 在前一天的每个小时内创建,以便不再需要手动执行此操作或出现问题时。文件名,如 $FilePattern 所示,都包含它们的创建日期以及时间。显然,我的 Foreach 循环中的逻辑是有缺陷的,因为 $Time 将始终以 $Hours 为单位,但我一直在摸不着头脑,无法弄清楚我应该如何去做。我以为我可以比较两个数组,但我现在不太确定。我还遇到了看起来很有希望的 Compare-Object,但我无法完全掌握它。我为混乱道歉。我目前的代码如下。

[CmdletBinding()]

param(

    [Parameter(Mandatory=$false)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]
    $Path = "C:\Users\<username>\Desktop\Archive",
    $Year = [DateTime]::Today.AddDays(-1).Year,
    $Month = [DateTime]::Today.AddDays(-1).Month,
    $Day = ([DateTime]::Today.AddDays(-1).Day),
    $strMonth = ([String]$Month).PadLeft(2,'0'),
    $strDay = ([String]$Day).PadLeft(2,'0'),
    $Date = "$Year" + "$strMonth" + "$strDay",
    $FilePattern = @("850_" + $Date + "*.txt"),
    $Files = (Get-ChildItem -Path $Path -Include $FilePattern -Recurse | 
        Select-Object -ExpandProperty CreationTime | Get-Date -f "yyyyMMdd"),
    $Time = (Get-ChildItem -Path $Path -Include $FilePattern -Recurse |
        Select-Object -ExpandProperty CreationTime | Get-Date -f "hh"),
    $Hours = @(0..23)

)

Foreach ($File in $Files) {

    #if (-Not (Test-Path "$Path\$FilePattern")) {
    #    Write-Host "Warning: The file path doesn't exist!"
    #} else {
    #    Write-Host "The file path exists..."
    #}

    if ($Hours -notin $Time) {
        Write-Host "There's no file present for $Time o'clock for $Date."
    } else {
        Write-Host "There's at least one file per hour for $Date."
    }

}

【问题讨论】:

  • 您想将哪些信息传递给该脚本?文件名中不包含小时数吗?

标签: arrays powershell compareobject


【解决方案1】:

这是一个更短且可能更易读的实现:

$Path = "C:\Users\<username>\Desktop\Archive\*"
$Date = (Get-Date).AddDays(-1).ToString('yyyyMMdd')
$Hours = Get-ChildItem -Path $Path -Include "850_$($Date)*.txt" | ForEach-Object {(Get-Date $_.CreationTime).Hour} | Sort-Object | Get-Unique
for ($Hour = 0; $Hour -lt 24; $Hour++) {
    if ($Hour -in $Hours) {
        Write-Host "There's at least one file for $Hour o'clock for $Date." -ForegroundColor Green
    } else {
        Write-Host "There's no file present for $Hour o'clock for $Date." -ForegroundColor Red
    }
}

那么我改变了什么:

  • 我删除了params 块,因为我认为您只是使用它来初始化变量,但它旨在定义您想要传递给函数的参数。看起来您不想向该脚本传递任何内容。纠正我,如果我错了。
  • 我在您的路径中添加了一个星号 (*) 以使 -Include 参数起作用(请参阅 docs)。我认为您添加了-Recurse 以使其正常工作。仅当您的日志位于子目录中时才使用 -Recurse
  • 我添加了一种更具可读性和更易于理解的方法来创建所需的时间戳。
  • 我提取了小时数,您正在寻找数字,因此您可以将它们与数字进行比较,而不必创建由两位数字字符串化小时数组成的数组。
  • 如果缺少任何文件,我在输出中添加了颜色以获得更快的概览。

【讨论】:

  • 比我想出的更优雅的解决方案。你提到的很多事情我都不知道,而且我正在阅读的这本书没有很好地涵盖它们,所以非常感谢。我特别喜欢你做 For 循环的方式,这让我想起了我在 C 中做事情的传统方式,以及你如何将 $Date 减少到一行而不是我的六行。
【解决方案2】:

我仍然需要重构和更改一些东西,但这似乎可行。

[CmdletBinding()]

param(

    $Path = "C:\Users\<username>\Desktop\Archive",
    $Year = [DateTime]::Today.AddDays(-1).Year,
    $Month = [DateTime]::Today.AddDays(-1).Month,
    $strMonth = ([String]$Month).PadLeft(2,'0'),
    $Day = ([DateTime]::Today.AddDays(-1).Day),
    $strDay = ([String]$Day).PadLeft(2,'0'),
    $Date = "$Year" + "$strMonth" + "$strDay",
    $Hours = @(
        "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11",
        "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"
    ),
    $strHours = $Hours.ToString().PadLeft(2,'0'),
    $FilePattern = @("850_" + $Date + "*.txt"),
    $Files = (Get-ChildItem -Path $Path -Include $FilePattern -Recurse | 
        Select-Object -ExpandProperty CreationTime | Get-Date -f "HH")

)

ForEach ($Hour in $Hours) {

    if ($Hour -notin $Files) {

        Write-Host "There's no file present for $Hour o'clock for $Date."

    } else {

        Write-Host "There's at least one file for $Hour o'clock for $Date."

    }

}

【讨论】:

  • 参见上面 Thomas 的卓越解决方案。
猜你喜欢
  • 2020-06-18
  • 1970-01-01
  • 2021-01-28
  • 2012-03-30
  • 2019-04-30
  • 1970-01-01
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多