Power shell to loop subfolders according to sequence - shell

I would like to use power shell to loop all subfolders and run all the files in it. But, if my root contain 3 subfolders, I would like to loop and list it accordingly to the sequence where : Subfolder C , Subfolder B and Subfolder A so that the file execution will run according to the sequence ( C-->B-->A) .
Below is my coding.
Get-ChildItem -path "C:\Root\subfolders\" -recurse -Filter *.sql | foreach-object -process { $_.FullName }|
ForEach-Object {
sqlcmd -i $_
}

Give this a try, get all folders of C:\Root\subfolders and foreach folder found get its files recursively :
Get-ChildItem C:\Root\subfolders |
Where-Object {$_.PSIsContainer} |
Foreach-Object {Get-ChildItem $_.FullName -Recurse -Filter *.sql | Foreach-Object {sqlcmd -i $_.FullName} }

Related

Recursively add an extension to a group of files in PowerShell Version. 4

I'm looking at how to add an extension recursively to an entire folder structure. This line does what I need, but only for the current folder. I need to do the same for the subfolders structure.
Get-ChildItem -File | % { mv ($_.BaseName+"") ($_.BaseName+".png") }
But I keep getting this error:
Cannot find path 'C:\Users\Jess...\' because it does not exist.
I used the search, however I only founded a solution for the Bash, not the PowerShell. So I couldn't get the -Recurse to work in the same way.
Get-ChildItem -File -Recurse | % { mv ($_.BaseName+"") ($_.BaseName+".png") }
Here's a way to get the full pathname. In powershell 6 this isn't an issue.
Get-ChildItem -File -Recurse | % { $_ | mv -destination ($_.Name + '.png' ) -whatif }
Or
Get-ChildItem -File -Recurse | ? { ! $_.extension } |
mv -destination { $_.Name + '.png' } -whatif

Powershell Get-ChildItem wildcard in path?

Can a wildcard be put in a folder name mask? Or is it necessary to run Get-ChildItem twice, one for the direcdtories and a second for the path? Even with the code below, I'm getting no directories returned.
I think this post shows how to do it with the older syntax:
$folderName = "c:\BizTalk\Vendors\*\AS2FilesReceived\"
$folderMask = "$folderName\*.*"
$dirs = Get-ChildItem -Path $folderName -Recurse -Directory
Write-Host "Number of Matching Directories = $($dirs.Count)"
$dirs
#$files = $dirs | %{ Get-ChildItem -Path $folderMask -Filter "*.*" -Exclude "*997*.*" -File} | Where-Object {$_.CreationTime -gt (Get-Date).AddDays(-6)} | Sort-Object LastWriteTime -Descending
Get-ChildItem supports wildcards in the path, but the wildcard applies only to a single folder level, i.e. a pattern C:\foo\*\bar will find folders C:\foo\abc\bar and C:\foo\xyz\bar, but won't find a folder C:\foo\abc\xyz\bar. For the latter you need something like this:
Get-ChildItem 'C:\foo' -Filter 'bar' -Directory -Recurse
If you have just a single variable folder level and want only files from the given path (without recursion) you can do something like this:
Get-ChildItem 'C:\foo\*\bar\*' -File
If you also want all files in subfolders below bar use this:
Get-ChildItem 'C:\foo\*\bar' -File -Recurse
Assuming that you want to find and return info about all files in all AS2FilesReceived directories for each folder under Vendors, then this might help you...
#Find all AS2FilesReceived directories
$dirs= Get-ChildItem -Path 'C:\BizTalk\Vendors\*\AS2FilesReceived\' -Directory
#Return number of directories
"$($dirs.Count) directories found"
#Return list of directory names
$dirs | % {$_.Parent.Name}
#Return the full name of every text file under each directory
$dirs | % {Get-ChildItem -Path $_ *.txt} | % {$_.FullName}
Which returns...
3 directories found
Vendor1
Vendor2
Vendor3
C:\BizTalk\Vendors\Vendor1\AS2FilesReceived\Vendor1AS2File.txt
C:\BizTalk\Vendors\Vendor2\AS2FilesReceived\Vendor2AS2File.txt
C:\BizTalk\Vendors\Vendor3\AS2FilesReceived\Vendor3AS2File.txt
Ultimately, I just wanted the files, not sure if I had a typo or what, but now this works. It's possible I swithced from $folderMask to $folderName, or didn't have the *.* on the end of the $folderMask.
$folderMask = "c:\BizTalk\Vendors\*\AS2FilesReceived\*.*"
$files = Get-ChildItem -Path $folderMask -File
Write-Host "Number of Matching Files = $($files.Count)"

List 2 folders using a single command

