Author Posts

October 27, 2015 at 1:26 am

Hi

I'm experiencing that I can not use Get-Item -Force C:\pagefile.sys (even though this is it's current location). It throws the following error:
get-item : Cannot find path 'C:\pagefile.sys' because it does not exist.

attrib.exe says that the pagefile.sys has the ASH attributes. If I set these attributes on a test file I create I can use Get-Item -Force on this file. So the attributes doesn't seem to be the problem.

This does not happen on computers that have powershell 2 (I can get the file as expected without an error). It only happens on computers with powershell 4, but this might be a coincidence.

Does anyone know why the error is thrown?

October 27, 2015 at 4:44 am

The answer seems to be that the file is locked, which causes the underlying Win32 API functions to behave differently. I did some digging in the FileSystemProvider code, and found this link: http://www.developerblogger.com/157_16789819/

The Get-Item code uses the GetFileAttributes function to determine whether a file exists. Because it's returning -1, the FileSystemProvider is behaving as though the file doesn't exist.

It looks like the FileSystemProvider used slightly different code in PowerShell 2.0, doing much of its work via .NET's FileInfo and DirectoryInfo classes instead of going straight to the Win32 API. This change was probably part of a performance increase, but I can't say for sure.

October 27, 2015 at 6:53 am

@kethrax:
Yes, Get-ChildItem -Force will display the pagefile.sys (and other content), but I don't want to use Get-ChildItem. I want to get pagefile.sys as a single object.

Use case: You want to get the size of pagefile.sys:

While this is possible:
(Get-ChildItem -Force \ | Where-Object {$_.Name -eq "pagefile.sys"}).Length

This would be much prettier in every way:
(Get-Item -Force \pagefile.sys).Length

@dlwyatt:
Hm. Nice digging. What kind of lock is set on the file? Is it possible to set this kind of lock with powershell to prove the issue?

EDIT:
Didn't know that @-ing users actually worked. @-ed the real usernames.

October 27, 2015 at 7:23 am

Not sure. I tried opening the file with [FileShare]::None set from .NET, but that didn't reproduce the problem. Might be possible to reproduce this either by digging into Win32 to call its functions with some other combination of parameters, or by running code as LocalSystem.

Incidentally, this works fine even when Get-Item fails: [System.IO.FileInfo]'c:\pagefile.sys'

October 27, 2015 at 7:25 am

You could simply do ...

C:\> (Get-ChildItem -Path C:\ -Filter pagefile.sys -Force).Length
17179869184

Granted ... a little longer than Get-Item, but it works (and without a pipe to Where)