Powershell Copy-Item does not keep folderstructure like intended - powershell

I try to use powershell to deploy a build (Visual Studio) to multiple remote server.
The problem is, that the powershellscript does not copy the folders like I intendet to.
I use the following powershell command to copy the published website to the destinations.
Copy-Item -Path D:\Websites\$(ProjectName)\ -Recurse -Destination \\%RemoteServer%\D$\Websites\$(ProjectName)\ -Container -Exclude *.config -force
When the folder on the remoteserver does not exist, everything works fine.
But if the folder exists, all files are copied into a new subfolder instead of overwriting the existing ones.
So in the first execution the destination is corrected and looks like this:
D:\Websites\TestWebsite\ {all files}
After a second copy, the destination of the copy is:
D:\Websites\TestWebsite\Publish\ {all files}
The variables ProjectName and RemoteServer are in both executions the same.

Related

Copy-item cmdlets only working correctly when the destination folder exists

I want to copy folders with their contents to a remote computer using a PSSession and Copy-item. When running the script for the first time it has to create the destination folder, it does so correctly and then is supposed to dump the folders with their contents inside into the destination folder. What it is instead doing is dumping two of the folders correctly and then dumping the contents of the third folder, not the folder itself. When I run it a second time without deleting the destination folder, everything runs fine.
I have tried using various different parameters, including -container but it doesn't seem to help at all. Here is where I use the function in my code, I use a lot of environment variables and variables in general because this needs to be a script that can be put anywhere and work.
if (Test-Path -path "$env:TEMP\VMlogs") {
Write-Host "I'M GONNA SEND IT!"; Pause
Copy-Item -path "$env:TMP\VMLogs\*" -tosession $Targetsession -destination $Destination`_$Source -force -recurse
Write-Host Logs copied sucessfully!
Remove-Item "$env:TEMP\VMlogs" -recurse
} else {
Write-Host "There was an issue copying logs!"
Pause
Exit
What I expect is that the folders are put into the destination folder with their intact structure but instead this only happens on the second running of the script, after the destination folder has already been created.

Copy All Items within a Drive and Export to New Destination

I need to be able to copy all items within a drive and move them to a new destination using Powershell. At present, I've tried doing this with Copy-Item but am unable to do so within a drive. I've looked for solutions elsewhere but have yet to find a working fix, Any suggestions?
Copy-Item -Path 'P:' -Destination 'Destination'
If you're trying just to copy all of the items from one drive to a folder on another drive, you can use Copy-Item, like you are, with a few adjustments (-Destination path is just an example):
Copy-Item -Path C:\* -Destination F:\destinationPath -Recurse
Using the * in C:\* for the path tells the shell to get all files and directories at that folder, in this case, the C: root. -Recurse tells it to copy all files and directories recursively. Consider adding the -Force parameter if you want to use this in automation, as it will forcibly overwrite any existing files at the destination rather than prompt for input.

Powershell copy file from an environment variable to the zip folder of another environment variable

I am really new to the Powershell and want to copy a file from BUILD_SOURCESDIRECTORY environment variable to a zip folder inside BUILD_STAGINGDIRECTORY environment variable in my VSTS build definition.
if(Test-Path $Env:BUILD_SOURCESDIRECTORY/MyFolder/MyFIle.txt)
{
Write-Host "Source File: $Env:BUILD_SOURCESDIRECTORY/MyFolder/MyFIle.txt"
Write-Host "Target Location: $Env:BUILD_STAGINGDIRECTORY\StagingDirectoryFolder.zip\TestFolder"
}
Copy file from one path to another is quite straight forward but I really don't know how to move file into the zip folder structure.
If I could suggest a non power shell solution (although it is worth looking up the Expand-Archive and Compress-Archive cmdlets as recommended in the comments.)
I would use a Archive Files build task to handle the zipping. In your power shell build script, copy your artifact(s) into $ENV:BUILD_BINARIESDIRECTORY, and then leverage the VSTS build to do the archiving of all of the files.
This then lets you publish that zip file using the VSTS build which will allow it to be easily accessible through the VSTS web gui which imo offers a superior user experience (for troubleshooting your build, as well as other users who need access to those artifacts (either physical people, or automated processes)). If you need to do something else with the zip file, you could then add another powershell script after your archive files that would be able to access the file from the $ENV:BUILD_ARTIFACTSTAGINGDIRECTORY. This way your scripts stay simple, and you can offload some of your build maintenance onto Microsoft.
You can copy MyFIle.txt to the subfolder TestFolder under a zip file by Expand-Archive and Compress-Archive (as gvee mentions). The PowerShell script as below:
if(Test-Path $(Build.SourcesDirectory)\MyFolder/MyFIle.txt)
{
clear-host
[string]$zipF = '$(Build.ArtifactStagingDirectory)\StagingDirectoryFolder.zip'
[string]$fileToZip = '$(Build.SourcesDirectory)\MyFolder\MyFIle.txt'
[string]$tempEx= '$(Build.SourcesDirectory)\temp'
[string]$copyDes='$(Build.SourcesDirectory)\temp\TestFolder'
Expand-Archive -Path $zipF -DestinationPath $tempEx -Force
Copy-Item $fileToZip -Destination $copyDes -Force
Compress-Archive -Path $tempEx\* -Update -DestinationPath $zipF
Remove-Item -Recurse -Force $tempEx
}
Now the zip file $(Build.ArtifactStagingDirectory)\StagingDirectoryFolder.zip contains MyFIle.txt under $(Build.ArtifactStagingDirectory)\StagingDirectoryFolder.zip\TestFolder.

PowerShell not returning items in current directory with wildcard

I'm trying to create a PowerShell script to automatically create and upload Nuget packages to a local Nuget feed, but I'm having some issues with PowerShell that I don't understand.
The first step is to create all the packackages with this command:
Get-ChildItem -Include *.nuspec -Recurse | Foreach {nuget pack $_.fullname}
This goes in to each project directory and recursively looks for .nuspec files, and builds the .nupkg file for each of them, placing it in the solution directory. In this case "MultiPack.Client.1.0.0.nupkg", "MultiPack.Common.1.0.0.nupkg", and "MultiPack.Server.1.0.0.nupkg". It seems to be working just fine.
The next step would be to run nuget add fileName.nupkg -Source "c:\localNuget" on each of those files. I modified the previous command to:
Get-ChildItem -Include *.nupkg | Foreach {nuget add $_.fullname -Source c:\localNuget}
but it doesn't seem to be working. Doing some debugging, I find that Get-ChildItem -Include *.nupkg produces no results even though the files are definitely there. It works if I use -Recurse, but I don't really want to do that, since the .nupkg files will always be in the current directory.
Why isn't it finding my files with the wildcard, and how can I change the script to work without the -Recurse flag?
As stated by Tomalak
Try -Filter instead of -Include
Reason:
You need a "-Recurse" to get this working with Include
The -Include parameter is effective only when the command includes the
-Recurse parameter or the path leads to the contents of a directory, such as C:\Windows*, where the "*" wildcard character specifies the
contents of the C:\Windows directory.

Excluding a file while using Copy-Item

I'm having a few issues while copying desktop files as a part of the back up process from local folder to server.
My script automatically creates a backup folder on the server and I just realised when it creates the back up folder windows automatically creates a desktop.ini file, and as desktop.ini is a system file the script failed to write another desktop.ini from desktop to the backup folder in server.
My initial code was :
Copy-Item ("$Global:localBackupRestoreLocation\Desktop\$file") ("$Global:remoteBackupRestorePath\$nameOfbackupDirectory") ($recursive="true")
But I was to use the exclude in that line and I know exclude does not work recursively and I have to use Get-ChildItem.
Try something like this
$Exclude = #('desktop.ini')
copy-item -Path $Source -Destination $Dest -Exclude $Exclude