I want to copy folder EXCLUDING those with certain folder names - powershell-2.0

I have a folder called "Testnames" and within that two folders called "Bunny, Bugs_" and "Lightyear, Buzz".
Using the command:
Get-ChildItem C:\Users\Galen\Desktop\Testnames -Recurse -Exclude '_'
I get:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 10/9/2015 11:43 AM Lightyear, Buzz
Perfect!
However when I use the command:
Copy-Item C:\Users\Galen\Desktop\Testnames -Exclude '_' -Recurse C:\Users\Galen\Testfolder
Both Bug's and Buzz's folders are copied into Testfolder. What change do I need to implement to only copy Buzz's folder?

Run Get-ChildItem without the parameter -Recurse to get the root folders. Filter that list for items that don't have an underscore in their name. Then copy the remaining items recursively.
Get-ChildItem 'C:\Users\Galen\Desktop\Testnames' |
Where-Object { $_.Name -notlike '*_*' } |
Copy-Item -Destination 'C:\Users\Galen\Testfolder' -Recurse

Related

Delete long name path folders older than 7 days

I need to make a script that it will be delete folders and files(all things), but only older than 7 days. I have a code, but it has a problem when path name is longer than 256 chars. One of the user has a many folders, name lenght equal 303 chars.
Below code works on Windows 10, but has problem on Windows 2008R2(.net 4.7.2) with \\?\....
Get-ChildItem -Path '\\?\c:\test\users' | ?{ $_.CreationTime -le $(Get-Date).AddDays(-7) } | Remove-Item -recurse -force
And that has problem with long path name:
Get-ChildItem D:\foler\folder\file | ?{ $_.CreationTime -le $(Get-Date).AddDays(-7) } | Remove-Item -Force -Recurse
Get-ChildItem D:\foler\folder\file | ?{ $_.CreationTime -le $(Get-Date).AddDays(-7) } | Remove-Item -Force -Recurse
Also I try with robocopy. So will be ok any script on powershell, .bat or .vbs.

Rename files with same name and extension (usually .pdf) in the sub directories with incrementing number

My folder structure is like this:
Folder 1
File 1.pdf
File 2.pdf
File 3.pdf
Folder 2
File 1.pdf ---> Rename this to "File 1-1.pdf"
File 2.pdf ---> Rename this to "File 2-1.pdf"
File 5.pdf
SubFolder 2.1
File 2.pdf ---> Rename this to "File 2-2.pdf"
File 4.pdf
File 5.pdf ---> Rename this to "File 5-1.pdf"
Folder 3
File 1.pdf ---> Rename this to "File 1-2.pdf"
File 2.pdf ---> Rename this to "File 2-3.pdf"
File 4.pdf ---> Rename this to "File 4-1.pdf"
File 6.pdf
File 7.pdf
This is what i was trying, but its certainly wrong. I am using Powershell Version 2.0.
$i = 1
$folder = Get-ChildItem "C:\Users\xyz\testfolder\pdf_files\"
foreach ($file in $folder){
if (($file.BaseName + $file.extension) -match ($file.BaseName +
$file.extension)){
Rename-Item -Path $file.FullName -NewName "$($file.BaseName +
$i)$($file.extension)" -Verbose -WhatIf
$i++
}
}
I just found the answer to my question through a very kind person. Anyway..here is the PS script that worked for me..
$Files = Get-ChildItem -LiteralPath 'C:\Foo\Bar\Files\' -Recurse | Where-
Object { -not $_.PSIsContainer }
$FileNameCounts = #{}
ForEach ($File In $Files) {
$BaseName = $File.BaseName
If ($FileNameCounts.Keys -contains $BaseName) {
$NewName = '{0}-{1}{2}' -f $BaseName, $FileNameCounts[$BaseName],
$File.Extension
$File | Rename-Item -NewName $NewName -WhatIf
$FileNameCounts[$BaseName]++
} Else {
$FileNameCounts[$BaseName] = 1
}
}
Here is an alternative way of doing the same thing.
Get-ChildItem -Recurse -file | Group-Object Name | foreach-object {
$script:i = 1
$_.Group | Select-Object -Skip 1 |
Rename-Item -newname { "{0}-{1}{2}" -f $_.basename, $script:i++, $_.extension }
}
Group-Object gives us all the files with the same name, and for each group of names, the first file is skipped and the rest is being renamed.
It also takes advantage of a feature that was designed specifically for this usecase, that -NewName can take a scriptblock as a parameter. The scriptblock will be invoked for each pipeline item and the result will be passed to Rename-Item as the newname.

Powershell wildcard on returns items

