Create .txt file inPowesShell containing Version number for all files in folder - powershell

Good afternoon,
Although I've been programming in VBA for 20 years, I'm on Week 2 with PowerShell, so please be patient!
I want to use a PowerShell script to create a txt file containing details for all .dll files greater than 15000 bytes within the specfied folder thus:
$MySourceFolderName = "C:\PetesStuff\01 Backup"
$MyOutputFile = "C:\PSOutputA.txt"
get-childitem $MySourceFolderName -recurse |where-object {$_.length -gt 15000} | where-object {$_.extension -eq ".dll"} |
sort-object -property Length -descending | Format-Table Name, Length -auto| Out-File -filepath $MyOutputFile
So far, this works, but I also want to include the File version, which can't be accessed in the same way that Name and Length can.
Can anyone help me out, please?
Thanks in advance
Pete

Ok, can do! What you want is Get-Command (I don't know why, but I do know it works). We can put it in a little impromptu hash table in the Format-Table command. Also, I'm going to move the second Where statement to a -filter so the provider filters that for you, and toss in some aliases because this is such a very long line.
GCI $MySourceFolderName -recurse -Filter "*.dll" | ?{$_.length -gt 15000} | sort -property Length -descending |
FT Name, Length, #{l="File Version";e={(Get-Command $_.FullName).FileVersionInfo.FileVersion}} -auto| Out-File -filepath $MyOutputFile

Related

Counting .csv files based on their first n number of characters

I need to write a script that checks the first 3 to say 5 characters of a .csv file, then count those files and report the characters with the corresponding count.
I already have a few methods to do the simpler tasks. I've used a filter before to only select certain .csvs, using this:
Get-ChildItem C:\path -Recurse -Filter *.csv | Where {$_.Name -match 'NNN'}
I also use this to count the number of csvs in that corresponding location:
(Get-ChildItem C:\path -Recurse -Filter *.csv | Measure-Object).Count
How can I run a scan through a folder with say 3 random titles for the csv? Say they're RUNxxxxxxxx.csv, FUNxxxxxxx.csv, and TUNxxxxxxx.csv.
Edit: Let me explain more; basically, the example csvs I have above would be completely random, so it'd need to recognize those first 3 are different and only count those.
I'm not sure if a prompt inputting these would do any. The values are known, just different week to week (which is when this would be run;every week)
Thanks!
You can accomplish that using the where-object filter combining three or statements which finds anything starting with the three letters you want and a wild card after.
Get-ChildItem C:\path -Recurse -Filter *.csv | Where {$_.Name -like "RUN*" -or $_.Name -like "Fun*" -or $_.Name -like "TUN*"}
You could also use the get-childitem -filter to accomplish this instead of searching for all .csv files and then use where-object.
Get-ChildItem C:\path -Recurse -Include "fUN*.csv","RUN*.csv","Tun*.csv"
How about using a calculated property to add the desired part as additional property to be able to work with it?
$PatternList =
'run',
'fun',
'tun'
Get-ChildItem -Recurse -Filter *.csv |
Select-Object -Property #{Name = 'Part'; Expression={($_.Name).substring(0,3)}},* |
Where-Object -Property Part -In -Value $PatternList |
Group-Object -Property Part

Power shell how to get list of N biggest files of type text

PowerShell how to get list of N biggest files of type text ?
my goal is exactly to
select all files that have an age over 30 days (whatever extension
is)
but ignoring any form of binary file
sort & display the top ten biggest text/ascii files.
I spend a bunch of time for doing tries all day long yesterday around things like
gci -r|sort -descending -property length | select -first 10 name, length
get-childItem .....
-filter and so on but no success but I a m new to powershell so ..
Testing if a file is textual of binary is extremely hard to do, but in Windows you can use the file extensions to filter out what you don't want in the result.
$refDate = (Get-Date).AddDays(-30).Date
# fill the list of binary filetypes that are most likely found
$binaries = '*.exe', '*.bin', '*.png', '*.gif', '*.jpg', '*.dll' # etcetera
Get-ChildItem -File -Recurse -Exclude $binaries |
Where-Object {$_.LastWriteTime -lt $refDate} |
Sort-Object Length -Descending |
Select-Object -First 10 |
Select-Object Name, Length # I would use FullName as you are using recursion..
Of course, you will have to add binary files that pop up in the output to th list in $binaries because I have just put a few examples in there now.

Powershell -- Get-ChildItem Directory full path and lastaccesstime

I am attempting to output full directory path and lastaccesstime in one line.
Needed --
R:\Directory1\Directory2\Directory3, March 10, 1015
What I am getting --
R:\Directory1\Directory2\Directory3
March 10, 1015
Here is my code, It isn't that complicated, but it is beyond me.
Get-ChildItem -Path "R:\" -Directory | foreach-object -process{$_.FullName, $_.LastAccessTime} | Where{ $_.LastAccessTime -lt [datetime]::Today.AddYears(-2) } | Out-File c:\temp\test.csv
I have used foreach-object in the past in order to ensure I do not truncate the excessively long directory names and paths, but never used it when pulling two properties. I would like the information to be on all one line, but haven't been successful. Thanks in advance for the assist.
I recommend filtering (Where-Object) before selecting the properties you want. Also I think you want to replace ForEach-Object with Select-Object, and lastly I think you want Export-Csv rather than Out-File. Example:
Get-ChildItem -Path "R:\" -Directory |
Where-Object { $_.LastAccessTime -lt [DateTime]::Today.AddYears(-2) } |
Select-Object FullName,LastAccessTime |
Export-Csv C:\temp\test.csv -NoTypeInformation
We can get your output on one line pretty easily, but to make it easy to read we may have to split your script out to multiple lines. I'd recommend saving the script below as a ".ps1" which would allow you to right click and select "run with powershell" to make it easier in the future. This script could be modified to play around with more inputs and variables in order to make it more modular and work in more situations, but for now we'll work with the constants you provided.
$dirs = Get-ChildItem -Path "R:\" -Directory
We'll keep the first line you made, since that is solid and there's nothing to change.
$arr = $dirs | Select-Object {$_.FullName, $_.LastAccessTime} | Where-Object{ $_.LastAccessTime -lt [datetime]::Today.AddYears(-2) }
For the second line, we'll use "Select-Object" instead. In my opinion, it's a lot easier to create an array this way. We'll want to deal with the answers as an array since it'll be easiest to post the key,value pairs next to each other this way. I've expanded your "Where" to "Where-Object" since it's best practice to use the full cmdlet name instead of the alias.
Lastly, we'll want to convert our "$arr" object to csv before putting in the temp out-file.
ConvertTo-CSV $arr | Out-File "C:\Temp\test.csv"
Putting it all together, your final script will look like this:
$dirs = Get-ChildItem -Path "C:\git" -Directory
$arr = $dirs | Select-Object {$_.FullName, $_.LastAccessTime} | Where{ $_.LastAccessTime -lt [datetime]::Today.AddYears(-2) }
ConvertTo-CSV $arr | Out-File "C:\Temp\test.csv"
Again, you can take this further by creating a function, binding it to a cmdlet, and creating parameters for your path, output file, and all that fun stuff.
Let me know if this helps!

PowerShell find most recent file

I'm new to powershell and scripting in general. Doing lots of reading and testing and this is my first post.
Here is what I am trying to do. I have a folder that contains sub-folders for each report that runs daily. A new sub-folder is created each day.
The file names in the sub-folders are the same with only the date changing.
I want to get a specific file from yesterday's folder.
Here is what I have so far:
Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | where(get-date).AddDays(-1)
Both parts (before and after pipe) work. But when I combine them it fails.
What am I doing wrong?
What am I doing wrong?
0,1,2,3,4,5 | Where { $_ -gt 3 }
this will compare the incoming number from the pipeline ($_) with 3 and allow things that are greater than 3 to get past it - whenever the $_ -gt 3 test evaluates to $True.
0,1,2,3,4,5 | where { $_ }
this has nothing to compare against - in this case, it casts the value to boolean - 'truthy' or 'falsey' and will allow everything 'truthy' to get through. 0 is dropped, the rest are allowed.
Get-ChildItem | where Name -eq 'test.txt'
without the {} is a syntax where it expects Name is a property of the thing coming through the pipeline (in this case file names) and compares those against 'test.txt' and only allows file objects with that name to go through.
Get-ChildItem | where Length
In this case, the property it's looking for is Length (the file size) and there is no comparison given, so it's back to doing the "casting to true/false" thing from earlier. This will only show files with some content (non-0 length), and will drop 0 size files, for example.
ok, that brings me to your code:
Get-ChildItem | where(get-date).AddDays(-1)
With no {} and only one thing given to Where, it's expecting the parameter to be a property name, and is casting the value of that property to true/false to decide what to do. This is saying "filter where *the things in the pipeline have a property named ("09/08/2016 14:12:06" (yesterday's date with current time)) and the value of that property is 'truthy'". No files have a property called (yesterday's date), so that question reads $null for every file, and Where drops everything from the pipeline.
You can do as Jimbo answers, and filter comparing the file's write time against yesterday's date. But if you know the files and folders are named in date order, you can save -recursing through the entire folder tree and looking at everything, because you know what yesterday's file will be called.
Although you didn't say, you could do approaches either like
$yesterday = (Get-Date).AddDays(-1).ToString('MM-dd-yyyy')
Get-ChildItem "d:\receive\bhm\$yesterday\MBVOutputQueriesReport_C12_Custom.html"
# (or whatever date pattern gets you directly to that file)
or
Get-ChildItem | sort -Property CreationTime -Descending | Select -Skip 1 -First 1
to get the 'last but one' thing, ordered by reverse created date.
Read output from get-date | Get-Member -MemberType Property and then apply Where-Object docs:
Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | `
Where-Object {$_.LastWriteTime.Date -eq (get-date).AddDays(-1).Date}
Try:
where {$_.lastwritetime.Day -eq ((get-date).AddDays(-1)).Day}
You could pipe the results to the Sort command, and pipe that to Select to just get the first result.
Get-ChildItem -filter “MBVOutputQueriesReport_C12_Custom.html” -recurse -path D:\BHM\Receive\ | Sort LastWriteTime -Descending | Select -First 1
Can do something like this.
$time = (get-date).AddDays(-1).Day
Get-ChildItem -Filter "MBVOutputQueriesReport_C12_Custom.html" -Recurse -Path D:\BHM\Receive\ | Where-Object { $_.LastWriteTime.Day -eq $time }

PowerShell script file modify time>10h and return a value if nothing is found

I am trying to compose a script/one liner, which will find files which have been modified over 10 hours ago in a specific folder and if there are no files I need it to print some value or string.
Get-ChildItem -Path C:\blaa\*.* | where {$_.Lastwritetime -lt (date).addhours(-10)}) | Format-table Name,LastWriteTime -HideTableHeaders"
With that one liner I am getting the wanted result when there are files with
modify time over 10 hours, but I also need it to print value/string if there are
no results, so that I can monitor it properly.
The reason for this is to utilize the script/one liner for monitoring purposes.
Those cmdlet Get-ChildItem and where clause you have a would return null if nothing was found. You would have to account for that separately. I would also caution the use of Format-Table for output unless you are just using it for screen reading. If you wanted a "one-liner" you would could this. All PowerShell code can be a one liner if you want it to be.
$results = Get-ChildItem -Path C:\blaa\*.* | where {$_.Lastwritetime -lt (date).addhours(-10)} | Select Name,LastWriteTime; if($results){$results}else{"No files found matching criteria"}
You have an added bracket in your code, that might be a copy artifact, I had to remove. Coded properly would look like this
$results = Get-ChildItem -Path "C:\blaa\*.*" |
Where-Object {$_.Lastwritetime -lt (date).addhours(-10)} |
Select Name,LastWriteTime
if($results){
$results
}else{
"No files found matching criteria"
}