Copying over files using powershell seems very inconsistent - powershell

I am not certain I understand where I am going wrong.
I basically have the same command copying and pasting files for different instances. I guess I could have built it more object oriented, so I can solve the problem once and apply it for different instances, but this is a freaking script, and I just want to copy over dll's and pdb's...
gci -path $FromPath\* -Include *.dll, *pdb | ? {$_.Name -match "example1|example2|example3|example4|example5"} | foreach{
write-host("File being moved: "+ $_.Fullname) Copy-item $_.Fullname -destination $ToPath -force
}
The above works and sends dll's and pdb's to the correct directory.
gci -path $FromPath\* -Include *.dll, *pdb | ? {$_.Name -match "example1|example2|example3|example4"}| foreach{
write-host("File being moved: "+ $_.Fullname) Copy-item $_.Fullname -destination $ToPath -force
}
That does not. For whatever reason my pdb's don't go over with my dll's. I can't understand why it only grabs the dll and not the pdb. It lists both of them if I write out, why doesn't it move over both of them?

Related

powershell copy all folder structure and exclude one or more folders

I'm trying to use PowerShell to copy a folder with sub-folders from our users to a small backup. These folders contain a folder called "windows" I don't want to copy.
I have tried "exclude" but can't seem to get it to work.
This is the script so far:
Copy-Item "E:\Curos folder" -Exclude 'Windows' -Destination "E:\Curos folder backup" -Recurse -Verbose
I have read other posts but don't quiet understand how it works
It's my first time working with PowerShell
You are complete right.
Actually the script it's simpler than the one I have wrote before.
Here we go:
$source = "C:\Users\gaston.gonzalez\Documents\02_Scripts"
$destination = "D:\To Delete"
$exclude = "Windows"
$folders = Get-ChildItem -Path $source | Where {($_.PSIsContainer) -and ($exclude -notcontains $_.Name)}
foreach ($f in $folders){
Write-Host "This folders will be copied: $f"
Copy-Item -Path $source\$f -Destination $destination\$f -Recurse -Force
}
I'd use something like this:
Get-ChildItem $root -Directory -Recurse | % {$_.name -ne 'Windows'} | foreach {Copy-Item "$($_.FullName)" -Destination $dest -Recurse}
I haven't tested it but it's the skeleton of something you should be able to make work, although I don't find the point of using recurse on both, Get-ChildItem and Copy-Item my advice is to use it on Get-ChildItem.

Powershell: Move file from one directory to another, based on string within file

