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!
The issue is that you are not joining the paths well. You do this:
At that point
$triage_location
isC:\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:Use
Join-Path
instead: