Files sorting with version number in Powershell - powershell

I have this folder in a directory. With different version on them.
CD1,CD2,CD3,CD4,CD5,CD6,CD7,CD8,CD9,CD11,CD12
I'm new to powershell, can anyone help me to get the latest version folder from the above folders? Here CD12 is the latest folder. I can't use last modified time because I copy them at the same time.
$FolderName=(Get-ChildItem C:\Current\CD |Where-Object {$_.name -like "*CD*"}| sort{$_.name.Substring(2,2)}|Select-Object Name -Last 1).Name)
Write-Host "$FolderName"
I tried the above script and it did not help. Can anyone help me?
The next new version is CD13, and the script should get that folder

You can try something like below
$max_version = Get-ChildItem "C:\Current\" | Where-Object {$_.PSIsContainer}
| Foreach-Object {$_.Name} | Foreach-object {$_ -replace "CD", ""}
| measure -maximum | Select-Object -expand Maximum
Write-host ("CD" + $max_version)
Which will result in CD12

You almost have it. When I tried to run your code, I ran into two errors. First, you have an extra ')' at the end of the line causing a syntax error. Second, your 'SubString()' call is failing because you're trying to get the 3rd and 4th characters of a string without a 4th character ("CD1"). You don't need the scriptblock to your Sort command, though. You can just sort on the Name field.
$FolderName = Get-ChildItem C:\7005\Hot-Fix\CD | where Name -like "CD*" | sort Name | Select-Object -Last 1 -ExpandProperty Name
As a side note, this uses the PowerShell 3 syntax for Where-Object and Sort-Object to omit the {}. And it uses the -ExpandProperty parameter to Select-Object, so you don't have to wrap the whole thing in parens to get the Name property.

You could try this:
#requires -v 3
$baseFolder='C:\7005\Hot-Fix\CD'
$folder=dir $baseFolder\CD* -Directory |
? basename -CMatch 'CD\d{1,}' |
sort #{e={'{0:0000}' -f [int]($_ -replace '\D')}} -Descending |
select -First 1
Notice, I'm considering case sensitive matching; also, $folder contains what you're looking for.

Related

Sorting by date PowerShell

I'm trying to find all files that include some string and are not older than "x" days. Those files have to be sorted and then sent in .txt format.
The code seemed fine to me, but it doesn´t filter files by date. All other cmdlets work as intended, but the part Where-Object {$_.LastWriteTime -ge (Get-Date).AddDays(-$days)} doesn´t seem to be working at all.
Do you have any recommendations how to fix it?
Get-ChildItem -Path $path -Recurse |
Where-Object {$_.LastWriteTime -ge (Get-Date).AddDays(-$days)} |
Select-String -Pattern $searched |
Group-Object -Property Path, Filename |
select Name |
Out-File -Filepath C:\tmp\output.txt
| Sort-Object -Property propertyName -Descending
cmdlet to sort by property value
reference link - https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/sort-object?view=powershell-6

Powershell Create CSV of files with "_lowRes.jpg" of a certain file size

I am trying to create a CSV file of all jpgs in a directory and its sub-directories that are above 100 KB and have the suffix "_lowRes.jpg".
Want to use Powershell.
Any help please?
This is pretty easy actually!
You'll do this with two separate filters, which PowerShell achieves via the Where-Object cmdlet. This cmdlet accepts comparisons in the format of {$_.PropertyName -eq "Something"} or PropertyName -eq "Something". The later format is only available on PowerShell v3 and up.
First, to filter to only files above 100KB.
Where-Object Length -ge 100KB
The second part, where the filename contains something.
Where-object Name -like "*lowRes.jpg*"
You could join them, but I would just pipe one into the other, like this.
dir *.jpg -Recurse | Where-Object Length -ge 100KB | Where-object Name -like "*lowRes.jpg*"
You might want to put the Name filtering first, because less files will have a certain name than be above or below a certain size. Depends on how your files are laid out.
Finally, pipe all of that into the Export-Csv cmdlet and bam, you're done!
you can do it simply like this :
Get-ChildItem "C:\temp" -Recurse -file -filter "*_lowRes.jpg" |
Where Length -ge 100KB | select fullname, Length |
export-csv "c:\temp\result.csv" -NoType
short version (for no purist) :
gci "C:\temp" -Rec -file -filter "*_lowRes.jpg" | ? L -le 100KB | select fu*, le* | epcsv "c:\temp\result.csv" -Not

Return the second level directory names only