I'm trying to determine whether the directories under a specified root directory contain files that match a certain pattern, in my case RT*.dcm.
I'm using Powershell 2.0 and I first obtain all sub-directories beneath the specified root directory using
$dirList = Get-ChildItem $homeDir -recurse | where {$_.Attributes -eq 'Directory'} | Select-Object FullName
I then loop through these to see if they contain *.dcm files using (perhaps there's a better way?)
# Find files with a "dcm" extension.
$fileList = Get-ChildItem $dir.fullname | where {$_.extension -eq ".dcm"} | Select-Object FullName
# Look for directories that contain *.dcm files
if ($fileList.Count -gt 0) {
[Console]::WriteLine("Dicom directory: " + $dir.fullname)
$dicomDirList += $dir
}
The above two sections work ok
I then search through the found directories using
foreach($dir in $dicomDirList) {
$rtFileList = Get-ChildItem $dir | where {$_.name -like "RT*.dcm"} | Select-Object FullName
foreach($file in $rtFileList) {
[Console]::WriteLine("RT likey file: " + $file.fullname)
}
}
However this doesn't find the files I know that are there?
If I use
Get-ChildItem C:\myfolder\RT*.dcm
this works, but I can't figure out how to use the returned items from the previous Get-ChildItem call
Could someone please point me in the right direction?
It looks like you may be over-complicating things.
To accomplish what Get-ChildItem C:\myfolder\RT*.dcm does for the entirety of $homeDir (which is what I believe you're trying to do), you can use a single Get-ChildItem command:
Get-ChildItem $homeDir -Recurse | Where-Object{$_.Name -like "RT*.dcm"}
This searches the entirety of $homeDir recursively for all of the .dcm files you're looking for and returns them.

PowerShell copy random files

I am trying to copy 7 random .txt files to a different location, but sub-folders get copied instead of the .txt files.
Here is my script:
$d = #(gci G:\Users\Public\Test) | resolve-path | get-random -count 2
$d | gci | get-random -count 7
Copy-Item $d -destination G:\Users\Public\Videos
What do I need to change?
One possible solution might be to use the PSIsContainer attribute to filter out folders.
I tried the following...
$d = gci "C:\Work\a\*.txt" | Where {$_.psIsContainer -eq $false}| resolve-path | get-random -count 7
Copy-Item $d -destination C:\Work\b
The where clause filtered out anything that was not a "container" and ignored the test folders I had set up. If you need .txt files specifically then use the wildcard included in the path as above.
Also, if you were to add -recurse then it would presumably search in all sub folders of your original search location and still filter out any "folders" for copying. Though I haven't tested this very thoroughly.
$d = gci "C:\Work\a\*.txt" -recurse | Where {$_.psIsContainer -eq $false}| resolve-path | get-random -count 7

Powershell: Count items in a folder with PowerShell

I'm trying to write a very simple PowerShell script to give me the total number of items (both files and folders) in a given folder (c:\MyFolder). Here's what I've done:
Write-Host ( Get-ChildItem c:\MyFolder ).Count;
The problem is, that if I have 1 or 0 items, the command does not work---it returns nothing.
Any ideas?
You should use Measure-Object to count things. In this case it would look like:
Write-Host ( Get-ChildItem c:\MyFolder | Measure-Object ).Count;
or if that's too long
Write-Host ( dir c:\MyFolder | measure).Count;
and in PowerShell 4.0 use the measure alias instead of mo
Write-Host (dir c:\MyFolder | measure).Count;
I finally found this link:
https://blogs.perficient.com/microsoft/2011/06/powershell-count-property-returns-nothing/
Well, it turns out that this is a quirk caused precisely because there
was only one file in the directory. Some searching revealed that in
this case, PowerShell returns a scalar object instead of an array.
This object doesn’t have a count property, so there isn’t anything to
retrieve.
The solution -- force PowerShell to return an array with the # symbol:
Write-Host #( Get-ChildItem c:\MyFolder ).Count;
If you need to speed up the process (for example counting 30k or more files) then I would go with something like this..
$filepath = "c:\MyFolder"
$filetype = "*.txt"
$file_count = [System.IO.Directory]::GetFiles("$filepath", "$filetype").Count
Only Files
Get-ChildItem D:\ -Recurse -File | Measure-Object | %{$_.Count}
Only Folders
Get-ChildItem D:\ -Recurse -Directory | Measure-Object | %{$_.Count}
Both
Get-ChildItem D:\ -Recurse | Measure-Object | %{$_.Count}
You can also use an alias
(ls).Count
Recursively count files in directories in PowerShell 2.0
ls -rec | ? {$_.mode -match 'd'} | select FullName, #{N='Count';E={(ls $_.FullName | measure).Count}}
In powershell you can to use severals commands, for looking for this commands digit: Get-Alias;
So the cammands the can to use are:
write-host (ls MydirectoryName).Count
or
write-host (dir MydirectoryName).Count
or
write-host (Get-ChildrenItem MydirectoryName).Count
To count the number of a specific filetype in a folder.
The example is to count mp3 files on F: drive.
( Get-ChildItme F: -Filter *.mp3 - Recurse | measure ).Count
Tested in 6.2.3, but should work >4.

Resources