Looking around the site and can't seem to find some answers for myself.
I'm looking to write a script, that will enable me to move files from one destination to another, based on the contents within the file.
To get into Specifics
Source Destination - V:\SW\FromSite
Copy to Destination - V:\SW\ToSW
FileType - .txt
String - test
Ideally I'd also like to ONLY have the script search files that begin with 7. These are unique identifiers to a region.
Pulling my hair out a bit trying.
I was using the below, which runs without error, but does nothing.
$DestDir = "V:\SW\FromSite"
$SrcDir = "V:\SW\ToSW"
$SearchString = "test"
gci $SrcDir -filter 7*.txt | select-string $SearchString | select path |
move-item -dest $DestDir -whatif
Here's what I would do, though I'm sure there's a more streamlined way to do it.
$files = gci $SrcDir -filter 7*.txt
$files | %{
if ((select-string -path $_.FullName -pattern $SearchString) -ne $null) {
move-item -path $_.FullName -dest $DestDir
}
}
So did some more messing around and the below is working perfectly for what I need
get-childitem "<SourceFolder>" -filter 7*.txt -
recurse | select-string -list -pattern "test" | move -dest "<DestinationFolder>"
Thanks all for the help
Not sure if I missed something (didn't tried it on my machine) - but as long as you pass the -whatif option, move-item "shows what would happen if the cmdlet runs. The cmdlet is not run."; see https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/move-item.
So probably it would have been sufficient to just remove the -whatif from the initial statement.

PowerShell to copy files to destination's subfolders while excluding certain folders in the destination

So I have danced with this off and on throughout the day and the timeless phrase "There's more than one way to skin a cat" keeps coming to mind so I decided to take to the community.
Scenario:
Source folder "C:\Updates" has 100 files of various extensions. All need to be copied to the sub-folders only of "C:\Prod\" overwriting any duplicates that it may find.
The Caveats:
The sub-folder names (destinations) in "C:\Prod" are quite dynamic and change frequently.
A naming convention is used to determine which sub-folders in the destination need to be excluded when the source files are being copied (to retain the original versions). For ease of explanation lets say any folder names starting with "!stop" should be excluded from the copy process. (!stop* if wildcards considered)
So, here I am wanting the input of those greater than I to tackle this in PS if I'm lucky. I've tinkered with Copy-Item and xcopy today so I'm excited to hear other's input.
Thanks!
-Chris
Give this a shot:
Get-ChildItem -Path C:\Prod -Exclude !stop* -Directory `
| ForEach-Object { Copy-Item -Path C:\Updates\* -Destination $_ -Force }
This grabs each folder (the -Directory switch ensures we only grab folders) in C:\Prod that does not match the filter and pipes it to the ForEach-Object command where we are running the Copy-Item command to copy the files to the directory.
The -Directory switch is not available in every version of PowerShell; I do not know which version it was introduced in off the top of my head. If you have an older version of PowerShell that does not support -Directory then you can use this script:
Get-ChildItem -Path C:\Prod -Exclude !stop* `
| Where-Object { $_.PSIsContainer } `
| ForEach-Object { Copy-Item -Path C:\Updates\* -Destination $_ -Force }
To select only sub folders which do not begin with "!stop" do this
$Source = "C:\Updates\*"
$Dest = "C:\Prod"
$Stop = "^!stop"
$Destinations = GCI -Path $Dest |?{$_.PSIsContainer -and $_.Name -notmatch $Stop }
ForEach ($Destination in $Destinations) {
Copy-Item -Path $Source -Destination $Destination.FullName -Force
}
Edited Now copies all files from Update to subs of Source not beginning with "!stop" The -whatif switch shows what would happen, to arm the script remove the -whatif.
Edit2 Streamlined the script. If also Sub/sub-folders of C:\Prod shall receive copies include a -rec option to the gci just in front of he pipe.

I get errors when trying to rename files

I have files in a folder C:\Users\xxx\Documents\Projects\files\old\. I have built a loop to rename them but it doesn't work out:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName $newfiles+"$($entry.Custom_ID).$($file.BaseName).PDF"
How do I concatenate properly $newfiles to the rename path? I tried everything but keep getting errors:
Rename-Item : A positional parameter cannot be found that accepts argument '-'
you need to either copy and rename or move and rename files.using -whatif is a good practise because it shows you what is going to happen if you execute a particular command.
Notice also i am using a filter to get-childitem to only get the pdf files so that i know that the files i am going to rename will only be pdf files. of course if the oldfiles folder only contains pdf files then you dont need to use the filter.
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
$oldfiles = "C:\Users\xxx\Documents\Projects\files\old\"
Get-ChildItem -Path $oldfiles -Filter *.pdf |
Move-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf
or
Get-ChildItem -Path $oldfiles -Filter *.pdf |
copy-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf
This is how I always concatenate things in Powershell:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName ("{0}{1}.PDF" -f $newfiles,$($entry.Custom_ID).$($file.BaseName))
From experience, this always works.

Powershell not copying files and not throwing exception

I am not understanding what is happening.
I am attempting to copy and paste dll's from one directory and another.
gci -path $FromPath -Include ("*.dll", "*.pdp") | ? {$_.Name -match "appMaskA|appMaskB|appMaskC"} | foreach{Copy-item $_.Fullname -destination $ToPath -force}
Now that command works for one function that I have it in, but not for this one...
Now, this command is moving dll's to a different server. Not certain why it isn't working.
And if it isn't working it should throw an exception. I did wrap that command in a try catch by the way? Should I be catching a specific exception?
What does your $ToPath look like? If your code is wrapped in try/catch add -ErrorAction Stop parameter to your copy statement as the default value is to continue so the catch block will never be executed.
gci -path $FromPath -Include ("*.dll", "*.pdp") | ? {$_.Name -match "appMaskA|appMaskB|appMaskC"} | foreach{Copy-item $_.Fullname -destination $ToPath -force -ErrorAction Stop}
Does this need to be Powershell or can you use XCOPY via a BASH/CLI script. Using XCOPY you can access C Drive by doing
SERVER.DOMAIN.LOCAL/c$/path/to/dll
Maybe this works for you:
gci -path $FromPath -Include *.dll,*.pdp | where {$_.Name -match "appMaskA|appMaskB|appMaskC"} | Copy-item -path $_ -destination $ToPath -force
For complicated and/or large copying jobs I would use the program robocopy. Robocopy is part of Windows. Execute this command to verify its location:
Get-Command robocopy|select path