Skip to content

Instantly share code, notes, and snippets.

@mhudasch
Last active September 23, 2016 09:29
Show Gist options
  • Save mhudasch/1826e190a68485854bd1c561833bbaf7 to your computer and use it in GitHub Desktop.
Save mhudasch/1826e190a68485854bd1c561833bbaf7 to your computer and use it in GitHub Desktop.
The Set-FileSystemItem command is the easiest way to create new, empty files. It is also used to change the timestamps (i.e., dates and times of the most recent access and modification) on existing files.
Function Set-FileSystemItem {
<#
.SYNOPSIS
The Set-FileSystemItem command is the easiest way to create new, empty files. It is also used to change the timestamps (i.e., dates and times of the most recent access and modification) on existing files.
.DESCRIPTION
The Set-FileSystemItem command is used to update the access date and / or modification date of a file. In its default usage, it is the equivalent of creating or opening a file and saving it without any change to the file contents. Touch eliminates the unnecessary steps of opening the file, saving the file, and closing the file again. Instead it simply updates the dates associated with the file or directory. An updated access or modification date can be important for a variety of other programs such as backup utilities. Typically these types of programs are only concerned with files which have been created or modified after the program was last run. Set-FileSystemItem can also be useful for quickly creating files for programs or scripts that require a file with a specific name to exist for successful operation of the program, but do not require the file to have any specific content.
.PARAMETER Names
When used without any options, Set-FileSystemItem creates new files for any file names that are provided as arguments (i.e., input data) if files with such names do not already exist. Set-FileSystemItem can create any number of files simultaneously.
.PARAMETER NoCreate
If one of the files does not exist, do not create it and do not report this condition.
.PARAMETER SetLastAccessTime
When present only the access date and time are getting changed. When both SetLastAccessTime and SetLastModifiedTime are missing both are getting changed.
.PARAMETER SetLastModifiedTime
When present only the modified date and time are getting changed. When both SetLastModifiedTime and SetLastAccessTime are missing both are getting changed.
.PARAMETER Date
A parsable [datetime] in string format.
.PARAMETER DateString
A parsable [datetime] in the fixed string format '[YY]MMDDhhmm[.ss]'.
.PARAMETER ReferenceFile
This parameter tells the Set-FileSystemItem command to use the LastAccessTime and LastModifiedTime of the given file as a reference.
.PARAMETER SubtractSeconds
Used in conjunction with the reference file parameter the seconds of this parameter get subtracted from the LastAccessTime and LastModifiedTime of the given reference file.
.PARAMETER AddSeconds
Used in conjunction with the reference file parameter the seconds of this parameter get added to the LastAccessTime and LastModifiedTime of the given reference file.
.EXAMPLE
Set-FileSystemItem myfile.txt
Set-FileSystemItem doesn't modify the contents of myfile.txt; it just updates the timestamp of the file to the computer's current date and time, whatever that happens to be. Or, if myfile.txt does not exist it is created, with zero length.
The short equivalent would be:
touch myfile.txt
.EXAMPLE
Set-FileSystemItem file1,file2,file3
This will perform the command of Set-FileSystemItem to 3 files simultaneously.
The short equivalent would be:
touch file1,file2,file3
.EXAMPLE
Set-FileSystemItem myfile.txt -SetLastAccessTime -SetLastModifiedTime
The -SetLastAccessTime option changes only the access time, while the -SetLastModifiedTime option changes only the modification time. The use of both of these options together changes both the access and modification times to the current time.
The short equivalent would be:
touch myfile.txt -a -m
.EXAMPLE
Set-FileSystemItem myfile.txt -Date '1 May 2005 10:22'
Uses the given parsable DateTime string for the files LastAccessTime and LastModifiedTime.
The short equivalent would be:
touch myfile.txt -d '1 May 2005 10:22'
.EXAMPLE
Set-FileSystemItem myfile.txt -SetLastAccessTime -Date '1 May 2005 10:22'
Uses the given parsable DateTime string only for the files LastAccessTime.
The short equivalent would be:
touch myfile.txt -a -d '1 May 2005 10:22'
.EXAMPLE
Set-FileSystemItem myfile.txt -DateString '0912311627'
Uses the time specified (in the format '[YY]MMDDhhmm[.ss]') to update the LastAccessTime and LastModifiedTime. In this example the times would be the 31. December 2009, 16:27.
The short equivalent would be:
touch myfile.txt -t '0912311627'
.EXAMPLE
Set-FileSystemItem myfile.txt -DateString '0912311627'
Uses the time specified (in the format '[YY]MMDDhhmm[.ss]') to update the LastAccessTime and LastModifiedTime. In this example the times would be the 31. December 2009, 16:27.
The short equivalent would be:
touch myfile.txt -t '0912311627'
.EXAMPLE
Set-FileSystemItem myfile.txt -ReferenceFile somefile.txt
Uses the LastAccessTime and LastModifiedTime of the given reference file 'somefile.txt' and updates the times of 'myfile.txt' to its values.
The short equivalent would be:
touch myfile.txt -r somefile.txt
.EXAMPLE
Set-FileSystemItem myfile.txt -ReferenceFile somefile.txt -SubtractSeconds 30
Uses the LastAccessTime and LastModifiedTime of the given reference file 'somefile.txt' and subtracts 30 seconds of that times. After that the command updates the times of 'myfile.txt' with the resulting times.
The short equivalent would be:
touch myfile.txt -r somefile.txt -B 30
.EXAMPLE
Set-FileSystemItem myfile.txt -ReferenceFile somefile.txt -AddSeconds 20
Uses the LastAccessTime and LastModifiedTime of the given reference file 'somefile.txt' and adds 20 seconds to that times. After that the command updates the times of 'myfile.txt' with the resulting times.
The short equivalent would be:
touch myfile.txt -r somefile.txt -F 30
.EXAMPLE
Set-FileSystemItem myfile.txt -SetLastAccessTime -ReferenceFile somefile.txt
Uses only the LastAccessTime of the given reference file 'somefile.txt' and updates the LastAccessTime of 'myfile.txt'.
The short equivalent would be:
touch myfile.txt -a -r somefile.txt
#>
[CmdletBinding(SupportsShouldProcess=$true)]
Param (
[Parameter(Mandatory=$true,Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string[]]$Names,
[Parameter(Mandatory=$false,Position=1)]
[Alias("c")]
[switch]$NoCreate,
[Parameter(Mandatory=$false,Position=2)]
[Alias("a")]
[switch]$SetLastAccessTime,
[Parameter(Mandatory=$false,Position=3)]
[Alias("m")]
[switch]$SetLastModifiedTime,
[Parameter(Mandatory=$true,Position=4, ParameterSetName="date")]
[Alias("d")]
[nullable`1[datetime]]$Date,
[Parameter(Mandatory=$true,Position=4, ParameterSetName="datestring")]
[Alias("t")]
[ValidatePattern("(?<Y>\d{2})?(?<M>\d{2})(?<T>\d{2})(?<h>\d{2})(?<m>\d{2})(\.(?<s>\d{2}))?")]
[string]$DateString,
[Parameter(Mandatory=$true,Position=4, ParameterSetName="referenced")]
[Alias("r")]
[string]$ReferenceFile,
[Parameter(Mandatory=$false,Position=5, ParameterSetName="referenced")]
[Alias("B")]
[double]$SubtractSeconds = 0,
[Parameter(Mandatory=$false,Position=6, ParameterSetName="referenced")]
[Alias("F")]
[double]$AddSeconds = 0)
Begin {
Function Set-ItemTime {
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[io.filesysteminfo]$Item,
[bool]$IsDirectory,
[datetime]$ADateTime,
[datetime]$MDateTime,
[switch]$LastAccessTime,
[switch]$LastModifiedTime)
Process {
if(-not($LastAccessTime) -and -not($LastModifiedTime)) {
$LastAccessTime = $LastModifiedTime = [switch]::new($true);
}
if($LastAccessTime -and $PSCmdlet.ShouldProcess($Item.FullName, ("Set LastAccessTime to " -f $ADateTime))) {
if($Item -is [io.DirectoryInfo]){
[io.Directory]::SetLastAccessTime($Item.FullName, $ADateTime);
} else {
[io.File]::SetLastAccessTime($Item.FullName, $ADateTime);
}
}
if($LastModifiedTime -and $PSCmdlet.ShouldProcess($Item.FullName, ("Set LastWriteTime to " -f $MDateTime))) {
if($Item -is [io.DirectoryInfo]){
[io.Directory]::SetLastWriteTime($Item.FullName, $MDateTime);
} else {
[io.File]::SetLastWriteTime($Item.FullName, $MDateTime);
}
}
}
}
}
Process {
$Names | ForEach-Object { $n = $_;
$exists = (Test-Path $n);
if(-not($exists) -and -not($NoCreate)) {
$pathPart = [io.Path]::GetDirectoryName($n);
$filePart = [io.Path]::GetFileName($n);
if($pathPart -and -not([io.Directory]::Exists([io.Path]::Combine((Get-Location).Path, $pathPart)))) {
if($PSCmdlet.ShouldProcess($pathPart, "Create new directory.")) {
New-Item -Path $pathPart -ItemType Directory -Force | Out-Null
}
}
if(!$pathPart) { $pathPart = (Get-Location).Path; }
if($PSCmdlet.ShouldProcess([io.Path]::Combine($pathPart, $filePart), "Create new file.")) {
New-item -ItemType File -Path $pathPart -Name $filePart -Force | Out-Null
}
}
if(-not($exists) -and $NoCreate){
return;
}
$attr = [io.File]::GetAttributes([io.Path]::Combine((Get-Location).Path, $n));
if($attr.HasFlag([io.FileAttributes]::Directory)) {
$f = [io.DirectoryInfo]::new([io.Path]::Combine((Get-Location).Path, $n));
} else {
$f = [io.fileInfo]::new([io.Path]::Combine((Get-Location).Path, $n));
}
$aDateTime = $mDateTime = [datetime]::Now;
# date mode
if($Date) {
$aDateTime = $mDateTime = $Date;
# date string mode
} elseif($DateString) {
$match = ([regex]"(?<Y>\d{2})?(?<M>\d{2})(?<T>\d{2})(?<h>\d{2})(?<m>\d{2})(\.(?<s>\d{2}))?").Match($DateString);
$Year = @($match.Groups["Y"].Value, [datetime]::Now.ToString("yy"))[-not($match.Groups["Y"].Success)]
$Month = $match.Groups["M"].Value;
$Day = $match.Groups["T"].Value;
$Hour = $match.Groups["h"].Value;
$Minute = $match.Groups["m"].Value;
$Second = @($match.Groups["s"].Value, "00")[-not($match.Groups["s"].Success)]
$aDateTime = $mDateTime = [datetime]::new((([int]$Year)+2000), [int]$Month, [int]$Day, [int]$Hour, [int]$Minute, [int]$Second);
# reference file mode
} elseif ($ReferenceFile) {
$rexists = (Test-Path $ReferenceFile);
if(!$rexists){
throw "Reference file or directory does not exist.";
}
$rattr = [io.File]::GetAttributes([io.Path]::Combine((Get-Location).Path, $ReferenceFile));
if($rattr.HasFlag([io.FileAttributes]::Directory)) {
$rf = [io.DirectoryInfo]::new([io.Path]::Combine((Get-Location).Path, $ReferenceFile));
$aDateTime = [io.Directory]::GetLastAccessTime($rf.FullName).AddSeconds($AddSeconds).AddSeconds($SubtractSeconds * -1.0);
$mDateTime = [io.Directory]::GetLastWriteTime($rf.FullName).AddSeconds($AddSeconds).AddSeconds($SubtractSeconds * -1.0);
} else {
$rf = [io.DirectoryInfo]::new([io.Path]::Combine((Get-Location).Path, $ReferenceFile));
$aDateTime = [io.File]::GetLastAccessTime($rf.FullName).AddSeconds($AddSeconds).AddSeconds($SubtractSeconds * -1.0);
$mDateTime = [io.File]::GetLastWriteTime($rf.FullName).AddSeconds($AddSeconds).AddSeconds($SubtractSeconds * -1.0);
}
}
if($PSCmdlet.ShouldProcess($f.FullName, "Set file/directory attributes")) {
Set-ItemTime -Item $f -IsDirectory ($attr.HasFlag([io.FileAttributes]::Directory)) -ADateTime $aDateTime -MDateTime $mDateTime -LastAccessTime:($SetLastAccessTime.IsPresent) -LastModifiedTime:($SetLastModifiedTime.IsPresent)
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment