Getting original object after piping via Out-GridView - powershell

I need to show a list of file names without paths and open the selected file.
I can get it to work with full paths:
Get-ChildItem *.txt -Recurse | Sort-Object Name| Out-GridView -PassThru | Invoke-Item
But when I try to show only the file names it fails:
Get-ChildItem *.txt -Recurse | Sort-Object Name| Select-Object Name | Out-GridView -PassThru | Invoke-Item
By piping it through Get-Member I understand that Select-Object Name striped all non-Name properties. So how can I trace the original file object from what I got from GridView?

You might want to use the DefaultDisplayPropertySet property of the hidden PSStandardMembers set for this:
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]#('Name'))
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]#($defaultDisplayPropertySet)
Get-ChildItem *.txt -Recurse | Select-Object * |
ForEach-Object {
$_ | Add-Member MemberSet PSStandardMembers $PSStandardMembers; $_
} | Out-Gridview -PassThru | Select-Object FullName
Get-ChildItem *.txt has a default display propery set of: LastWriteTime, Length, Name
Select-Object * strips off the complete property set (displays all properties)
Add-Member MemberSet PSStandardMembers $PSStandardMembers adds a new display set with just the Name property and keeps the rest of the properties hidden
Select-Object FullName reveals the hidden FullName property

The problem is, that the Invoke-Item needs the path and not only the filename.
You could store the get-childitem in a temporary variable:
$tmp = Get-ChildItem *.txt -Recurse | Sort-Object Name
$tmp | Select-Object Name | Out-GridView -PassThru
$tmp | Invoke-Item
Is that what you wanted? Please let me know if it worked, and if it did please mark my post as the answer. :)

Related

Extract Path from FullName property into results

I have this script:
Get-ChildItem -Path R:\MyFolder\archive -Recurse |
>> Sort-Object -Property LastAccessTime |
>> Select-object -Property Name, FullName
Rather than FullName I'd like the Path without the files name so I tried to adapt as follows:
Get-ChildItem -Path R:\MyFolder\archive -Recurse |
>> Sort-Object -Property LastAccessTime |
>> Select-object -Property Name, [System.IO.Path]::GetDirectoryName(fullname)
I'm obviously very new to PS - is it clear what I am attempting, and failing, to do?
Generally, Get-ChildItem cmdlet returns objects of different type:
System.IO.FileInfo
System.IO.DirectoryInfo
Unfortunately, on the latter you do not find property called DirectoryName. You can use Get-ChildItem -File (the -File parameter eliminates such objects), or use calculated property as follows:
$rootPath = 'R:\MyFolder\archive'
Get-ChildItem -Path $rootPath -Recurse |
Sort-Object -Property LastAccessTime |
Select-Object -Property Name,
#{ Name = 'DirectoryName';
Expression = { $_.FullName | Split-Path }}
For explanation, read in Select-Object => Parameters:
-Property
Specifies the properties to select. These properties are added as
NoteProperty members to the output objects. Wildcards are permitted.
The value of the Property parameter can be a new calculated
property. To create a calculated property, use a hash table.
Valid keys are:
Name (or Label):
Expression or
How about :
Get-ChildItem -Path 'R:\MyFolder\archive' -Recurse | Sort-Object -Property LastAccessTime | Select-object -Property Name, DirectoryName
?

Query File Version using powershell

I have a code that let me query one file version at the time.How can I query all file version inside of this registry key or if I just want to query specific files including firefox, chrome, etc.?
(Get-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\App Paths\communicator.exe').'(Default)' | ForEach-Object {
Get-ChildItem -Path $_ | Select-Object -ExpandProperty VersionInfo | Select FileDescription,ProductVersion
} | Format-Table -AutoSize
Instead of providing a literal path you should run Get-ChildItem on the "folder" the registry keys are contained in you are interested in. The result of this you pipe to your piece of code ... like this:
$Path = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\App Paths'
Get-ChildItem -Path $Path |
ForEach-Object {
Get-ItemProperty -Path $_.PSPath |
Select-Object -ExpandProperty '(default)' -ErrorAction SilentlyContinue |
ForEach-Object {
Get-Item -Path $_ -ErrorAction SilentlyContinue |
Select-Object FullName -ExpandProperty VersionInfo
}
} |
Format-Table -AutoSize

