7
votes

For PowerShell commands on Windows 10, I encounter a strange behaviour.

To change a file's Date created, I use:

Get-ChildItem  C:\testFile1.txt | % {$_.CreationTime = '01/11/2005 06:00:36'}

To change a folder's Date created, I use:

Get-Item  C:\testFolder1 | % {$_.CreationTime = '01/11/2004 22:13:36'}

Those 2 commands work well on a regular basis on system partition C:\ or on desktop.

The story is different if the folder exists on an external USB flash drive.

(P.S. The command to change a file's timestamp still remains working on the external USB flash drive.)

Suppose I try to change the Date created of a folder (not file) on an external USB flash drive:

Get-Item  U:\testFolder1 | % {$_.CreationTime = '01/11/2002 06:00:36'}

I get this error message:

Exception setting "CreationTime": "The process cannot access the file 'U:\testFolder1' because it is being used by another process."
At line:1 char:31
+ ... et-Item  U:\testFolder1 | % {$_.CreationTime = '01/11/2002 06:00:36'}
+                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

Digging further, I realize that the process is Windows 10's File Explorer, which prevents me from changing the timestamp. As long as I don't open File Explorer, I can use PowerShell to change the Date created of a folder on the USB flash drive.

Is there anyway like .Dispose() to stop Windows 10's File Explorer from locking the folder without the need to close File Explorer every time?

2
You could try with Directory.SetCreationTime() directly: [System.IO.Directory]::SetCreationTime('U:\testFolder1', '01/11/2002 06:00:36')Mathias R. Jessen
Thanks Mathias but this is what I got:Bart Simpson
PS U:\> [System.IO.Directory]::SetCreationTime('U:\testFolder1', '01/11/2000 06:00:36')Bart Simpson
Exception calling "SetCreationTime" with "2" argument(s): "The process cannot access the file 'U:\testFolder1' because it is being used by another process." At line:1 char:1 + [System.IO.Directory]::SetCreationTime('U:\testFolder1', '01/11/2000 ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : IOExceptionBart Simpson

2 Answers

3
votes

I have a function that I keep on hand that uses Handle.exe from SysInternals to find what process has a lock on a file, and then tries to kill that process's lock on the file.

Function Close-LockedFile{
Param(
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][Object[]]$InputFile
)
Begin{
    $HandleApp = 'C:\localbin\Handle.exe'
    If(!(Test-Path $HandleApp)){Write-Host "Handle.exe not found at $HandleApp`nPlease download it from www.sysinternals.com and save it in the afore mentioned location.";break}
}
Process{
    $HandleOut = Invoke-Expression ($HandleApp+' '+$InputFile.Fullname)
    $Locks = $HandleOut |?{$_ -match "(.+?)\s+pid: (\d+?)\s+type: File\s+(\w+?): (.+)\s*$"}|%{
        [PSCustomObject]@{
            'AppName' = $Matches[1]
            'PID' = $Matches[2]
            'FileHandle' = $Matches[3]
            'FilePath' = $Matches[4]
        }
    }
    ForEach($Lock in $Locks){
        Invoke-Expression ($HandleApp + " -p " + $Lock.PID + " -c " + $Lock.FileHandle + " -y") | Out-Null
    }
    $InputFile
}
}

You should be able to pipe your files to that, and it will unlock any that have a lock, and then pass the file object down the pipe.

1
votes

Please try following command.

(Get-Item "U:\testFolder1").LastWriteTime = '01/11/2002 06:00:36'}