有没有办法在Powershell中使用等效的触摸来更新文件的时间戳?

我经常使用unix命令“ touch”来更新系统中任何新获取/下载的文件的时间戳。很多时候,现有文件的时间戳很旧,因此它可能会在系统中丢失。在MS-Windows powershell中有没有一种方法可以做到这一点。我同时拥有Powershell 5和Powershell6。

SophiaBJ 回答:有没有办法在Powershell中使用等效的触摸来更新文件的时间戳?

您可以使用

$file = Get-Item C:\Intel\Logs\IntelCpHDCPSvc.log
$file.LastWriteTime = (Get-Date)

或者,如果愿意,可以选择CreationTime或LastAcccessTime。

作为功能

Function UpdateFileLastWriteTimeToToday() { 
        Param ($FileName)
    $file = Get-Item $FileName
    Echo "Current last write time: " $file.LastWriteTime
    $file.LastWriteTime = (Get-Date)
    Echo "New last write time: " $file.LastWriteTime
}

#How to use

UpdateFileLastWriteTimeToToday -FileName C:\Intel\Logs\IntelGFX.Log

输出为

Current last write time: 
Tuesday,April 16,2019 1:09:49 PM

New last write time: 
Monday,November 4,2019 9:59:55 AM
,

Mark's helpful answer显示了如何更新单个文件的上次修改时间戳。

以下是功能Touch-Item 的源代码,该功能以PowerShell惯用的方式实现Unix touch实用程序提供的大多数功能,包括对-WhatIf的支持,详细的输出和pass-thru选项。

它在Windows PowerShell(版本3或更高版本)和PowerShell Core中均可使用。

例如,您可以将函数放入$PROFILE中;致电Get-Help Touch-Item寻求帮助。
如果要定义别名,建议不要命名为touch,以免与类Unix平台上的本机实用程序混淆;
例如,Set-Alias ti Touch-Item可以工作。

注意:该代码也可以在this Gist中作为.ps1脚本使用。

示例

# Sets the last-modified and last-accessed timestamps for all text files
# in the current directory to the current point in time.
Touch-Item *.txt


# Creates files 'newfile1' and 'newfile2' and outputs information about them as 
# System.IO.FileInfo instances.
# Note the need to use "," to pass multiple paths.
Touch-Item newfile1,newfile2 -PassThru


# Updates the last-modified and last-accessed timestamps for all text files
# in the current directory to midnight (the start of) of today's date.
Touch-Item *.txt -DateTime (Get-Date).Date


# Sets the last-modified and last-accessed timestamps of all text files
# in the current directory back by 1 hour.
Get-Item *.txt | Touch-Item -Offset '-1:0'


# Sets the last-modified and last-accessed timestamps of all files in the 
# current directory to the last-modified timestamp of the current directory minus
# 1 minute.
Get-ChildItem -File | Touch-Item -ReferencePath . -Offset '-0:1'

Touch-Item源代码:

注意:“触摸”在PowerShell中不是经过批准的动词,但还是选择了它, 因为没有一个批准的动词不能充分传达 该命令。

