My code below moves databases from one location to another location:
$filters = Get-Content "c:\customerName.txt"
$source = "\\Server1\Databases"
$destination = "\\Server2\Databases"
foreach($filter in $filters)
{
Get-Childitem $source -include *.* -Recurse`
| ? {!$_.PsIsContainer -and $_.fullname -match $filter} `
| % {
Move-Item $_.FullName -Destination $destination"\$filter"
}
}
The code works absolutely fine, but I need to change it so that it doesnt move files from a specific folder i.e. \\Server1\Databases\AMG
So am trying to edit the above code as following:
foreach($filter in $filters)
{
Get-Childitem $source -include *.* -Recurse | where {$_.source -notlike *"\\Server1\Databases\AMG"*} `
| ? {!$_.PsIsContainer -and $_.fullname -match $filter} `
| % {
Move-Item $_.FullName -Destination $destination"\$filter"
}
}
But if I run the code, it moves everything including the stuff from \\Server1\Databases\AMG
How can I fix this code to work as it is supposed to? Any ideas?
You need to change:
Get-Childitem $source -include *.* -Recurse | where {$_.source -notlike *"\\Server1\Databases\AMG"*}
To:
Get-Childitem $source -include *.* -Recurse | where {$_.fullname -notlike "*\\Server1\Databases\AMG*"}
There is no .source property returned by Get-Childitem. Instead you could use .fullname which is the full path for each file or folder.
You should put the * wildcard characters inside the quote marks.
Related
I am trying to recursively search for files on a windows 7 machine + network drives attached to it while excluding certain folders i.e. C:\windows & all recursive folders in this such as system32.
I know this question has been asked before but following the answers has not helped and I am still left with a blank variable.
Here are the combinations I have tried:
$AllDrives = Get-PSDrive
$files=#("*.xml",*.txt)
foreach ($Drive in $AllDrives) {
if ($Drive.Provider.Name -eq "FileSystem") {
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notlike "*Windows*" -and $_.PSParentPath -notlike "*Microsoft*"
}
}
I have also tried these combinations:
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notmatch "Program Files|Users|Windows"}
$exclude_pattern = $drive.root + "Windows"
$filenames = Get-ChildItem -Force -Recurse -path $drive.root -Include $files -Attributes !Directory+!System -ErrorAction "SilentlyContinue" | Where-Object { $_.PSIsContainer -eq $false } | Where-Object { $_.FullName -notmatch $exclude_pattern }
Unfortunately, after an amount of time has elapsed, when I type $filename into the terminal nothing has been assigned to it.
I am doing some batch file name updates and am having trouble including folders. I have it currently set to target only specific file types, but I also want to include folders. Since folders don't have an extension I am unsure how to specify folders in the "-include" string. Any help would be greatly appreciated.
Here is what I am currently working with, but it ignores folders when I would like them included.
Get-ChildItem k:/toolbox/powershell -Include *.gif, *.jpg, *.png, *.xls,
*.xlsx, *.ppt, *.pptx, *.doc, *.docx, *.pdf -recurse | where {$_.name -match
"_"} | foreach {
$New=$_.name.Replace("_","-")
Rename-Item -path $_.Fullname -newname $New -passthru
}
(Get-Item '~\Desktop\*') | foreach { $FolderName = $_.name.Replace("_","-"); Rename-Item -path $_.fullname -newname $FolderName -passthru }
I would just add 2nd statement:
Get-ChildItem "k:/toolbox/powershell" -Recurse |where mode -eq d----- | where {$_.name -match "_"} | foreach {$New=$_.name.Replace("_","-")
Rename-Item -path $_.Fullname -newname $New -passthru }
If you run Get-ChildItem "k:/toolbox/powershell" you will receive a list of items where the "Mode" is "d-----" for directories, hence you can use that filter criteria for directories
I tried to copy files from one folder to another which have word HIGH at the end of name of files in their names but didn't get it. Any suggestion?
$dest = "C:\transform"
$source = "D:\result"
get-childitem $source - filter ".jpg" -recurse | Where-Object {$_.DirectoryName -match "HIGH" | ForEach-Object { Copy-Item $.fullname $dest}
$_.DirectoryName holds the folder name, $_.Name the file name :
$dest = "C:\transform"
$source = "D:\result"
Get-ChildItem $source -Filter ".jpg" -Recurse |
? { $_.BaseName -match "HIGH$" } |
% { Copy-Item $_.FullName $dest}
Or, as pointed by #Walter Mitty, a simpler :
Copy-Item -Path $source -Filter "*HIGH.jpg" -Destination $dest –Recurse
(in this case -Filter and -Include seem to behave the same)
The simplest way to copy files from one folder to another is the Copy-Item cmdlet.
Take a look at the -Path -Include -Destination and -Recurse parameters.
https://technet.microsoft.com/library/60a19812-67ab-4b58-a6f5-34640edafbb0(v=wps.630).aspx
I have subfolders, and subsubfolders. In the subsubfolders, I want to find all subfolders without a file named PKA.dump. Can this be done in powershell?
The subfolders go from Angle1, Angle2, etc up to Angle24
The subsubfolders go from 1eV, 2eV, to 150eV.
I can find when they are less than a certain size:
Get-Childitem -path . -filter "PKA.dump" -recurse | where {$_.Length -le 500}
But what if they dont exist?
If you have just 2 levels of directories, don't recurse. Do something like this instead:
Get-ChildItem -Path . -Directory | Get-ChildItem -Directory | ? {
-not (Test-Path -LiteralPath (Join-Path $_.FullName 'PKA.dump'))
}
For a deeper folder structure this should be ok:
Get-ChildItem -Path C:\yourpath\ -recurse | where {$_.psiscontainer} | % {
if((Get-ChildItem -Path $_.FullName -File).name -notcontains "pka.dump"){ $_.FullName }
}
I am trying to write a silent script that deletes files older than 14 days and removes empty folders. The part that deletes files work fine, but the part that deletes folders is popping up a confirmation window no matter what I do to suppress it. Here's my code:
$date=(get-date).AddDays(-14)
$ConfirmPreference="None"
$DebugPreference="SilentlyContinue"
$ErrorActionPreference="SilentlyContinue"
$ProgressPreference="SilentlyContinue"
$VerbosePreference="SilentlyContinue"
$WarningPreference="SilentlyContinue"
$OutputEncoding=[console]::OutputEncoding
function FullNuke ([string] $strPath) {
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {!$_.PSIsContainer -and $_.LastAccessTime -lt $date} | Remove-Item -Force
#The line below is the one that triggers the confirmation
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {$_.PSIsContainer -and #(Get-ChildItem -LiteralPath $_.FullName -Recurse -Force | Where-Object {!$_.PSIsContainer}).Length -eq 0} | Remove-Item -Force
}
Most of the answers I have found say to add -Recurse to my final Remove-Item command, but that would be the opposite of what I want. If the folder is empty, I want it removed. If it is not empty, I do not want it removed. I'm not sure why non-empty folders are even being caught in the first place.
UPDATE
After much frustration, I discovered that the second line was processing items in reverse order, thus requiring confirmation. It was also not properly identifying empty folders, which also triggered confirmation. I ended up using the following function.
function FullNuke ([string] $strPath) {
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {!$_.PSIsContainer} | Where-Object {$_.LastAccessTime -lt $date} | Remove-Item -Force
Get-ChildItem -Path $strPath -Recurse -Force | Where-Object {$_.PSIsContainer} | Where-Object {#(Get-ChildItem -LiteralPath $_.FullName -Recurse -Force).Length -eq 0} | Remove-Item -Force
}
I put it here because while it is a solution (it erases files and folders to my satisfaction), it is not an answer to my posted question.
Remove -Force from first Get-ChildItem and add -Recurse and -Confirm:$false.
This will work:
Get-ChildItem -Path $strPath -Recurse |
Where-Object {$_.PSIsContainer -and
#(Get-ChildItem -LiteralPath $_.FullName -Recurse -Force |
Where-Object {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -Force -Recurse -Confirm:$false
If you are using v3 or higher powershell client you can use the -directory and -file switches for Get-ChildItem and use this:
function FullNuke ([string] $strPath) {
Get-ChildItem -Path $strPath -Recurse -Force -File | Where-Object {$_.LastAccessTime -lt $date} | Remove-Item -Force
Get-ChildItem -Path $strPath -Recurse -Force -Directory | Where-Object {(gci $_.FullName -File -Recurse -Force).count -eq 0} | Remove-Item -Force -Recurse
}
Yes, I added -Recurse to the folder removal because with my testing no folders with any files in them were being passed to that point, and if it is a folder with nothing but empty folders in it then they all need to go anyway right?