CIM_DataFile

The CIM_DataFile class represents a file on a drive.

CIM_DataFile represents (any) file on (any) accessible drive. This is why CIM_DataFile is an extremely useful and at the same time dangerous WMI class. When you query for CIM_DataFile without any constraints, WMI enumerates all files which can be hundreds of thousands of instances. This may take a long time or even error out due to missing resources.

The same applies when you do add constraints but use the WQL operator LIKE. For fast results, it is of utmost importance to use fixed constraints on Name or Path. The examples below illustrate this.

Examples

Let’s start with a line of code that you should never execute: it takes a very long time to complete and yields hundreds of thousands of instances, one per accessible file:

# don't run this:
Get-CimInstance -ClassName CIM_DataFile

For fast results, always make sure you specify a constraint on Name or Path. Name is the full path name of a file (including drive and filename) whereas Path is the path component only (without drive and filename).

Accessing Individual File

To access an individual file, use a constraint on Name:

# access a single file
$path = 'c:\windows\explorer.exe'
# escape backslash for wmi
$wmipath = $path.Replace('\','\\')
Get-CimInstance -Class Cim_DataFile -Filter "Name='$wmipath'"

The backslash is a special escape character in WQL which is why in paths, a literal backslash needs to be escaped. In essence, each backslash needs to be replaced by two backslashes.

Accessing Folder Content

To access the files in a folder, use a constraint on Path:

# access all files in a folder
$path = 'c:\windows'
$drive = Split-Path -Path $path -Qualifier
$folder = Split-Path -Path $path -NoQualifier
# escape backslash for wmi and make sure the folder ends with a backslash:
$wmifolder = ($folder.TrimEnd('\') + "\").Replace('\','\\')
Get-CimInstance -Class Cim_DataFile -Filter "Drive='$drive' and Path='$wmifolder'"

The property Path contains the path component only (without drive and filename). This path must start and end with a backslash.

Files And Subfolders

Since CIM_DataFile represents files only, the result are just the files in the folder. Subfolders are not listed. If you want to return both files and subfolders, use the parent class CIM_LogicalFile which represents both files and folders:

# access files and subfolders in a folder
$path = 'c:\windows'
$drive = Split-Path -Path $path -Qualifier
$folder = Split-Path -Path $path -NoQualifier
# escape backslash for wmi and make sure the folder ends with a backslash:
$wmifolder = ($folder.TrimEnd('\') + "\").Replace('\','\\')
Get-CimInstance -Class Cim_LogicalFile -Filter "Drive='$drive' and Path='$wmifolder'"

Subfolders Only

To list only subfolders and exclude files, use Win32_Directory instead:

# access files and subfolders in a folder
$path = 'c:\windows'
$drive = Split-Path -Path $path -Qualifier
$folder = Split-Path -Path $path -NoQualifier
# escape backslash for wmi and make sure the folder ends with a backslash:
$wmifolder = ($folder.TrimEnd('\') + "\").Replace('\','\\')
Get-CimInstance -Class Win32_Directory -Filter "Drive='$drive' and Path='$wmifolder'"

Careful With LIKE

WMI queries come with powerful query operators such as LIKE which (theoretically) allow you to recursively search for files. This example lists all files with extension .log anywhere in your windows folder:

# warning: this is not recommended and takes a long time to complete
Get-CimInstance -ClassName CIM_DataFile -Filter 'Drive="c:" and Path LIKE "\\windows\\%" and Extension="log"'

While this line will eventually return the requested information, it will take a very long time, and you may even run out of resources. The CPU load is high. This is because when your query does not use explicit filters on Name or Path, WMI always first retrieves all instances of CIM_DataFile. In essence, it first collects every single file on your system. Only then will it apply the filter and return the requested log files.

A query like the one above can run a couple of minutes and use 100% CPU time for one core at that time.

So you should avoid the WQL operator LIKE on the properties Name and Path. You can safely use it for any other property, but either Name or Path should always specified as a fixed constraint:

# finding all files with extension that starts with L in Windows folder:
Get-CimInstance -ClassName CIM_DataFile -Filter 'Drive="c:" and Path="\\windows\\" and Extension LIKE "l%"'

Because of this limitation, you cannot easily query multiple folders recursively in WMI.

Searching Recursively

First of all: WMI is not a perfect solution for recursive searches. Classes like CIM_DataFile are extremely useful for accessing or testing the existence of individual files, or dumping the direct content of one folder.

Once you want to search for a file across multiple folders, WMI becomes very slow. Still, if you must use WMI to find files, the first step is not to use wildcard queries and the WMI operator LIKE. As pointed out already, in order to use wildcard queries, WMI always enumerates all files on your system first which is prohibitive.

A more realistic approach is implementing the recursion yourself. This still takes much more execution time than using local commands such as Get-ChildItem, but it is faster than wildcard queries.

Here is an example of such a self-implemented recursion: Get-LogicalFile dumps the content of a folder and optionally supports a parameter -Recurse. When specified, the function calls itself whenever it hits a subfolder.

function Get-LogicalFile
{
  [CmdletBinding(DefaultParameterSetName='AutomaticSession')]
  param
  (
    # path to file
    [Parameter(Mandatory)]
    [string]
    $FilePath,

    # search recursively
    [switch]
    $Recurse,

    # return files only
    [switch]
    $File,
    
    # return directories only
    [switch]
    $Directory,
    
    # additional custom filters
    [string]
    $FilterString,
    
    # optional remoting session
    [Parameter(ParameterSetName='ReusableSession')]
    [CimSession[]]
    $CimSession,
    
    # optional computer name(s)
    [Parameter(ParameterSetName='AutomaticSession')]
    [Alias('CN','ServerName')]
    [string[]]
    $ComputerName,
    
    # maximum time for query in seconds
    [Alias('OT')]
    [uint32]
    $OperationTimeoutSec,
    
    # properties to return. When omitted, all properties are returned:
    [Alias('SelectProperties')]
    [string[]]
    $Property
  )
  
  # escape backslash
  $FilePath = $FilePath.Replace('\','\\')
  # identify our own parameters;
  $blacklist = 'filepath','recurse','file','directory','filterstring'
  # reuse parameters for WMI via splatting for recursive calling
  $parameters = $PSBoundParameters.Keys | 
  # exclude our own parameters...
  Where-Object { $blacklist -notcontains $_ } | 
  # ...and copy the remainder to a hashtable for splatting:
  ForEach-Object { $clone = @{}} { $clone[$_] = $PSBoundParameters[$_] } { $clone}
  
  # search by drive and path
  $drive = $FilePath | Split-Path -Qualifier
  $path = (($FilePath | Split-Path -NoQualifier).TrimEnd('\') + '\\')
  
  # if -File was specified, search for files:
  if (!$Directory.IsPresent)
  {
    if (![string]::IsNullOrWhiteSpace($FilterString))
    {
      $parameters["Filter"] = "Drive='$drive' and Path='$path' and $FilterString"
    }
    else
    {
      $parameters["Filter"] = "Drive='$drive' and Path='$path'"
    } 
    Get-CimInstance -ClassName CIM_DataFile @parameters
  }
  # if -Directory is specified, search for subfolders:
  if ($Directory.IsPresent -or $Recurse.IsPresent)
  {
    # do not use custom filtering for subfolders
    $parameters["Filter"] = "Drive='$drive' and Path='$path'" 
    Get-CimInstance -ClassName Win32_Directory @parameters |
    ForEach-Object {
      if (!$File.IsPresent) { $_ }
        
      # do recursion
      if ($Recurse.isPresent)
      {
        $PSBoundParameters['FilePath'] = $_.Name
        Get-LogicalFile @PSBoundParameters 
      }
    }
  }
}

To find all files with extension .log anywhere in the folder Security inside your Windows folder, run it like this:

Get-LogicalFile -FilePath "$env:windir\security" -Recurse -FilterString 'Extension="log"' -File | Select-Object -Property Name, FileSize

Recursion works great and takes only a few seconds when you traverse a few subfolders. Once you traverse large folder structures, i.e. the entire windows folder, it, too, becomes painfully slow.

The result looks similar to this:

Name                                    FileSize
----                                    --------
C:\Windows\security\database\edb.log     1048576
C:\Windows\security\database\edbtmp.log  1048576
C:\Windows\security\logs\scecomp.log         930
C:\Windows\security\logs\scesetup.log      13404

Resolving Paths

Sometimes, even though you don’t know the exact file location, you can still pinpoint the location using wildcards. For example, PowerShell comes with Resolve-Path to resolve paths like this one:

# find location of winword.exe
Resolve-Path -Path "C:\Program Files*\Microsoft Office\root\Office*\WINWORD.EXE"

This command would find winword.exe regardless of whether it is installed as a 32-bit or 64-bit application, and regardless of version, provided it is installed at all and stored in the general path scheme you resolved:

Path                                                             
----                                                             
C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE

Some Office versions do not use the subfolder root so as you see, this is not a catch-all solution, and you may have to resolve multiple potential paths. This is still faster than searching the entire folder structure recursively.

WMI can also locally and remotely resolve paths for you: Resolve-WmiPath starts at the root of a path and then examines each subfolder and replaces wildcards with the actual subfolders WMI found:

function Resolve-WmiPath
{
  [CmdletBinding(DefaultParameterSetName='AutomaticSession')]
  param
  (
    # path to resolve. May contain wildcards (*)
    [String]
    [Parameter(Mandatory,ValueFromPipeline)]
    $Path,
    
    # optional remoting session
    [Parameter(ParameterSetName='ReusableSession')]
    [CimSession[]]
    $CimSession,
    
    # optional computer name(s)
    [Parameter(ParameterSetName='AutomaticSession')]
    [Alias('CN','ServerName')]
    [string[]]
    $ComputerName
  )
  
  process
  {
    # forward parameters less private parameters
    # we are forwarding any optional remoting session or computername
    $null = $PSBoundParameters.Remove('Path')
    
    # no more wildcards? We are done:
    if ($Path -notmatch '\*') { 
      # check to see if this path exists:
      $wmiPath = $Path.Replace('\','\\').Replace('_','\_')
      $exists = @(Get-CimInstance -ClassName CIM_LogicalFile -Property Name -Filter "Name='$wmiPath'" @PSBoundParameters).Count -gt 0
      # emit it only if it exists:
      if ($exists) { return $Path }
    }
    
    # get path components:
    $drive = Split-Path -Path $Path -Qualifier
    $paths = Split-Path -Path $Path -NoQualifier
    # examine each folder in path separately:
    $folders = $paths.Trim('\') -split '\\'
  
    # construct the current path as we go
    # the loop investigates each additional subfolder and recurses:
    $parentPath = $drive
    $relativePath = '\\'
    # this is the number of characters we read into the
    # string with folders so we can add the remaining folders
    # later:
    $offset = 0
    
    # examine each folder:
    foreach($folder in $folders)
    {
      # calculate the string offset in the remainder of the folders string:
      $offset += ($folder.length + 1)
      # if the current folder has wildcards...
      if ($folder -match '\*')
      {
        # use WMI to get the actual folders at this location
        
        # use WMI wildcard: % in place of *
        $currentPath = (Join-Path $parentPath -ChildPath $folder).Replace('*','%').Replace('\','\\').Replace('_','\_')
        $remainder = $paths.Substring($offset)
        
        # add the optional remoting session or computer name infos:
        Get-CimInstance -ClassName Cim_LogicalFile -Property Name -Filter "Drive='$drive' and Path='$relativePath' and Name LIKE '$currentPath'" @PSBoundParameters | 
          # add the remainder (unexamined) folders to the identified paths:
          ForEach-Object { Join-Path -Path $_.Name -ChildPath $remainder } |
          # call the function again with the path(s) that have been resolved so far: 
          Resolve-WmiPath @PSBoundParameters
      }
      else
      {
        # folder has no wildcards, just add and continue:
        $relativePath += ($folder + '\\')
        $parentPath = Join-Path -Path $parentPath -ChildPath $folder
      }
    }
  }
}

In contrast to Resolve-Path, Resolve-WmiPath comes with built-in remoting, so it can be used to resolve paths on remote machines as well:

# testing against own machine. Replace computername with target machine name.
$computerName = $env:computerName

Resolve-WmiPath -Path "C:\Program Files*\Microsoft Office\root\Office*\WINWORD.EXE" -ComputerName $computername

The resolved paths can then be used to directly specify the files and paths you need to work with, and to speed up WMI queries this way.

Remote Access

To access remote system(s), use the parameter -ComputerName:

Get-CimInstance -ClassName CIM_DataFile -Filter 'Name="c:\\windows\\explorer.exe"' -ComputerName webserver12

Learn more about accessing remote computers.

Get-ChildItem is the equivalent of a built-in cmdlet to list files and folders. This cmdlet has no remoting capabilities. It is much faster than WMI, though, because it has considerably less overhead.

Methods

CIM_DataFile has 14 methods:
Method Description
ChangeSecurityPermissions Changes the security permissions for the logical file specified in the object path. Implemented by WMI.
ChangeSecurityPermissionsEx Changes the security permissions for the logical file specified in the object path. Implemented by WMI.
Compress Uses NTFS compression to compress the logical file (or directory) specified in the object path. Implemented by WMI.
CompressEx Compresses the logical file (or directory) specified in the object path. Implemented by WMI.
Copy Copies the logical file (or directory) specified in the object path to the location specified by the input parameter. Implemented by WMI.
CopyEx Copies the logical file (or directory) specified in the object path to the location specified by the input parameter. Implemented by WMI.
Delete Deletes the logical file (or directory) specified in the object path. Implemented by WMI.
DeleteEx Deletes the logical file (or directory) specified in the object path. Implemented by WMI.
GetEffectivePermission Determines whether the caller has the aggregated permissions specified by the Permission argument. Implemented by WMI.
Rename Renames the logical file (or directory) specified in the object path. Implemented by WMI.
TakeOwnerShip Obtains ownership of the logical file specified in the object path. Implemented by WMI.
TakeOwnerShipEx Obtains ownership of the logical file specified in the object path. Implemented by WMI.
Uncompress Uncompresses the logical file (or directory) specified in the object path. Implemented by WMI.
UncompressEx Uncompresses the logical file (or directory) specified in the object path. Implemented by WMI.

Learn more about Invoke-CimMethod and how to invoke commands. Click any of the methods listed above to learn more about their purpose, parameters, and return value.

Properties

CIM_DataFile returns 32 properties:

'AccessMask','Caption','Compressed','CompressionMethod','CreationClassName',
'CreationDate','CSCreationClassName','CSName','Description','Drive','EightDotThreeFileName',
'Encrypted','EncryptionMethod','Extension','FileName','FileSize','FileType','FSCreationClassName',
'FSName','Hidden','InstallDate','InUseCount','LastAccessed','LastModified','Manufacturer',
'Name','Path','Readable','Status','System','Version','Writeable'

Unless explicitly marked as WRITEABLE, all properties are read-only.

AccessMask

UINT32

Bitmask that represents the access rights required to access or perform specific operations on the file.

Note: On FAT volumes, the FULL_ACCESS value is returned instead, which indicates no security has been set on the object.

AccessMask returns a numeric value. To translate it into a meaningful text, use any of the following approaches:

Use Update-Type

Update-Type tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:

Update-TypeData -MemberName AccessMask -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/cim_datafile" -MemberType ScriptProperty  -Value {
  [Flags()] Enum EnumAccessMask
  {
    READDATA_LISTDIRECTORY   = 1
    WRITEDATA_ADDFILE        = 2
    APPENDDATA_ADDSUBDIR     = 4
    READEA                   = 8
    WRITEEA                  = 16
    EXECUTE_TRAVERSE         = 32
    DELETECHILD              = 64
    READATTRIBUTES           = 128
    WRITEATTRIBUTES          = 256
    UNKNOWN512               = 512
    UNKNOWN1024              = 1024
    UNKNOWN2048              = 2048
    UNKNOWN4196              = 4096
    UNKNOWN8192              = 8192
    UNKNOWN16384             = 16384
    UNKNOWN32768             = 32768
    DELETE                   = 65536
    READCONTROL              = 131072
    WRITEDAC                 = 262144
    WRITEOWNER               = 524288
    SYNCHRONIZE              = 1048576
    UNKNOWN2097152           = 2097152
    UNKNOWN4194304           = 4194304
    UNKNOWN8388608           = 8388608
  }

  [EnumAccessMask]($this.PSBase.CimInstanceProperties['AccessMask'].Value)
} -Force

Get-CimInstance -ClassName CIM_DataFile -Filter "Name='c:\\windows\\explorer.exe'" | Select-Object -Property Name, AccessMask
Use Select-Object

Select-Object supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:

$AccessMask = @{
  Name = 'AccessMaskText'
  Expression = {
    [Flags()] Enum EnumAccessMask
    {
      READDATA_LISTDIRECTORY   = 1
      WRITEDATA_ADDFILE        = 2
      APPENDDATA_ADDSUBDIR     = 4
      READEA                   = 8
      WRITEEA                  = 16
      EXECUTE_TRAVERSE         = 32
      DELETECHILD              = 64
      READATTRIBUTES           = 128
      WRITEATTRIBUTES          = 256
      UNKNOWN512               = 512
      UNKNOWN1024              = 1024
      UNKNOWN2048              = 2048
      UNKNOWN4196              = 4096
      UNKNOWN8192              = 8192
      UNKNOWN16384             = 16384
      UNKNOWN32768             = 32768
      DELETE                   = 65536
      READCONTROL              = 131072
      WRITEDAC                 = 262144
      WRITEOWNER               = 524288
      SYNCHRONIZE              = 1048576
      UNKNOWN2097152           = 2097152
      UNKNOWN4194304           = 4194304
      UNKNOWN8388608           = 8388608
    }
    
    [EnumAccessMask][int]$_.AccessMask
  }  
}

Get-CimInstance -ClassName CIM_DataFile | Select-Object -Property Name, AccessMask, $AccessMask
Use a PowerShell Hashtable

You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:

$AccessMask_map = @{
      1 = 'READDATA_LISTDIRECTORY'
      2 = 'WRITEDATA_ADDFILE'
      4 = 'APPENDDATA_ADDSUBDIR'
      8 = 'READEA'
     16 = 'WRITEEA'
     32 = 'EXECUTE_TRAVERSE'
     64 = 'DELETECHILD'
    128 = 'READATTRIBUTES'
    256 = 'WRITEATTRIBUTES'
    512 = 'UNKNOWN512'
   1024 = 'UNKNOWN1024'
   2048 = 'UNKNOWN2048'
   4096 = 'UNKNOWN4196'
   8192 = 'UNKNOWN8192'
  16384 = 'UNKNOWN16384'
  32768 = 'UNKNOWN32768'
  65536 = 'DELETE'
 131072 = 'READCONTROL'
 262144 = 'WRITEDAC'
 524288 = 'WRITEOWNER'
1048576 = 'SYNCHRONIZE'
2097152 = 'UNKNOWN2097152'
4194304 = 'UNKNOWN4194304'
8388608 = 'UNKNOWN8388608'
}
Use Enum structure

You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:

[Flags()] Enum EnumAccessMask
{
  READDATA_LISTDIRECTORY   = 1
  WRITEDATA_ADDFILE        = 2
  APPENDDATA_ADDSUBDIR     = 4
  READEA                   = 8
  WRITEEA                  = 16
  EXECUTE_TRAVERSE         = 32
  DELETECHILD              = 64
  READATTRIBUTES           = 128
  WRITEATTRIBUTES          = 256
  UNKNOWN512               = 512
  UNKNOWN1024              = 1024
  UNKNOWN2048              = 2048
  UNKNOWN4196              = 4096
  UNKNOWN8192              = 8192
  UNKNOWN16384             = 16384
  UNKNOWN32768             = 32768
  DELETE                   = 65536
  READCONTROL              = 131072
  WRITEDAC                 = 262144
  WRITEOWNER               = 524288
  SYNCHRONIZE              = 1048576
  UNKNOWN2097152           = 2097152
  UNKNOWN4194304           = 4194304
  UNKNOWN8388608           = 8388608
}

Caption

STRING MAX 64 CHAR

A short textual description of the object.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Caption

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Caption | Foreach-Object {

  $Name = $_.Name
  $value = $_.Caption
  "${Name}: Caption = $value"
}

Compressed

BOOL

If $true, the file is compressed.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Compressed

# filtering all instances with Compressed set to $true:
Get-CimInstance -ClassName CIM_DataFile | Where-Object Compressed -eq $true | Select-Object -Property Name, Compressed

CompressionMethod

STRING

Free-form string that indicates the algorithm or tool used to compress the logical file. If the compression scheme is unknown or not described, use “Unknown”. If the logical file is compressed, but the compression scheme is unknown or not described, use “Compressed”. If the logical file is not compressed, use “Not Compressed”. This property may be empty.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CompressionMethod

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CompressionMethod | Foreach-Object {

  $Name = $_.Name
  $value = $_.CompressionMethod
  "${Name}: CompressionMethod = $value"
}

CreationClassName

STRING

Name of the class.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CreationClassName

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CreationClassName | Foreach-Object {

  $Name = $_.Name
  $value = $_.CreationClassName
  "${Name}: CreationClassName = $value"
}

CreationDate

DATETIME

Date and time of the file’s creation.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CreationDate

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CreationDate | Foreach-Object {

  $Name = $_.Name
  $value = $_.CreationDate
  "${Name}: CreationDate = $value"
}

CSCreationClassName

STRING

Class of the computer system.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CSCreationClassName

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CSCreationClassName | Foreach-Object {

  $Name = $_.Name
  $value = $_.CSCreationClassName
  "${Name}: CSCreationClassName = $value"
}

CSName

STRING

Name of the computer system.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CSName

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, CSName | Foreach-Object {

  $Name = $_.Name
  $value = $_.CSName
  "${Name}: CSName = $value"
}

Description

STRING

A textual description of the object.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Description

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Description | Foreach-Object {

  $Name = $_.Name
  $value = $_.Description
  "${Name}: Description = $value"
}

Drive

STRING

Drive letter (including the colon that follows the drive letter) of the file.

Example: “c:”

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Drive

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Drive | Foreach-Object {

  $Name = $_.Name
  $value = $_.Drive
  "${Name}: Drive = $value"
}

EightDotThreeFileName

STRING

DOS-compatible file name.

Example: “c:\progra~1”

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, EightDotThreeFileName

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, EightDotThreeFileName | Foreach-Object {

  $Name = $_.Name
  $value = $_.EightDotThreeFileName
  "${Name}: EightDotThreeFileName = $value"
}

Encrypted

BOOL

If $true, the file is encrypted.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Encrypted

# filtering all instances with Encrypted set to $true:
Get-CimInstance -ClassName CIM_DataFile | Where-Object Encrypted -eq $true | Select-Object -Property Name, Encrypted

EncryptionMethod

STRING

Free-form string that identifies the algorithm or tool used to encrypt a logical file. If the encryption scheme is not indulged (for security reasons, for example), use “Unknown”. If the file is encrypted, but either its encryption scheme is unknown or not disclosed, use “Encrypted”. If the logical file is not encrypted, use “Not Encrypted”.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, EncryptionMethod

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, EncryptionMethod | Foreach-Object {

  $Name = $_.Name
  $value = $_.EncryptionMethod
  "${Name}: EncryptionMethod = $value"
}

Extension

STRING

File name extension without the preceding period (dot).

Example: “txt”, “mof”, “mdb”

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Extension

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Extension | Foreach-Object {

  $Name = $_.Name
  $value = $_.Extension
  "${Name}: Extension = $value"
}

FileName

STRING

File name without the file name extension. Example: “MyDataFile”

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FileName

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FileName | Foreach-Object {

  $Name = $_.Name
  $value = $_.FileName
  "${Name}: FileName = $value"
}

FileSize

UINT64 “BYTES”

Size of the file, in bytes.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FileSize

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FileSize | Foreach-Object {

  $Name = $_.Name
  $value = $_.FileSize
  "${Name}: FileSize = $value bytes" 
  'FileSize = {0:n1} MB' -f ($_/1MB)
}

You can update the PowerShell type database to automatically convert the raw property value. This example illustrates overwriting ToString() method to provide formatted output while leaving the original property value untouched:

# outputting raw value:
Get-CimInstance -ClassName CIM_DataFile | Select-Object -ExpandProperty FileSize

# updating type database (needs to be done only once per PowerShell session)
# this command instructs PowerShell to overwrite the method ToString() and automatically divide the raw value and transform it in a different unit:
Update-TypeData -MemberName FileSize -TypeName 'Microsoft.Management.Infrastructure.CimInstance#root/cimv2/cim_datafile' -MemberType ScriptProperty -Value { ($this.PSBase.CimInstanceProperties['FileSize'].Value) | Add-Member -MemberType ScriptMethod -Name ToString -Force -Value { "{0:n2} MB" -f ($this/1MB) } -PassThru } -Force

# compare the results of the identical command.
# raw values are now automatically transformed into a more meaningful unit:
Get-CimInstance -ClassName CIM_DataFile | Select-Object -ExpandProperty FileSize

FileType

STRING

Descriptor that represents the file type indicated by the Extension property.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FileType

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FileType | Foreach-Object {

  $Name = $_.Name
  $value = $_.FileType
  "${Name}: FileType = $value"
}

FSCreationClassName

STRING

Class of the file system.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FSCreationClassName

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FSCreationClassName | Foreach-Object {

  $Name = $_.Name
  $value = $_.FSCreationClassName
  "${Name}: FSCreationClassName = $value"
}

FSName

STRING

Name of the file system.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FSName

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, FSName | Foreach-Object {

  $Name = $_.Name
  $value = $_.FSName
  "${Name}: FSName = $value"
}

Hidden

BOOL

If $true, the file is hidden.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Hidden

# filtering all instances with Hidden set to $true:
Get-CimInstance -ClassName CIM_DataFile | Where-Object Hidden -eq $true | Select-Object -Property Name, Hidden

InstallDate

DATETIME

Indicates when the object was installed. Lack of a value does not indicate that the object is not installed.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, InstallDate

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, InstallDate | Foreach-Object {

  $Name = $_.Name
  $value = $_.InstallDate
  "${Name}: InstallDate = $value"
}

InUseCount

UINT64

Number of “file opens” that are currently active against the file.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, InUseCount

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, InUseCount | Foreach-Object {

  $Name = $_.Name
  $value = $_.InUseCount
  "${Name}: InUseCount = $value"
}

LastAccessed

DATETIME

Date and time the file was last accessed.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, LastAccessed

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, LastAccessed | Foreach-Object {

  $Name = $_.Name
  $value = $_.LastAccessed
  "${Name}: LastAccessed = $value"
}

LastModified

DATETIME

Date and time the file was last modified.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, LastModified

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, LastModified | Foreach-Object {

  $Name = $_.Name
  $value = $_.LastModified
  "${Name}: LastModified = $value"
}

Manufacturer

STRING

Manufacturer string from the version resource (if one is present).

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Manufacturer

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Manufacturer | Foreach-Object {

  $Name = $_.Name
  $value = $_.Manufacturer
  "${Name}: Manufacturer = $value"
}

Name

KEY PROPERTY STRING

The Name property is a string representing the inherited name that serves as a key of a logical file instance within a file system. Full path names should be provided.

Example: C:\Windows\system\win.ini

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Name | Foreach-Object {

  $Name = $_.Name
  $value = $_.Name
  "${Name}: Name = $value"
}

Path

STRING

Path of the file including the leading and trailing backslashes. Example: “\windows\system"

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Path

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Path | Foreach-Object {

  $Name = $_.Name
  $value = $_.Path
  "${Name}: Path = $value"
}

Readable

BOOL

If $true, the file can be read.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Readable

# filtering all instances with Readable set to $true:
Get-CimInstance -ClassName CIM_DataFile | Where-Object Readable -eq $true | Select-Object -Property Name, Readable

Status

STRING MAX 10 CHAR

Current status of an object. Various operational and nonoperational statuses can be defined.

Available values:

'Degraded','Error','Lost Comm','No Contact','NonRecover','OK','Pred Fail','Service','Starting','Stopping','Stressed','Unknown'
# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Status

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Status | Foreach-Object {

  $Name = $_.Name
  $value = $_.Status
  "${Name}: Status = $value"
}

System

BOOL

If $true, the file is a system file.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, System

# filtering all instances with System set to $true:
Get-CimInstance -ClassName CIM_DataFile | Where-Object System -eq $true | Select-Object -Property Name, System

Version

STRING

Version string from the version resource (if one is present).

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Version

# reading property value:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Version | Foreach-Object {

  $Name = $_.Name
  $value = $_.Version
  "${Name}: Version = $value"
}

Writeable

BOOL

If $true, the file can be written.

# returning class instances:
Get-CimInstance -ClassName CIM_DataFile -Filter "Drive='c:' and Path='\\windows\\system32\\'" | Select-Object -Property Name, Writeable

# filtering all instances with Writeable set to $true:
Get-CimInstance -ClassName CIM_DataFile | Where-Object Writeable -eq $true | Select-Object -Property Name, Writeable

CDXML Definition

You can turn this WMI class and its methods into PowerShell cmdlets by importing below CDXML file (Cmdlet Definition XML) as a module.

Create CIM_DataFile.cdxml
$folder = "c:\wmi\CIM_DataFile"
$cdxmlPath = Join-Path -Path $folder -ChildPath "CIM_DataFile.cdxml"

# create folder if not present:
$exists = Test-Path -Path $folder
if (!$exists) { $null = New-Item -Path $folder -ItemType Directory }

# write file
$content = @'
<?xml version="1.0" encoding="utf-8"?>


<!--
This file is licensed under 'Attribution 4.0 International' license (https://creativecommons.org/licenses/by/4.0/).

You can free of charge use this code in commercial and non-commercial code, and you can freely modify and adjust the code 
as long as you give appropriate credit to the original author Dr. Tobias Weltner.

This material was published and is maintained here: 

https://powershell.one/wmi/root/cimv2/cim_datafile#cdxml-definition
-->


<PowerShellMetadata xmlns="http://schemas.microsoft.com/cmdlets-over-objects/2009/11">
  <!--referencing the WMI class this cdxml uses-->
  <Class ClassName="Root/CIMV2\CIM_DataFile" ClassVersion="2.0">
    <Version>1.0</Version>
    <!--default noun used by Get-cmdlets and when no other noun is specified. By convention, we use the prefix "WMI" and the base name of the WMI class involved. This way, you can easily identify the underlying WMI class.-->
    <DefaultNoun>WmiDataFile</DefaultNoun>
    <!--define the cmdlets that work with class instances.-->
    <InstanceCmdlets>
      <!--query parameters to select instances. This is typically empty for classes that provide only one instance-->
      <GetCmdletParameters>
        <QueryableProperties>
          <Property PropertyName="Drive">
            <Type PSType="system.string" />
            <RegularQuery AllowGlobbing="false">
              <CmdletParameterMetadata IsMandatory="false" />
            </RegularQuery>
          </Property>
          <Property PropertyName="Name">
            <Type PSType="system.string" />
            <RegularQuery AllowGlobbing="false">
              <CmdletParameterMetadata IsMandatory="false" />
            </RegularQuery>
          </Property>
          <Property PropertyName="Path">
            <Type PSType="system.string" />
            <RegularQuery AllowGlobbing="false">
              <CmdletParameterMetadata IsMandatory="false" />
            </RegularQuery>
          </Property>
        </QueryableProperties>
      </GetCmdletParameters>
      <GetCmdlet>
        <CmdletMetadata Verb="Get" />
        <GetCmdletParameters>
          <QueryableProperties>
            <Property PropertyName="AccessMask">
              <Type PSType="system.uint32" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Compressed">
              <Type PSType="switch" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="CompressionMethod">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="CreationClassName">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="CreationDate">
              <Type PSType="system.datetime" />
              <MinValueQuery>
                <CmdletParameterMetadata PSName="BeforeCreationDate" />
              </MinValueQuery>
              <MaxValueQuery>
                <CmdletParameterMetadata PSName="AfterCreationDate" />
              </MaxValueQuery>
            </Property>
            <Property PropertyName="CSCreationClassName">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="CSName">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Description">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Drive">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="EightDotThreeFileName">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Encrypted">
              <Type PSType="switch" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="EncryptionMethod">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Extension">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="FileName">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="FileSize">
              <Type PSType="system.uint64" />
              <MinValueQuery>
                <CmdletParameterMetadata PSName="MinFileSize" />
              </MinValueQuery>
              <MaxValueQuery>
                <CmdletParameterMetadata PSName="MaxFileSize" />
              </MaxValueQuery>
            </Property>
            <Property PropertyName="FileType">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="FSCreationClassName">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="FSName">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Hidden">
              <Type PSType="switch" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="InstallDate">
              <Type PSType="system.datetime" />
              <MinValueQuery>
                <CmdletParameterMetadata PSName="BeforeInstallDate" />
              </MinValueQuery>
              <MaxValueQuery>
                <CmdletParameterMetadata PSName="AfterInstallDate" />
              </MaxValueQuery>
            </Property>
            <Property PropertyName="InUseCount">
              <Type PSType="system.uint64" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="LastAccessed">
              <Type PSType="system.datetime" />
              <MinValueQuery>
                <CmdletParameterMetadata PSName="BeforeLastAccessed" />
              </MinValueQuery>
              <MaxValueQuery>
                <CmdletParameterMetadata PSName="AfterLastAccessed" />
              </MaxValueQuery>
            </Property>
            <Property PropertyName="LastModified">
              <Type PSType="system.datetime" />
              <MinValueQuery>
                <CmdletParameterMetadata PSName="BeforeLastModified" />
              </MinValueQuery>
              <MaxValueQuery>
                <CmdletParameterMetadata PSName="AfterLastModified" />
              </MaxValueQuery>
            </Property>
            <Property PropertyName="Manufacturer">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Name">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
              <ExcludeQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" PSName="ExcludeName" />
              </ExcludeQuery>
            </Property>
            <Property PropertyName="Path">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Readable">
              <Type PSType="switch" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Status">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="System">
              <Type PSType="switch" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Version">
              <Type PSType="system.string" />
              <RegularQuery AllowGlobbing="true">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
            <Property PropertyName="Writeable">
              <Type PSType="switch" />
              <RegularQuery AllowGlobbing="false">
                <CmdletParameterMetadata IsMandatory="false" />
              </RegularQuery>
            </Property>
          </QueryableProperties>
        </GetCmdletParameters>
      </GetCmdlet>
      <!--defining additional cmdlets that modifies instance properties-->
      <!--Set-DataFileSecurityPermissions: invoking method ChangeSecurityPermissions():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Set" Noun="WmiDataFileSecurityPermissions" ConfirmImpact="Medium" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="ChangeSecurityPermissions">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'SecurityDescriptor'-->
            <Parameter ParameterName="SecurityDescriptor">
              <!--the underlying parameter type is Win32_SecurityDescriptor which corresponds to the PowerShell .NET type [System.Management.ManagementBaseObject]-->
              <Type PSType="System.Management.ManagementBaseObject" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'Option'-->
            <Parameter ParameterName="Option">
              <!--the underlying parameter type is uint32 which really is the enumeration [CIM_DataFile.Option] that is defined below in the Enums node:-->
              <Type PSType="CIM_DataFile.Option" />
              <CmdletParameterMetadata Position="1" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Set-DataFileSecurityPermissionsEx: invoking method ChangeSecurityPermissionsEx():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Set" Noun="WmiDataFileSecurityPermissionsEx" ConfirmImpact="Medium" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="ChangeSecurityPermissionsEx">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'SecurityDescriptor'-->
            <Parameter ParameterName="SecurityDescriptor">
              <!--the underlying parameter type is Win32_SecurityDescriptor which corresponds to the PowerShell .NET type [System.Management.ManagementBaseObject]-->
              <Type PSType="System.Management.ManagementBaseObject" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'Option'-->
            <Parameter ParameterName="Option">
              <!--the underlying parameter type is uint32 which really is the enumeration [CIM_DataFile.Option] that is defined below in the Enums node:-->
              <Type PSType="CIM_DataFile.Option" />
              <CmdletParameterMetadata Position="1" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'StartFileName'-->
            <Parameter ParameterName="StartFileName">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="2" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'StopFileName'-->
            <Parameter ParameterName="StopFileName">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="3" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Add-DataFileCompression: invoking method Compress():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Add" Noun="WmiDataFileCompression" ConfirmImpact="Low" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="Compress">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
        </Method>
      </Cmdlet>
      <!--Add-DataFileCompressionEx: invoking method CompressEx():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Add" Noun="WmiDataFileCompressionEx" ConfirmImpact="Low" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="CompressEx">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'StartFilename'-->
            <Parameter ParameterName="StartFilename">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'Recursive'-->
            <Parameter ParameterName="Recursive">
              <!--the underlying parameter type is bool which corresponds to the PowerShell .NET type [bool]-->
              <Type PSType="bool" />
              <CmdletParameterMetadata Position="1" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--Method returns an instance of string in property StopFileName-->
            <Parameter ParameterName="StopFileName">
              <Type PSType="Microsoft.Management.Infrastructure.CimInstance[]" />
              <CmdletOutputMetadata />
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Copy-DataFile: invoking method Copy():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Copy" Noun="WmiDataFile" ConfirmImpact="Low" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="Copy">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'FileName'-->
            <Parameter ParameterName="FileName">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Copy-DataFileEx: invoking method CopyEx():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Copy" Noun="WmiDataFileEx" ConfirmImpact="Low" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="CopyEx">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'FileName'-->
            <Parameter ParameterName="FileName">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'StartFileName'-->
            <Parameter ParameterName="StartFileName">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="1" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'Recursive'-->
            <Parameter ParameterName="Recursive">
              <!--the underlying parameter type is bool which corresponds to the PowerShell .NET type [bool]-->
              <Type PSType="bool" />
              <CmdletParameterMetadata Position="2" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--Method returns an instance of string in property REF StopFileName-->
            <Parameter ParameterName="REF StopFileName">
              <Type PSType="Microsoft.Management.Infrastructure.CimInstance[]" />
              <CmdletOutputMetadata />
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Remove-DataFile: invoking method Delete():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Remove" Noun="WmiDataFile" ConfirmImpact="High" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="Delete">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
        </Method>
      </Cmdlet>
      <!--Remove-DataFileEx: invoking method DeleteEx():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Remove" Noun="WmiDataFileEx" ConfirmImpact="High" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="DeleteEx">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'StartFilename'-->
            <Parameter ParameterName="StartFilename">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--Method returns an instance of string in property REF StopFileName-->
            <Parameter ParameterName="REF StopFileName">
              <Type PSType="Microsoft.Management.Infrastructure.CimInstance[]" />
              <CmdletOutputMetadata />
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Get-DataFileEffectivePermission: invoking method GetEffectivePermission():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Get" Noun="WmiDataFileEffectivePermission" ConfirmImpact="Low" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="GetEffectivePermission">
          <ReturnValue>
            <Type PSType="bool" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'Permissions'-->
            <Parameter ParameterName="Permissions">
              <!--the underlying parameter type is uint32 which really is the enumeration [CIM_DataFile.Permissions] that is defined below in the Enums node:-->
              <Type PSType="CIM_DataFile.Permissions" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Rename-DataFile: invoking method Rename():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Rename" Noun="WmiDataFile" ConfirmImpact="Medium" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="Rename">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'FileName'-->
            <Parameter ParameterName="FileName">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Set-DataFileOwnership: invoking method TakeOwnerShip():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Set" Noun="WmiDataFileOwnership" ConfirmImpact="Medium" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="TakeOwnerShip">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
        </Method>
      </Cmdlet>
      <!--Set-DataFileOwnershipEx: invoking method TakeOwnerShipEx():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Set" Noun="WmiDataFileOwnershipEx" ConfirmImpact="Medium" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="TakeOwnerShipEx">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'StartFilename'-->
            <Parameter ParameterName="StartFilename">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'Recursive'-->
            <Parameter ParameterName="Recursive">
              <!--the underlying parameter type is bool which corresponds to the PowerShell .NET type [bool]-->
              <Type PSType="bool" />
              <CmdletParameterMetadata Position="1" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--Method returns an instance of string in property StopFileName-->
            <Parameter ParameterName="StopFileName">
              <Type PSType="Microsoft.Management.Infrastructure.CimInstance[]" />
              <CmdletOutputMetadata />
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
      <!--Remove-DataFileCompression: invoking method Uncompress():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Remove" Noun="WmiDataFileCompression" ConfirmImpact="Low" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="Uncompress">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
        </Method>
      </Cmdlet>
      <!--Remove-DataFileCompressionEx: invoking method UncompressEx():-->
      <Cmdlet>
        <!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
        <CmdletMetadata Verb="Remove" Noun="WmiDataFileCompressionEx" ConfirmImpact="Low" />
        <!--defining the WMI instance method used by this cmdlet:-->
        <Method MethodName="UncompressEx">
          <ReturnValue>
            <Type PSType="system.uint32" />
            <CmdletOutputMetadata>
              <ErrorCode />
            </CmdletOutputMetadata>
          </ReturnValue>
          <!--defining the parameters of this cmdlet:-->
          <Parameters>
            <!--native parameter name is 'StartFilename'-->
            <Parameter ParameterName="StartFilename">
              <!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
              <Type PSType="system.string" />
              <CmdletParameterMetadata Position="0" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--native parameter name is 'Recursive'-->
            <Parameter ParameterName="Recursive">
              <!--the underlying parameter type is bool which corresponds to the PowerShell .NET type [bool]-->
              <Type PSType="bool" />
              <CmdletParameterMetadata Position="1" IsMandatory="false">
                <ValidateNotNull />
                <ValidateNotNullOrEmpty />
              </CmdletParameterMetadata>
            </Parameter>
            <!--Method returns an instance of string in property StopFileName-->
            <Parameter ParameterName="StopFileName">
              <Type PSType="Microsoft.Management.Infrastructure.CimInstance[]" />
              <CmdletOutputMetadata />
            </Parameter>
          </Parameters>
        </Method>
      </Cmdlet>
    </InstanceCmdlets>
  </Class>
  <!--defining enumerations-->
  <Enums>
    <Enum EnumName="CIM_DataFile.AccessMask" UnderlyingType="system.uint32" BitwiseFlags="true">
      <Value Name="READDATALISTDIRECTORY" Value="1" />
      <Value Name="WRITEDATAADDFILE" Value="2" />
      <Value Name="APPENDDATAADDSUBDIR" Value="4" />
      <Value Name="READEA" Value="8" />
      <Value Name="WRITEEA" Value="16" />
      <Value Name="EXECUTETRAVERSE" Value="32" />
      <Value Name="DELETECHILD" Value="64" />
      <Value Name="READATTRIBUTES" Value="128" />
      <Value Name="WRITEATTRIBUTES" Value="256" />
      <Value Name="UNKNOWN512" Value="512" />
      <Value Name="UNKNOWN1024" Value="1024" />
      <Value Name="UNKNOWN2048" Value="2048" />
      <Value Name="UNKNOWN4196" Value="4096" />
      <Value Name="UNKNOWN8192" Value="8192" />
      <Value Name="UNKNOWN16384" Value="16384" />
      <Value Name="UNKNOWN32768" Value="32768" />
      <Value Name="DELETE" Value="65536" />
      <Value Name="READCONTROL" Value="131072" />
      <Value Name="WRITEDAC" Value="262144" />
      <Value Name="WRITEOWNER" Value="524288" />
      <Value Name="SYNCHRONIZE" Value="1048576" />
      <Value Name="UNKNOWN2097152" Value="2097152" />
      <Value Name="UNKNOWN4194304" Value="4194304" />
      <Value Name="UNKNOWN8388608" Value="8388608" />
    </Enum>
    <Enum EnumName="CIM_DataFile.Option" UnderlyingType="system.uint32" BitwiseFlags="true">
      <Value Name="CHANGEOWNERSECURITYINFORMATION" Value="1" />
      <Value Name="CHANGEGROUPSECURITYINFORMATION" Value="2" />
      <Value Name="CHANGEDACLSECURITYINFORMATION" Value="4" />
      <Value Name="CHANGESACLSECURITYINFORMATION" Value="8" />
    </Enum>
    <Enum EnumName="CIM_DataFile.Permissions" UnderlyingType="system.uint32" BitwiseFlags="true">
      <Value Name="READDATALISTDIRECTORY" Value="1" />
      <Value Name="WRITEDATAADDFILE" Value="2" />
      <Value Name="APPENDDATAADDSUBDIR" Value="4" />
      <Value Name="READEA" Value="8" />
      <Value Name="WRITEEA" Value="16" />
      <Value Name="EXECUTETRAVERSE" Value="32" />
      <Value Name="DELETECHILD" Value="64" />
      <Value Name="READATTRIBUTES" Value="128" />
      <Value Name="WRITEATTRIBUTES" Value="256" />
      <Value Name="UNKNOWN512" Value="512" />
      <Value Name="UNKNOWN1024" Value="1024" />
      <Value Name="UNKNOWN2048" Value="2048" />
      <Value Name="UNKNOWN4196" Value="4096" />
      <Value Name="UNKNOWN8192" Value="8192" />
      <Value Name="UNKNOWN16384" Value="16384" />
      <Value Name="UNKNOWN32768" Value="32768" />
      <Value Name="DELETE" Value="65536" />
      <Value Name="READCONTROL" Value="131072" />
      <Value Name="WRITEDAC" Value="262144" />
      <Value Name="WRITEOWNER" Value="524288" />
      <Value Name="SYNCHRONIZE" Value="1048576" />
      <Value Name="UNKNOWN2097152" Value="2097152" />
      <Value Name="UNKNOWN4194304" Value="4194304" />
      <Value Name="UNKNOWN8388608" Value="8388608" />
    </Enum>
  </Enums>
</PowerShellMetadata>
'@ | Set-Content -LiteralPath $cdxmlPath -Encoding UTF8

# import module
Import-Module -Name $cdxmlPath -Force -Verbose

# list new cmdlets
Get-Command -Module "CIM_DataFile"

Type Extensions for PowerShell

You can automatically improve properties of class instances by using a types.ps1xml file.

Create CIM_DataFile.Types.ps1xml
$folder = "c:\wmi\CIM_DataFile"
$typesPath = Join-Path -Path $folder -ChildPath "CIM_DataFile.Types.ps1xml"

# create folder if not present:
$exists = Test-Path -Path $folder
if (!$exists) { $null = New-Item -Path $folder -ItemType Directory }

# write file
$content = @'
<?xml version="1.0" encoding="utf-8"?>


<!--
This file is licensed under 'Attribution 4.0 International' license (https://creativecommons.org/licenses/by/4.0/).

You can free of charge use this code in commercial and non-commercial code, and you can freely modify and adjust the code 
as long as you give appropriate credit to the original author Dr. Tobias Weltner.

This material was published and is maintained here: 

https://powershell.one/wmi/root/cimv2/cim_datafile#typesps1xml-file
-->


<Types>
  <Type>
    <[email protected]

            Applicable type. This type is produced by Get-CimInstance. 
            To extend instances produced by Get-WmiObject, change the type name to: 

            System.Management.ManagementObject#root/cimv2\CIM_DataFile

        @-->
    <Name>Microsoft.Management.Infrastructure.CimInstance#Root/CIMV2/CIM_DataFile</Name>
    <Members>
      <ScriptProperty>
        <Name>AccessMask</Name>
        <!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
        <GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.CIM_DataFile.AccessMask]($this.PSBase.CimInstanceProperties['AccessMask'].Value)</GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>FileSize</Name>
        <!--overwriting ToString() method to provide formatted output while leaving the original property value untouched:-->
        <GetScriptBlock>($this.PSBase.CimInstanceProperties['FileSize'].Value) | Add-Member -MemberType ScriptMethod -Name ToString -Force -Value { "{0:n2} MB" -f ($this/1MB) } -PassThru</GetScriptBlock>
      </ScriptProperty>
    </Members>
  </Type>
</Types>
'@ | Set-Content -LiteralPath $typesPath -Encoding UTF8

# import type definition
Update-TypeData -PrependPath $typesPath

Note: CIM_DataFile.Types.ps1xml is using enumerations defined in ClassName.cdxml which are available only when you imported the .cdxml file via Import-Module.

Or, you can manually update the PowerShell type database using Update-TypeData.

View Update-TypeData commands for CIM_DataFile properties
Update-TypeData -MemberName AccessMask -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/cim_datafile" -MemberType ScriptProperty  -Value {
  [Flags()] Enum EnumAccessMask
  {
    READDATA_LISTDIRECTORY   = 1
    WRITEDATA_ADDFILE        = 2
    APPENDDATA_ADDSUBDIR     = 4
    READEA                   = 8
    WRITEEA                  = 16
    EXECUTE_TRAVERSE         = 32
    DELETECHILD              = 64
    READATTRIBUTES           = 128
    WRITEATTRIBUTES          = 256
    UNKNOWN512               = 512
    UNKNOWN1024              = 1024
    UNKNOWN2048              = 2048
    UNKNOWN4196              = 4096
    UNKNOWN8192              = 8192
    UNKNOWN16384             = 16384
    UNKNOWN32768             = 32768
    DELETE                   = 65536
    READCONTROL              = 131072
    WRITEDAC                 = 262144
    WRITEOWNER               = 524288
    SYNCHRONIZE              = 1048576
    UNKNOWN2097152           = 2097152
    UNKNOWN4194304           = 4194304
    UNKNOWN8388608           = 8388608
  }

  [EnumAccessMask]($this.PSBase.CimInstanceProperties['AccessMask'].Value)
} -Force

Update-TypeData -MemberName FileSize -TypeName 'Microsoft.Management.Infrastructure.CimInstance#root/cimv2/cim_datafile' -MemberType ScriptProperty -Value { ($this.PSBase.CimInstanceProperties['FileSize'].Value) | Add-Member -MemberType ScriptMethod -Name ToString -Force -Value { "{0:n2} MB" -f ($this/1MB) } -PassThru } -Force

Note: CIM_DataFile.Types.ps1xml is using enumerations defined in ClassName.cdxml which are available only when you imported the .cdxml file via Import-Module.

Requirements

To use CIM_DataFile, the following requirements apply:

PowerShell

Get-CimInstance was introduced with PowerShell Version 3.0, which in turn was introduced on clients with Windows 8 and on servers with Windows Server 2012.

If necessary, update Windows PowerShell to Windows PowerShell 5.1, or install PowerShell 7 side-by-side.

Operating System

CIM_DataFile was introduced on clients with Windows Vista and on servers with Windows Server 2008.

Namespace

CIM_DataFile lives in the namespace root/cimv2. This is the default namespace. There is no need to use the -Namespace parameter in Get-CimInstance.

Implementation

CIM_DataFile is implemented in CIMWin32.dll and defined in CIMWin32.mof. Both files are located in the folder C:\Windows\system32\wbem:

explorer $env:windir\system32\wbem
notepad $env:windir\system32\wbem\CIMWin32.mof