问题
Editor\'s note:
The gist of this question is:
* How do I add custom properties to objects output by Get-ChildItem
that contain derived path information, namely the parent folder path (as Folder
and name (as Foldername
)?
* How do I export the resulting objects to a CSV file?
Currently have a script running that I took from StackOverflow and modified for my own use. The purpose of the script is to look at a directory, grab file names, then export them to a directory as a .csv file.
I was able to modify the script to pull through just the file name as originally it only pulled through the path, user
etc. Was able to do this by adding ,Name
. For some reason I can\'t get the script to pull through the parent folder it\'s in, also wanting the parents parent folder.
I believe this part of the code is what I am having most trouble with. Upon the select
I was able to add ,Name
but adding ,folder
or ,foldername
after the select
doesn\'t pull through properly.
ForEach-Object {$_ | Add-Member -Name \"Owner\" -MemberType NoteProperty -Value (Get-Acl $_.FullName).Owner -PassThru} |
Sort-Object fullname |
Select FullName,CreationTime,LastWriteTime,Owner,Name,Folder,Foldername
回答1:
The [System.IO.FileInfo]
instances returned by Get-ChildItem
for files do not have Folder
or FolderName
properties.
Get-ChildItem -File $HOME\Desktop | Get-Member
, for instance, will show you the available properties, and will show you that the desired information can be derived from the PSPath
and PSParentPath
properties.
Select-Object allows hashtable-based property definitions, so-called calculated properties, which allow you to rename and/or transform properties and/or add custom properties derived from other property values by way of a script block.
Note: You can also use calculated properties with the Format-Table
and Format-List
cmdlets for creating output for display only.
A simplified example of what you're looking for (includes output to a CSV file):
Get-ChildItem $HOME\Desktop | Select-Object Name,
@{ n = 'Folder'; e = { Convert-Path $_.PSParentPath } },
@{ n = 'Foldername'; e = { ($_.PSPath -split '\\')[-2] } } |
Export-Csv Out.csv -Encoding Utf8 -NoTypeInformation
Note that, alternatively, you could add Folder
and FolderName
properties to the input objects via Add-Member
, as you do with Owner
in your question.
Explanation:
Note that you can get more detailed information about any of the commands mentioned by running Get-Help <command-name> -Full
; add -online
to view the help topic in a browser; to learn more about the -split
operator, run Get-Help about_split
; to learn about PowerShell's help system in general, run Get-Help Get-Help -online
.
Each
@{ ... }
construct passed toSelect-Object
is a hash table that defines a property to attach to each output object:- The hash table must have two entries:
Name
orLabel
, which defines the property's name; for brevity, you may use a (case-insensitive) prefix of the key name, such as justn
orl
.Expression
, which defines the property's value; again, a (case-insensitive) prefix of the key name works too, such as juste
.- The expression can be a mere property name (a string), in case you simply want to rename an input property, but is more typically a script block (
{ ... }
), which is a piece of code that gets executed for each input object, and whose output becomes the value of the property being defined; inside that script block, automatic variable$_
(or$PSItem
) refers to the input object at hand.
- The expression can be a mere property name (a string), in case you simply want to rename an input property, but is more typically a script block (
- The hash table must have two entries:
Definition of
Folder
property:Convert-Path $_.PSParentPath
converts the fully qualified PowerShell path that thePSParentPath
property contains - which includes a prefix identifying the drive provider - to a regular filesystem path; e.g.,Microsoft.PowerShell.Core\FileSystem::C:\Users\jdoe\Desktop
->C:\Users\jdoe\Desktop
.Definition of
Foldername
property:($_.PSPath -split '\\')[-2]
splits the full path into components by path separator\
, and then accesses the next-to-last component (-2
), which is the parent folder name; e.g.,C:\Users\jdoe\Desktop\file.txt
->Desktop
'\\'
must be used to represent\
, because-split
's 1st RHS operand is a regular expression, where\
has special meaning and must therefore be doubled to be taken as a literal.- If you wanted to support
/
as the path separator as well for cross-platform support, you'd use($_.PSPath -split '[\\/]')[-2]
.
Export-Csv
exports the objects output bySelect-Object
to CSVOut.csv
, where the input objects' property names become the header row, and the property values the data rows.-Encoding Utf8
ensures that non-ASCII characters are properly encoded; by default,Export-Csv
uses ASCII encoding and simply discards non-ASCII characters, such as foreign letters.-NoTypeInformation
suppresses a line thatExport-Csv
by defaults adds as the first line of the output file, which contains the full type name (class name) of the input objects (e.g.,#TYPE System.Management.Automation.PSCustomObject
; this is meant to facilitate later reconversion into objects).
来源:https://stackoverflow.com/questions/39840883/create-objects-with-custom-properties-containing-derived-filesystem-path-informa