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.
Related Information
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
<!--@
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