I would like to retrieve all (and only) second level directory names of my disk. For example, C:\folder1\folder2 and C:\folder1\folder3, I need to retrieve only folder2 and folder3.
I write this and the PS displays all the directory names:
Get-ChildItem -Recurse | ?{ $_.PSIsContainer} | Select-Object Name
I found this help, and I modify the previous command in this way:
Get-ChildItem -Recurse | `Where-Object {($_.directory -match '^*\\\S*$')} ` | ForEach-Object {?{ $_.PSIsContainer} | Select-Object Name }
but when I use it the PS doesn't display anything.
I can't understand why, someone can help me? Thank you!
Only files appear to have a .directory property, directories do not, so you will never get something which passes your (.directory matches a pattern) filter and also passes your (PSIsContainer) filter.
Except that your PSIsContainer filter doesn't work:
| ForEach-Object {?{ $_.PSIsContainer} | Select-Object Name }
this doesn't make sense; you can only filter the pipeline using ? with cmdlet | ? {}, you cannot filter at the start of a loop scriptblock with no input and get anything useful. This is running where-object {} over and over in a loop, - and that has no output.
Using -Recurse will be very slow, as you go into every single directory all the way to the end, and make [fileinfo] objects for all the files as well.
Apart from Matt's wildcard answer, assuming PS v3 or above, you could list all the directories in the root, and then all the directories inside those, and stop there:
Get-ChildItem c:\ -Directory | Get-ChildItem -Directory | Select -ExpandProperty Name
or
gci c:\ -Dir | ForEach { (gci $_ -Dir).Name }
You should just be able to use some fun wildcards to get what you want here.
Get-ChildItem \*\*\ | Where-Object{$_.PSIsContainer}
Or if you have at least PowerShell 3.0 this would be faster
Get-ChildItem \*\*\ -Directory
Then if you wanted just the names tack on | Select-Object -ExpandProperty Name
Here with full path, network compatible:
(Get-ChildItem "\\folder1\" -Dir).fullname | ForEach {(Get-ChildItem $_ -Dir).name}
Want it stored in an array?
$subfolders = (Get-ChildItem "\\folder1\" -Dir).fullname | ForEach {(Get-ChildItem $_ -Dir).name}

Check file names and delete files with lower number in suffix

I have a following task on PowerShell:
I need to check files on remote machines:
For instance:
Get-ChildItem \\ServerName\data\
In this folder I have following files:
standard_file.0.tst
standard_file.1.tst
standard_file.2.tst
standard_file.3.tst
So, i need to delete files with lower number prefix (based on file name).
In the end, into the folder should be only one file with biggest prefix.
For instance:
standard_file.3.tst
I broke up my mind - and have no any ideas how to perform this.
Could you please push me to the right direction?
Thanks in advance.
You could use a regex to get the number and cast it to an int. Then sort the filenames by the number using the Sort-Object cmdlet so the file with the highest number will be the last. Then you select all objects using Select-Object and skip the last one and finally remove it using Remove-Item:
Get-ChildItem '\ServerName\data\' |
Sort-Object { [int][regex]::Match($_, '.*?(\d+)\.[^.]+$').Groups[1].Value } |
Select-Object -SkipLast 1 |
Remove-Item
Regex:
.*?(\d+)\.[^.]+$
This will gather all the files in the path that have numerical suffixes in their names. The way that is done is by using a regex to match all of the digits on the end of the basename. Sorting on the result of that match in descending order will put the wanted file on the top of the list. We then remove the remaining files by skipping that first result.
$path = "c:\temp"
Get-ChildItem $path | Where-Object{$_.BaseName -match "\.\d+$"} |
Sort-Object -Property {$_.BaseName -match "\.(\d+)$";[int]$Matches[1]} -Descending |
Select-Object -Skip 1 |
Remove-Item -Confirm:$false -WhatIf
Remove -WhatIf when you are sure that it will remove the files you want.

Parse and Switch Elements of Folder Names with Powershell 2.0

I have been trying to write a powershell script (my first) to
parse out only the folders within a directory
select only those folders matching a specific naming convention ('SEASON YEAR')
switch the order of the elements of the name ('YEAR SEASON')
I eventually used the program BulkRenameUtility to do this using the regexp ^(\w+) (\d+) and switching the token order to $2 $1 -- however, I still am learning Powershell and would like to be able to do this without using an external program.
So, to re-iterate, at C:\Users\Test
there are folders and files.. some of the folders are named Spring 2015, Fall 2014, for example. However, other folders have names such as geogex. Files have names such as ENG1A SPRING 2015.odtand untitled_0.odt.
How do I only change the names of the folders named like "Spring 2015" to read "2015 Spring", "2014 Fall" etc. ?
I was able to use
gci | ? {$_.PSIsContainer} | select-string -pattern '\d+'
to accomplish 1 and 2 but am stuck on using this to do part 3: actually rename by reversing the elements of the name. I tried putting the above within a variable and like so:
gci | ? {$_.PSIsContainer} | select-string -pattern '\d+' | %{$data = $_.line; Write-Output "$data"};
however, while the above outputs exactly the folders I want the array $data seems to only hold the last line of output. Such that:
gci | ? {$_.PSIsContainer} | select-string -pattern '\d+' | %{$data = $_.line; Write-Output "$data"};
$data
will output:
test 123
test 321
test 321
I am unsure if this is even the a valid direction to begin with.
Any help would be greatly appreciated.
This should get the job done.
$Path = "C:\Users\Test"
$regex = "^(Spring|Summer|Fall|Winter)\s+\d{4}$"
Get-ChildItem $Path |
Where-Object {$_.PSIsContainer -and $_.Name -match $regex} |
Rename-Item -NewName {$split = $_.Name -split "\s+"; "{0} {1}" -f $split[1],$split[0]}
We use that regex to filter out the folder that fit your convention. Should be a little more targeted using specific season names. The year is a little more lacked by just looking for 4 numbers.
Other ways to do it but for the rename I just split the name on the space and reversed the output using the -f format operator.