Assume I have 2 folders A and B
Folder A contains files like "food.txt", "drinks.txt", ...
Folder B contains files like "beverage.txt", "entre.txt",...
Is there a way using dir (gci) or any command to get an output like
"beverage.txt", "drinks.txt", "entre.txt", "food.txt",..
Just use:
Get-ChildItem -File -Recurse | Select-Object -ExpandProperty Name
-File will list only files
-Recurse will also get all folder under the given one
Select-Object -Expandproperty Name will give you only the filename
If the files are located somewhere completely different you can just give GCImultiple Paths:
Get-ChildItem -File -Path "PathToFolderA","PathToFolderB" | Select-Object -ExpandProperty Name
The pre PSv3 way to check for file/directory is to inspect the PSIsContainer property in a Where-Object
So this line will return:
PS A:\> Get-ChildItem -Path "Folder A","Folder B" |Where-object {!$_.PSIsContainer}| Select-Object -ExpandProperty Name
drinks.txt
food.txt
beverage.txt
entre.txt
Taking your question literal with double quotes and separated with ,
(Get-ChildItem -Path "Folder A","Folder B" |Where-object {!$_.PSIsContainer}|ForEach-Object { '"{0}"' -f $_.Name}) -join ', '
"drinks.txt", "food.txt", "beverage.txt", "entre.txt"
To have output sorted, just insert a |Sort-Object Name
(Get-ChildItem -Path "Folder A","Folder B" |sort Name|Where-object {!$_.PSIsContainer}|ForEach-Object { '"{0}"' -f $_.Name}) -join ', '
"beverage.txt", "drinks.txt", "entre.txt", "food.txt"

Recursively Rename Files In All Subfolders Sequentially

I have a series of folders and subfolders, structured in this way:
001/Fabric/Blue/ (.jpg files, sequentially named)
001/Fabric/Green/ (.jpg files, sequentially named)
002/Fabric/Blue/ (.jpg files, sequentially named)
002/Fabric/Green/ (.jpg files, sequentially named)
etc.
The file names have excess string characters that I would like to remove, and I would like to convert their file names into an easier sequential format (0.jpg, 1.jpg, etc.).
I tried working with a few different PowerShell examples to get this to work. I have the recursive searching functionality working, however I receive an error about an InvalidOperationException when trying to rename the files in the ForEach-Object loop. Additionally, I am afraid my sequential numbering is not being 'reset' for each of the folders where it renames files.
$i = 0
Get-ChildItem -Filter "*.jpg" -Recurse | ForEach-Object {
Rename-Item $_ -NewName ('$i.jpg' -f $i++)
}
So, two questions:
How can I fix the error with Rename-Item?
How can I ensure my variable is reset for each subfolder the script starts renaming files in?
If you take a two step approach, first getting all the folders containing jpg's and then iterating through this list, you have no problem beginning with 1. But I'd always use leading zeroes for such a renumbering.
$BaseFld = "Q:\Test\"
$Ext = "*.jpg"
$jpgFolders = gci $($BaseFld+$Ext) -Recurse |
Select -ExpandProperty Directory -Unique |
select -ExpandProperty Fullname | Sort
ForEach ($Folder in $jpgFolders) {
Set-location $Folder
$i = 1
Get-ChildItem $Ext | %{Ren $_ -NewName ('{0:D4}.jpg' -f $i++) -whatif}
}
If the ouptut suits you, remove the -whatif in the second last line
other method
$rootdir="C:\temp"
gci $rootdir -Recurse -Directory | %{$i=1; gci $_.FullName -Recurse -File -Filter "*.jpg" | %{Ren $_.FullName -NewName ('{0}.jpg' -f $i++)} }

Counting folders with Powershell

Does anybody know a powershell 2.0 command/script to count all folders and subfolders (recursive; no files) in a specific folder ( e.g. the number of all subfolders in C:\folder1\folder2)?
In addition I also need also the number of all "leaf"-folders. in other words, I only want to count folders, which don't have subolders.
In PowerShell 3.0 you can use the Directory switch:
(Get-ChildItem -Path <path> -Directory -Recurse -Force).Count
You can use get-childitem -recurse to get all the files and folders in the current folder.
Pipe that into Where-Object to filter it to only those files that are containers.
$files = get-childitem -Path c:\temp -recurse
$folders = $files | where-object { $_.PSIsContainer }
Write-Host $folders.Count
As a one-liner:
(get-childitem -Path c:\temp -recurse | where-object { $_.PSIsContainer }).Count
To answer the second part of your question, of getting the leaf folder count, just modify the where object clause to add a non-recursive search of each directory, getting only those that return a count of 0:
(dir -rec | where-object{$_.PSIsContainer -and ((dir $_.fullname | where-object{$_.PSIsContainer}).count -eq 0)}).Count
it looks a little cleaner if you can use powershell 3.0:
(dir -rec -directory | where-object{(dir $_.fullname -directory).count -eq 0}).count
Another option:
(ls -force -rec | measure -inp {$_.psiscontainer} -Sum).sum
This is a pretty good starting point:
(gci -force -recurse | where-object { $_.PSIsContainer }).Count
However, I suspect that this will include .zip files in the count. I'll test that and try to post an update...
EDIT: Have confirmed that zip files are not counted as containers. The above should be fine!
Get the path child items with recourse option, pipe it to filter only containers, pipe again to measure item count
((get-childitem -Path $the_path -recurse | where-object { $_.PSIsContainer }) | measure).Count

Resources