function Touch-Item {
  <#
.SYNOPSIS
"Touches" files and directories.

.DESCRIPTION
Similar to the Unix touch utility,this command updates the last-modified and
last-accessed timestamps of files and directories or creates files on
demand.

The current point in time is used by default,but you can pass a
specific timestamp with -DateTime or use an existing file or directory''s 
last-modified timestamp with -ReferencePath.
The resulting timestamp can be modified with -Offset.

Symbolic links are invariably followed,which means that it is a link''s
*target file or directory* whose timestamps get updated.
If the target doesn''t exist,a non-terminating error occurs.

Use -WhatIf to preview the effects of a given command,and -Verbose to see
details.
Use -PassThru to pass the touched items through,i.e.,to output updated
information about them.

Note that in order to pass multiple target files / patterns as arguments
you must *comma*-separate them,because they bind to a single,array-valued
parameter.

.PARAMETER Path
The paths of one or more target files or directories,optionally expressed
as wildcard expressions,and optionally passed via the pipeline.

.PARAMETER LiteralPath
The literal paths of one or more target files or directories,optionally
passed via the pipeline as output from Get-ChildItem or Get-Item.

.PARAMETER DateTime
The timestamp to assign as the last-modified (last-write) and last-access
values,optionally modified by -Offset.

By default,the current point in time is used.

.PARAMETER ReferencePath
The literal path to an existing file or directory whose last-modified
timestamp should be used,optionally modified by -Offset.

.PARAMETER Offset
A timespan to apply as an offset to the effective new timestamp:

* If neither -DateTime nor -ReferencePath are specified,the offset is applied
to the current point in time.

* If -DateTime or -ReferencePath is specified,the offset is applied to the
given timestamp.

Examples of strings that can be used to specify timespans are '-1' for
one day ago and '-2:0' for two hours ago.

Note that positive values adjust the timestamps into the (relative) future,whereas negative values adjust into the (relative) past.

Alternatively,use something like -(New-TimeSpan -Days 1)

.PARAMETER NoNew
Specifies that only existing files should have their timestamps updated.

By default,literal target paths that do not refer to existing items 
result in files with these paths getting created on demand.

.PARAMETER PassThru
Specifies that the "touched" items are passed through,i.e. produced as this 
command''s output,as System.IO.FileInfo / System.IO.DirectoryInfo instances.

.EXAMPLE
Touch-Item *.txt

Sets the last-modified and last-accessed timestamps for all text files
in the current directory to the current point in time.

.EXAMPLE
Touch-Item newfile -PassThru

Creates file 'newfile' and outputs information about it as a System.IO.FileInfo
instance.

.EXAMPLE
Touch-Item *.txt -DateTime (Get-Date).Date

Updates the last-modified and last-accessed timestamps for all text files
in the current directory to midnight (the start of) of today''s date.

.EXAMPLE
Get-Item *.txt | Touch-Item -Offset '-1:0'

Sets the last-modified and last-accessed timestamps of all text files
in the current directory back by 1 hour.

.EXAMPLE
Get-ChildItem -File | Touch-Item -ReferencePath . -Offset '-0:1'

Sets the last-modified and last-accessed timestamps of all files in the 
current directory to the last-modified timestamp of the current directory minus
1 minute.


.NOTES
"Touch" is not an approved verb in PowerShell,but it was chosen nonetheless,because none of the approved verbs can adequately convey the core functionality
of this command.

Despite the generic "Item" noun,this command supports *filesystem* $items 
only.

In PowerShell *Core*,implementing this command to support multiple target
paths *as individual arguments* (as in Unix touch) would be possible
(via ValueFromRemainingArguments),but such a solution would misbehave in
Windows PowerShell.

#>

  [CmdletBinding(DefaultParameterSetName = 'Path',SupportsShouldProcess)]
  param(
    [Parameter(ParameterSetName = 'Path',Mandatory,Position = 0,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [Parameter(ParameterSetName = 'PathAndDateTime',ValueFromPipelineByPropertyName)]
    [Parameter(ParameterSetName = 'PathAndRefPath',ValueFromPipelineByPropertyName)]
    [string[]] $Path,[Parameter(ParameterSetName = 'LiteralPath',ValueFromPipelineByPropertyName)]
    [Parameter(ParameterSetName = 'LiteralPathAndDateTime',ValueFromPipelineByPropertyName)]
    [Parameter(ParameterSetName = 'LiteralPathAndRefPath',ValueFromPipelineByPropertyName)]
    [Alias('PSPath','LP')]
    [string[]] $LiteralPath,[Parameter(ParameterSetName = 'PathAndRefPath',Mandatory)]
    [Parameter(ParameterSetName = 'LiteralPathAndRefPath',Mandatory)]
    [string] $ReferencePath,[Parameter(ParameterSetName = 'PathAndDateTime',Mandatory)]
    [Parameter(ParameterSetName = 'LiteralPathAndDateTime',Mandatory)]
    [datetime] $DateTime,[timespan] $Offset,[switch] $NoNew,[switch] $PassThru
  )
  begin { 
    Set-StrictMode -Version 1
    $haveRefPath = $PSBoundParameters.ContainsKey('ReferencePath')
    $haveDateTime = $PSBoundParameters.ContainsKey('DateTime')
    $haveOffset = $PSBoundParameters.ContainsKey('Offset')
    # Initialize defaults (even though they may not be used).
    # Defining them unconditionally prevents strict-mode violations in pseudo-ternary conditionals.
    if (-not ($haveDateTime -or $haveRefPath)) { $DateTime = [datetime]::Now }
    if (-not $haveOffset) { $Offset = 0 }
    # If a reference item was given,obtain its timestamp now and abort if that fails.
    if ($haveRefPath) {
      try {
        $DateTime = (Get-Item -ErrorAction Stop $ReferencePath).LastWriteTime
      }
      catch {
        Throw "Failed to get the reference path's last-modified timestamp: $_"
      }
    }
    $touchedCount = 0
  }

  process {

    $wildcardsSupported = $PSCmdlet.ParameterSetName -notlike 'LiteralPath*'

    # Try to retrieve existing items.
    [array] $items = if ($wildcardsSupported) {
      Get-Item -Path $Path -ErrorAction SilentlyContinue -ErrorVariable err
    }
    else {
      Get-Item -LiteralPath $LiteralPath -ErrorAction SilentlyContinue -ErrorVariable err
    } 

    # -WhatIf / -Confirm support.
    # Note: The prompt message is also printed with just -Verbose
    $targets = ($LiteralPath,($Path,$items.FullName)[$items.Count -gt 0])[$wildcardsSupported] -replace '^Microsoft\.PowerShell\.Core\\FileSystem::' -replace ('^' + [regex]::Escape($PWD) + '[\\/]?')
    if ($targets.Count -gt 1) { $targets = "`n" + ($targets -join "`n") + "`n" }
    $newDateTimeDescr = if ($haveOffset -and -not ($haveDateTime -or $haveRefPath)) { "the current timestamp offset by $Offset" } else { "$($DateTime + $Offset)" }
    $actionDescr = ("Updating / creating with a last-modified timestamp of $newDateTimeDescr","Updating the last-modified timestamp to $newDateTimeDescr")[$NoNew.IsPresent]
    if (-not $PSCmdlet.ShouldProcess($targets,$actionDescr)) { return }

    # Try to create the items that don't yet exist,as files - unless opt-out -NoNew was specified.
    if ($err -and -not $NoNew) {
      $items += foreach ($item in $err.TargetObject) {
        Write-Verbose "Creating: $item"
        New-Item -Type File -Path $item
      }
    }

    # Set the last-modified and last-access timestamps.
    foreach ($item in $items) {
      $newDateTime = ($DateTime,$item.LastWriteTime)[$haveOffset -and -not ($haveDateTime -or $haveRefPath)] + $Offset
      $item.LastWriteTime = $item.LastAccessTime = $newDateTime
      if ($PassThru) { $item }
    }
    $touchedCount += $items.Count

  }

  end {
    if (-not $WhatIfPreference -and $touchedCount -eq 0) {
      Write-Warning "Nothing to touch."
    }
  }

}
本文链接:https://www.f2er.com/3169796.html

大家都在问