Powershell : Quickly count containers - powershell

I think we all know the PsIsContainer method to check if the current file is a folder or not. But in my project I need a way to quickly know the number of folders in a folder. All I need is to quickly get their number. I want to write in a .txt lines which would look like C:\folder;12. It would mean in the folder, with the -recurse argument, there would be 12 folders.
To explain why, I need to save the progress of my work when i cut off the program which is used to analyse some folders. When a folder's analysed, the result is written in a second .txt. For example, if a folder is called C:\folder\folder1, folder will be analysed and then folder1 will be too. Which makes folder appear 2 times in the file because the full name always is written. What i want to do is to count the number of lines where C:\folder is written. If it equals the number next it's path in the first .txt, it means the file already has been analysed and the function doesnt need to do it again.
Does someone have a solution ? Or maybe an another idea to save the progress ? Cause i really have the feeling this is taking too long to do this.
Thank you for your help.

Another approach, which i find much faster is using cmd built-in 'dir' command
of course this is in case you don't need the subfolders(which you can then run the function in a foreach loop, or change the function if this is the case)
Function Get-FolderCount($path)
{
$Dir = cmd /c dir $path /a:d
Return ($Dir[-1] -csplit 'Dir' -replace '\s')[0]
}
I use this as well for measuring folder size with /s switch and take the total size which is much faster then powershell, also much faster then run it on interactive shell...

Related

Powershell: Rename a folder when only partial name is known

