Get formatted output of file details in a folder - windows

I want to retrieve certain details about all files in a given folder.
Get-ItemPropertyValue .\*.dll -name versioninfo
Gives me output like this:
That aint bad but i wanna include some other properties, and the -include switch doesnt work like i thought.
And giving it -name versioninfo, lastwritetime for example, doesnt add another column to the list, it prints the date underneath:
How can i bring all read properties of one file into the same row (add column)?
EDIT:
i am aware of format-list but its not giving me the wide list output and format-wide only accepts one single property...

How about this?
Get-Item .\*.dll | Select-Object `
#{N='ProductVersion';E={Get-ItemPropertyValue $_ -Name versionInfo | Select-Object -ExpandProperty ProductVersion}} `
,#{N='FileVersion';E={Get-ItemPropertyValue $_ -Name versionInfo | Select-Object -ExpandProperty FileVersion}} `
,Name `
,LastWriteTime

I found an easier, more readable way to do this, and still generate the output when run inside a script:
Get-Childitem .\ThirdPartyComponents\*.dll | select name, lastwritetime, #{l="ProductVersion";e={$_.VersionInfo.ProductVersion}}, #{l="FileVersion";e={$_.VersionInfo.FileVersion}} | ft
The last pipe to | ft (Format table) is needed because the command does not generate any output when run inside a script otherwise. Why that is, im not exactly sure..

Related

find all VS-projects that compile to a .NET 3.5 console application

I have a deeply nested repository, with lots of Visual Studio projects. I need to find all projects, which have TargetFramework 3.5 and Output Type 'console application'.
I figured out that console applications have this in their csproj-file:
<OutputType>Exe</OutputType>
And applications with a window have this:
<OutputType>WinExe</OutputType>
This allows me find all files with extension csproj, which compile to a console application.
$csproj_ConsoleExes = gci -Recurse *.csproj | select-string "<OutputType>Exe</OutputType>"
What I need to do next: I need to filter only those projects with target-framework 3.5. But since $csproj_ConsoleExes contains search results I don't know how to apply select-string again.
select-string only work with input-objects of type FileInfo.
Any help is appreciated.
You can take advantage of Select-String's ability to accept multiple search patterns, which allows you to then use Group-Object to determine all those files where both patterns matched:
Get-ChildItem -Recurse -Filter *.csproj |
Select-String -SimpleMatch '<OutputType>Exe</OutputType>',
'<TargetFramework>net35</TargetFramework>' |
Group-Object Path |
Where-Object Count -eq 2 |
ForEach-Object Name
The above outputs the full paths of all *.csproj files in which both patterns were found.
Note:
This approach only works if, for each search pattern, at most one line per input file matches, which should be true for .csproj files.
See this answer for a solution for cases where this assumption cannot be made.
You can turn the items in $csproj_ConsoleExes to type FileInfo with this:
$csproj_Console_Items = $csproj_ConsoleExes| select Path | get-item
The above line first gets the path of every item and pipes it to get-item, which is then turned into a FileInfo-object.
Then you can find all lines containing TargetFrameworkVersion
$csproj_Console_TargetFrameworkVersion=$csproj_Console_Items | select-string "<TargetFrameworkVersion>"
Now you could again get the path and pipe it to get-item to get a new collection of type FileInfo.

How to get the name of a directory by regex?

I need to get the path or name of a directory, the things I know about it:
- the folder the directory is on
- its name follows a given regex
How can I accomplish this?
Working on Jenkins pipeline (groovy)
You can apply the pwd pipeline step to return the current directory as String and fetch the name from it by using regex groups.
See the following example to extract values from regex using groovy: https://gist.github.com/EwanDawson/2407215
I ended up assigning the result of powershell to the variable, I did this by telling the powershell step that it has a stdout return like:
def folder = powershell (returnStdout: true, script: """
Get-ChildItem -directory | Select-String -pattern '<pattern>'
""")
That combined with pwd() gives me the full path, although you can also get full path using a pipeline in the command, something like Get-ChildItem -directory | Select-Object Fullname | Select-String -pattern '<pattern>'

Powershell "LastWriteTime" not working

Is there a way to stop Powershell from sorting by default? I need to read in files from a directory and in the order which they are listed in the directory I need them to also be listed in the array (variable). Even when I use -lastwritetime on the get-childitem command, it seems to have no affect. The primary reason why I want to do this is because the files have names that are all the same except each file has a number after it like the following:
document1.doc
document2.doc
document3.doc
.....
document110.doc
The problem is if it's sorted by name, it will sort in this manner:
document1.doc
document10.doc
document111.doc
Which is horribly wrong!
Right now I have this command and it doesn't work:
$filesnames1 = get-childItem -name *.doc -Path c:\fileFolder\test | sort-object -LastWriteTime
You probably want something more along these lines.
$filesnames1 = Get-ChildItem -Path c:\fileFolder\test\*.doc |
Sort-Object -Property LastWriteTime
I don't think either of those two cmdlets have a -LastWriteTime parameter.
If you need only the names from those filesystem objects, you can use ($filesnames1).Name after the code above. There are other ways.
Thanks for responding Mike. What I did is put a "-filter *.pdf" just before -path which gave me the headers. Then I piped in a "select-object -ExpandProperty name" to list it exactly how I needed it to. It was a little trial and error but I did eventually figure it out.
$filesnames1 = Get-ChildItem -filter *.doc -Path c:\fileFolder\test |
Sort-Object -LastWriteTime | -ExpandProperty name

In PowerShell, how can I extract a file from HKEY_Users from all SIDs?

I am writing a PowerShell module to look for data that each user who has logged onto the computer at some point might have in their directory in HKEY_USERS. My initial thought was to mount HKEY_USERS, find a way to store each user's SID in a string variable, and then loop through all folders like so:
dir HKU\<STRING VARIABLE HOLDING SID>\Software\MyApp\Mydesireddata
Is there a way I can avoid having to loop through SIDs (because I won't know them ahead of time), and extract that file info from each SID on the system while remembering which SID it came from?
EDIT: Here is an example of the key I'm trying to extract from each user's SID using regedit (vncviewer's EulaAccepted)
Use Get-ChildItem to retrieve each user-specific subkey:
$UserHives = Get-ChildItem Registry::HKEY_USERS\ |Where-Object {$_.Name -match '^HKEY_USERS\\S-1-5-21-[\d\-]+$'}
Then loop over each entry and retrieve the desired registry value:
foreach($Hive in $UserHives)
{
# Construct path from base key
$Path = Join-Path $Hive.PSPath "SOFTWARE\MyApp\DataKey"
# Attempt to retrieve Item property
$Item = Get-ItemProperty -Path $Path -Name ValueName -ErrorAction SilentlyContinue
# Check if item property was there or not
if($Item)
{
$Item.ValueName
}
else
{
# doesn't exist
}
}
I tackled this issue a slightly different way; preferring to make use of a conspicuously placed wildcard.
Get-ItemProperty -Path Registry::HKEY_USERS\*\SOFTWARE\TestVNC\viewer\ -Name EulaAccepted |
Select-Object -Property #{n="SID";e={$_.PSPath.Split('::')[-1].Split('\')[1]}},EulaAccepted
The wildcard will automatically check all available paths and return what you need as well as the SID from the parent path.
As for the username (which is probably more useful than a SID), you didn't specifically ask for it, but I added it in for grins; this should cover local and domain accounts.
mind the line breaks
Get-ItemProperty -Path Registry::HKEY_USERS\*\SOFTWARE\TestVNC\viewer\ -Name EulaAccepted |
Select-Object -Property #{n="SID";e={$_.PSPath.Split('::')[-1].Split('\')[1]}},EulaAccepted |
Select-Object -Property #{n="User";e={[System.Security.Principal.SecurityIdentifier]::new($_.SID).`
Translate([System.Security.Principal.NTAccount]).Value}},SID,EulaAccepted
Getting the username is just ugly; there's likely a cleaner way to get it, but that's what I have in my head. The double-select really makes my skin crawl - there's something unpleasant about it. I could just do a one shot thing, but then it gets so unwieldly you don't even know what you're doing by looking at it.
I've included a screenshot of the registry below, and a screenshot of the screen output from running the few lines.

Index all files and folders under E:\data using batch file

I want to write a batch script which will make a CSV or JSON file containing all file and folders under E:\data. the informations I need to store are (file or folder name, size, type--file or folder, full location path).
Any help will be appreciated. Thank you.
PowerShell can do that with ease. Have to add a little subexpression to give friendly terms about if it is a folder or file. Otherwise we could get rid of the entire #{l=...} bit and just use PSIsContainer and it would be True/False to state if it is a folder or not.
Get-ChildItem E:\Data -recurse | Select Name,Length,#{l='Type';e={if($_.PSIsContainer){'Folder'}else{'File'}}},FullName | Export-CSV C:\Path\To\Output.csv -NoType
Or, if you want to find out folder sizes of folders (including files in the folder) you could run this:
| Select Name,#{l='Size';e={if($_.psiscontainer){$_.getfilesysteminfos()|measure -Sum -Property length|select -expand sum}else{$_.length}}},#{l='Type';e={if($_.PSIsContainer){'Folder'}else{'File'}}},FullName | Export-CSV C:\Path\To\Output.csv -NoType

Resources