Powershell array failing because of "Copy-Item : Illegal characters in path."

167 Views Asked by At

I have a specific usecase where I need to identify if files from a list exist, and if so, copy them to a separate location with the relevant file structure kept. I need to keep my list of targets in the same script.

I believe my issue is something to do with the way the data inside isn't being parsed correctly due to ":" for drive letters, but I'm unsure of how to get round this issue. As you can see from the code below, I attempted to fix the issue by ignoring the drive letter, and appending it during the Copy-Item, but it doesn't seem to work either. (e.g: C:\folder\file becomes \folder\file in the list.)

I created test directory to just help show the issue, of examples of files/folders that I want to grab (purely for testing, the real files are multiple locations/file types).

- test_dir_cmd
    - folder
        - folder1
            * file2.db
            * file3.json
        * file2.txt
        * file3.js
    - folder2
        * file.bak
        * file.db
        * file.txt
    * temp.dat

This method works for folders and their contents, but not for specific files or wildcard.

"\USERS\$USER\AppData\Local\test_dir_cmd\folder\folder1",
"\USERS\$USER\AppData\Local\test_dir_cmd\folder\*.txt",
"\USERS\$USER\AppData\Local\test_dir_cmd\*\file.db",
"\USERS\$USER\AppData\Local\test_dir_cmd\temp.dat”

This is an example of how the list of files I'll need to get is presented and I'll need to work with.

Errors given:

Copy-Item : Illegal characters in path.
At F:\P2P.ps1:37 char:1
+ Copy-Item "C:$path" -Destination "$triage_location\$path" -Force -Rec ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Copy-Item], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.CopyItem 
   Command

Full script used for context:

$triage_location = "C:\temp\output\Triage\c"

ForEach-Object { #Looping through C:\Users to find folders that begin with numbers only and add to an array called $users
    $users = @(Get-ChildItem -Path 'C:\Users'| Where-Object { $_.Name -match '^c+' } | Select -ExpandProperty Name)
}
Write-Host "users = $users"
write-host ""

$path_array = foreach ($user in $users) { # Loop through contents of users array and add each user to known locations

@(
    "\USERS\$USER\AppData\Local\test_dir_cmd\folder\folder1",
    "\USERS\$USER\AppData\Local\test_dir_cmd\folder\*.txt",
    "\USERS\$USER\AppData\Local\test_dir_cmd\*\file.db",
    "\USERS\$USER\AppData\Local\test_dir_cmd\temp.dat”
  )
 }

Write-Host "path_array = $path_array"
write-host ""

foreach ($path in $path_array) {
$a = Test-Path -Path "C:$path" # Creating variable called 'a' and setting it to Test-path value which is either True/False

if ($a -eq "True") # Test if browser location paths exist or not. If a returns True/False...
{
Write-Host "C:$path exists"
    if(!(Test-Path -Path "$triage_location"))
    {
        New-Item -ItemType Directory -Path $triage_location
    }

Copy-Item "C:$path" -Destination "$triage_location\$path" -Force -Recurse

}

else
{Write-Host "C:$path doesn't exist"}

}

if(Test-Path -Path "C:\temp\output\Triage")
    {
        Write-Host ""
        Write-Host "Creating relevant .ZIP"
        Compress-Archive -Path 'C:\temp\output\Triage' -DestinationPath 'C:\temp\output\P2P.zip' -Force # put zip in documents
    }

Any help and advice on how I can fix this would be greatly appreciated!

1

There are 1 best solutions below

1
On

The issue is that you are not joining the paths well. You do this:

-Destination "$triage_location\$path"

At that point $triage_location is C:\temp\output\Triage\c and $path is something like \USERS\TMTech\AppData\Local\test_dir_cmd\folder\folder1. You just make the path with string expansion but since $path starts with a \ and you include that in your string, so your string comes out looking like this:

"C:\temp\output\Triage\c\\USERS\TMTech\AppData\Local\test_dir_cmd\folder\folder1"

Use Join-Path instead:

Copy-Item (Join-Path 'C:\' $path) -Destination (Join-Path $triage_location $path) -Force -Recurse