I need to rename a folder without knowing the full folder name.
For Example C:\myfolder-2021-5-1 (I know the first part of the folder name)
I would like to rename it to c:\myfolder... Again, the script wont always know the full folder name.
Edit: I am new to Powershell. I have spent a few hours looking on Google and I don't see examples of people trying to rename a folder using a wildcard. There are very few folder renaming examples that I could find. Most of what I find pertains to renaming files not folders.
I get it people wanting me to "try" first and then ask questions. But, sometimes, especially for us newbies, we don't even know where to start.
I tried using several filename examples and just using a directory name with a wildcard and that did not work.
Don't know what else to say.
Any ideas?
Thanks!
You cant rename a directory if you dont know it's name - thats just not how files and directories work. What you can do is search for a directory that matches your criteria, then you can rename it.
(I'm assuming the reason you dont know the exact name is because its a date, but im also assuming the format of the directory name is consistent)
At its most basic level, this would work for your example:
get-childitem -Path c:\ -Directory -Filter "myfolder-????-*-*" | Move-Item -Destination "renamed-myfolder"
This will search for directories in C:\ that match the pattern "myfolder-????-*-*" - so this pattern would match your example folder C:\myfolder-2021-5-1. Then pass that Directory down the pipeline (|) into Move-Item where the directory is renamed to c:\renamed-myfolder.
This code has some major drawbacks though! It doesnt check if the new name exists before trying to rename the directory so it might fail. Also if more than 1 folder matches the filter only the first rename (Move-Item) will succeed. Its upto you to think about these edge cases and add suitable logic to detect/prevent them.
Its a good idea to use Test-Path command to check if the destination name already exists or not:
if(Test-Path -Path c:\renamed-myfolder){
throw "ERROR - c:\renamed-myfolder already exists!";
}
NOTE: Get-ChildItem filters * means "any characters" and ? means "one character" so "myfolder-*-*-*" would also work, but if the year is always 4 digits then use the ???? as its more specific. Ive used the filter "myfolder-????-*-*" as im assuming some days/months will be 2 digits like myfolder-2021-12-12.

Compare 2 large folders

I know there are a lot of questions asked/answered related to this but my question has twists.
So I'm comparing 2 folders that has huge amount of data (over 20gb and can go up to 40gb) one of them being OneDrive.
I'm trying to compare and find the missing ones along with which ones are newer. I can accomplish either or but regardless which one I try because the folders are huge, it takes a long time and sometimes even crashes. On top of that, when you run the script, it tries to download the files on OneDrive (even tho they are present when you do Test-Path.
I found a post that does both (link below) but wondering if there is an easier way to accomplish this without downloading or putting it in a variable?
Thank you everyone in advance!
https://serverfault.com/questions/532065/how-do-i-diff-two-folders-in-windows-powershell/637776?newreg=b08ad3ef3c8e45d48ac0d17676a28df4
you can try with compare-object but you have to get all child items before like this:
$gci1 = Get-ChildItem -Recurse "Path to Folder"
$gci2 = Get-ChildItem -Recurse "Path to Folder"
Compare-Object $gci1 $gci2

Powershell IF ELSE based on File Size

Trying to find a way in powershell that allowed me to move a file based on its size. I could not find exactly what I was looking for. I found how to move files of only a certain size and to do other if/then statements but not to move a file to different locations based on there size.
Why did I need/want to do this? A exe I am running creates and output even if it has no data. so sometimes the file is empty and sometimes it has data. When it has data I need it sent to someone, when its empty I just wanted it in a backup folder for reference.
This part let me move a file based on size: -cle is less than or equal to
$BlankFiles = Get-ChildItem c:\test\*.rej | where { $_.Length -cle 0kb}
This part let me check if an empty file exist: After lots of reading went with system.io.file over test-path
[System.IO.File]::Exists($BlankFiles)
Putting this all in a IF/ELSE statement was the problem i struggled with. Answer I came up with is below.
I am mainly posting this since I could not find the exact scenario and if any one sees a problem with this approach that I missed.
Here is the solution I came up with and it all the test I did it appears to be working as intended. Note: I only need to do this on one file at a time, which is why this works and why I left out recursive or loop steps.
If the file is blank it moves it to a backup folder and appends it with the date, if it has data it makes a copy with the date append to the backup folder and moves the file with date append to a different location that is accessible to the necessary users.
I was thinking about going with check to see how many lines are in the file over the size of the file, but it appears the file when blank sometimes has a return in it and sometimes it doesn't. So I went with size method instead
$BlankFiles = Get-ChildItem c:\test\*.rej | where { $_.Length -cle 0kb}
$date = Get-Date
$fndate = $date.ToString("MMddyyyy")
If ([System.IO.File]::Exists($BlankFiles) -eq "True") {
Move-Item C:\test\*.rej c:\test\blankfiles -"$fndate".rej
}
Else {
Copy-Item c:\test\*.rej c:\test\realfiles-"$fndate".rej
Move-Item c:\test\*.rej c:\user\accessible\realfiles-"$fndate".rej -Force
}
If anyone see any issues with doing this way or has a better suggestions, but as I mentioned from my test it appears to be working wonderfully and I thought I would share.

Renaming files with unnecessary zeros in Powershell

I've been looking into batch renaming files with Powershell and I've made some good progress. To put it simply I'm looking to remove all extra zeros from the beginning of my files. So far I have a folder of images named as such:
0001_random_name.jpg
0002_random_name.jpg
0003_random_name.jpg
All the way up to 900~. I created a Powershell script that takes the first four characters and adds the .jpg extension back. Here is that script:
Get-ChildItem 'G:\InvaluableNumbered' | rename-item -newname { $_.name.substring(0,4) + ".jpg" }
This renames the files to
0001.jpg
0002.jpg
0003.jpg
For this project I need to name them
1.jpg
2.jpg
3.jpg
All the way up to 968.jpg. Is there any way I can use the script that I wrote and then have another command that removes all 0s up to where it hits the first number greater than zero?
Thank you for your time.
You can use TrimStart string method to achieve desired result:
$_.name.substring(0,4).TrimStart('0')
Other possibility could be cast value to [int] and then back to [string]:
[string][int]$_.name.substring(0,4)

preplog.exe ran in foreach log file

I have a folder with x amount of web log files and I need to prep them for bulk import to SQL
for that I have to run preplog.exe into each one of them.
I want to create a Power script to do this for me, the problem that I'm having is that preplog.exe has to be run in CMD and I need to enter the input path and the output path.
For Example:
D:>preplog c:\blah.log > out.log
I've been playing with Foreach but I haven't have any luck.
Any pointers will be much appreciated
I would guess...
Get-ChildItem "C:\Folder\MyLogFiles" | Foreach-Object { preplog $_.FullName | Out-File "preplog.log" -Append }
FYI it is good practice on this site to post your not working code so at least we have some context. Here I assume you're logging to the current directory into one file.
Additionally you've said you need to run in CMD but you've tagged PowerShell - it pays to be specific. I've assumed PowerShell because it's a LOT easier to script.
I've also had to assume that the folder contains ONLY your log files, otherwise you will need to include a Where statement to filter the items.
In short I've made a lot of assumptions that means this may not be an accurate answer, so keep all this in mind for your next question =)