Remove-Item cmdlet causes "Cannot find path" while process of removal of .exe files in local folder

I have script that selects .exe files with the specified name from the local folder and removes all files, except first.
$P variable is defined in param.
$P ="$($env:USERPROFILE)\Desktop\I"
Then I got this error
$C = Get-ChildItem $P -Filter *.exe| Where-Object Name -Like '*r_2-2*' | Sort-Object Name -Descending | Select-Object -ExpandProperty Name -Skip 1 | Remove-Item
Remove-Item : Cannot find path 'D:\FM\r_2-2.exe' because it does not exist.
At line:1 char:251
+ ... Descending | Select-Object -ExpandProperty Name -Skip 1 | Remove-Item
I know about foreach loop but want to use For-EachObject cmdlet instead.
You were quite close, if you want to use ForEach-Object:
Get-ChildItem $P -Filter *.exe | Where-Object Name -Like '*r_2-2*' | Select-Object -Skip 1 | ForEach-Object { remove-item $_.FullName -force }
To skip one first found result just Select-Object -Skip 1 is enough.
Remove-Item -Force also removes hidden and read-only files.
You can make the use of FullName parameter directly in your statement. Try this -
$C = Get-ChildItem $P -Filter *.exe| Where-Object Name -Like '*r_2-2*' | Sort-Object Name -Descending | Select-Object -ExpandProperty FullName -Skip 1
$c | ForEach-Object {Remove-Item -Path $_}
Use -Force parameter if you want to delete the hidden files too.

Retain values from some pipes for final output

How do you do something like
PS> A | B | C | Format-Table PropertyFromA, PropertyFromB, PropertyFromC
So for example
gci -r -i *.txt | Get-Content | where {$_.Contains("SomeText")} | FormatTable -Property {$_.Directory, $.Name}
In this case gci output will have properties of Directory, Name but these will be lost when I pipe through Get-Content. How do I store this and make use later when piped to Format-Table. Can all this be achieved nicely in a single pipe chain command?
A small modification to your command will work:
gci -r -i *.txt | ? { (gc $_.FullName) -Match "SomeText" } | FormatTable Directory,Name
Arco444 has the right answer for this situation. On the off chance you are not showing us the real reason you are asking this question, or if others make their way here, I am going to show two examples that address this question as well.
Get-ChildItem -Recurse -filter *.txt | ForEach-Object{
$_ | Add-Member -MemberType NoteProperty -Name FileData -Value (Get-Content $_.FullName) -PassThru
} | Where-Object{($_.Filedata).Contains("SomeText")} |
Format-Table name,directory
Get-ChildItem -Recurse -filter *.txt |
Select Name,Directory,#{Label="FileData";Expression={Get-Content $_.FullName}} |
Where-Object{($_.Filedata).Contains("SomeText")} |
Format-Table name,directory
These "oneliners" are both examples that add a property to the objects created by Get-ChildItem. The new property FileData is then what you filter on. This logic can be applied in other ways as well.

Powershell won't output folder path?

When I filter some folders and output to a html file, the path in the result is always empty.
I can't find why it only works on files but folders?
Get-ChildItem -Recurse $source -Filter *PML_*_ECR* | where { $_.psiscontainer } | Where{$_.LastWriteTime -gt (Get-Date).AddDays(-6)} | sort LastWriteTime -descending | select name,LastWriteTime,Directory | convertto-html -head $a -body "<H2>Folder LIST FOR PAST 7 DAYS </H2>" | out-file $output\results.htm
Folders are represented as DirectoryInfo objects, which don't have a Directory property. The full path of the folder object itself is provided via the FullName property:
... | select Name, LastWriteTime, FullName | ...
The path of the parent folder can be obtained via the Parent property:
... | select Name, LastWriteTime, #{n='Directory';e={$_.Parent.FullName}} | ...
Because Directory is not a property of that object. Try doing:
Get-ChildItem -Recurse $source -Filter *PML_*_ECR* | where { $_.psiscontainer } ||GM
Then look at the available properties. I think FullName may better suite your needs.