0

Ive been banging my head with a powershell script that i've tried a few differnt methods with and was wondering if someone can help?

Unsure at this point if im just doing something silly, thanks in advance

Aim:

To copy a vbs file from user's homedrives to a different location, the location of the vbs file changes depending on which user needs account admin doing hence why this needs to be variable. It gets the location from a text file which includes the exact path to go to and a destination which has already been created to copy the files to.

Where I have the issue currently:

$location = Get-Content C:\Users\Administrator\Desktop\here\drive4.txt | Out-String
$dest = "C:\Users\Administrator\Desktop\here"
Get-ChildItem -Path $location | 
Copy-Item -Destination $dest -Recurse -Container -filter "peruser.vbs"
write-host $location

Read-Host -Prompt "Press Enter to continue or CTRL+C to quit"

The Issue

Please see the below, I have put write host to show the location powershell is trying to reach, as a side note I am able to reach this location fine through file explorer

Screenshot of error

Error Recieved

Get-ChildItem : Illegal characters in path.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (\\WIN-7V7GI0R7C...             
:String) [Get-ChildItem], ArgumentException
    + FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Cannot find path '\\WIN-7V7GI0R7CFK\homedrives\Onetest$                                                     

' because it does not exist.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (\\WIN-7V7GI0R7C...             
:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
3
  • What do you get on your variables? What the $location and $dest have after the command? Write $location = Get-Content C:\Users\Administrator\Desktop\here\drive4.txt | Out-String And then $location to check if it is the path you want. The other error has a $ in the end, is it a system directory? Probably the $ sign causing the error. Commented Mar 14, 2020 at 18:09
  • Hi there, I get the correct location on my variables -$Location points to \\WIN-7V7GI0R7CFK\homedrives\Onetest$, and $dest points to C:\Users\Administrator\Desktop\here . The directory i am trying to reach is a shared drive, all our users homedrives have a $ on the end Commented Mar 14, 2020 at 18:25
  • Try with the -Force switch on Get-ChildItem Commented Mar 14, 2020 at 20:45

2 Answers 2

0

Unless I have misunderstood you - you are just trying to copy a file to various locations based on a list. If so you just need to loop through your list. Does this work for you?

$location = Get-Content "C:\Users\Administrator\Desktop\here\drive4.txt"
$dest = "C:\Users\Administrator\Desktop\here"

foreach ($loc in $location){
    $vbs = (gci $loc -Filter "peruser.vbs").FullName
    Copy-Item $vbs $dest -Force
}
Sign up to request clarification or add additional context in comments.

5 Comments

What script this at all? You can just use Windows RoboCopy.exe for this effort. It's why it exists. Don't script if you don't have to. You could even use Robocopy in PowerShell scrips.I don't understand why you are doing this --- Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' | Out-String --- it is just a text file being read in there is really no reason to pipe that to the screen in a variable assignment. Also, you can get a drive list dynamically, using this... --- Get-PSDrive -PSProvider FileSystem and pipe / manipulate that as needed.
Just attempting to fix the questioners script. Like most things - there are various approaches you can take
Perfect thankyou! that worked a treat. The reason i am scripting it is because the organisation i work in has a large number of shared drives some of which have the same drive letter, when our helpdesk staff some of whome work only part time and do not have as much knowledge are doing account admin (adding permissions) they are adding a drive letter which the user already has assigned which is causing problems on their end. Doing this means they can simply type in the username and it will give them a list of drive letters not to assign,this is just a quick short term solution for them
Itchydon --- No disagreement about the help, as we all volunteer for this stuff. Also, 100% agree on the multiple approach ting as we are both showing in our samples. Yet, just pointing out a potential option that was not considered, as well. I am a firm believer after many years in this industry of the adage, don't unnecessarily increase your workloads, if the core platform provides what one could need. If you do get creative, that means you have to take care of that forever, documentation, maintenance, et all.
Agreed. It is just that sometimes when you have been looking at code for hours you want to know where you went wrong with your own code. I reckon the OP will learn more from looping techniques than the robocopy/ copy-item debate
0

You are not showing what is in the text file, forcing us to guess, which is not really a good thing relative to trying to help you. So, I am going to assume it's just a list of drive letters or path UNC's, which is really moot since you can pull those dynamically, thus no need for the file.

I don't understand why you are doing this...

Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' | 
Out-String

If it is just a text file for reading, why are you piping that anywhere?

You don't need double quotes for this. Single quotes for simple string, double for variable expansion or other specific formatted requirements

$dest = 'C:\Users\Adminstrator\Desktop\here'

Just pass the read directly

Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' | 
ForEach {
    "Processing location $($PSItem.FullName)"
    Copy-Item -Path $PSItem.FullName -Destination $dest -Filter 'peruser.vbs' -Recurse -WhatIf
} 

Point of note: You don't need Write-Host to output to the screen, as that is the PowerShell default, as I'll show in my example to follow. Really, except for writing screen text with color, you'd never need to use Write-Host/echo at all, well, there are a few other specific times to use it.

Also of note, regarding Write-Host from the inventor of Monad/PowerShell Jeffery Snover

You also, do not necessarily need both Get-ChildItem and Copy-Item, since both will read the folder tree recursively. As I'll show below. I am using splatting to tighten up the code block for readability.

So, if I demo this just using a drive and folder on my system. And step through a script build out to make sure I am getting what I expect at each step before moving to the next.

Get-PSDrive -PSProvider FileSystem | 
Format-Table -AutoSize
<#
# Results

Name Used (GB) Free (GB) Provider   Root  CurrentLocation
---- --------- --------- --------   ----  ---------------
C       357.48    118.83 FileSystem C:\  Windows\system32
D       114.10    362.71 FileSystem D:\           Scripts
E      1194.00    668.89 FileSystem E:\                  
F      3537.07    188.83 FileSystem F:\                  
G                        FileSystem G:\  
#>

# Validate if there is any content in the destination
Try 
{
    Get-PSDrive -PSProvider FileSystem | 
    Where Name -eq 'D' | 
    ForEach {
        "Processing location $($PSItem.Root) and the contents are as listed."
        (Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
    }
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results

Processing location D:\ and the contents are as listed.
WARNING: No content in the destination folder
#>

# Show what is on the drive for the source files
Get-PSDrive -PSProvider FileSystem | 
Where Name -eq 'D' | 
ForEach{
    "Processing the location $($PSItem.Root)"
    (Get-ChildItem -Path "$($PSItem.Root)\Temp\book1.csv" -Recurse).FullName
}
<#
# Results

Processing the location D:\
D:\Temp\Source\book1.csv
D:\Temp\book1.csv
#>

<#
# Show what will happen if a Copy files from the source to the destination occurs
Using splatting for readability
#>

Get-PSDrive -PSProvider FileSystem | 
Where Name -eq 'D' | 
ForEach{
    "Processing the location $($PSItem.Root)"
    $CopyItemSplat = @{
        Path        = "$($PSItem.Root)\Temp\book1.csv"  
        Destination = "$($PSItem.Root)\Temp\here" 
        Recurse     = $true
        WhatIf      = $true
    }
}
Copy-Item @CopyItemSplat
<#
# Results

Processing the location D:\
What if: Performing the operation "Copy File" on target "Item: D:\Temp\book1.csv Destination: D:\Temp\here\book1.csv".

If the results are as expected, execute the action
Using splatting for readability
#>

Get-PSDrive -PSProvider FileSystem | 
Where Name -eq 'D' | 
ForEach{
    "Processing the location $($PSItem.Root)"
    $CopyItemSplat = @{
        Path        = "$($PSItem.Root)\Temp\book1.csv"  
        Destination = "$($PSItem.Root)\Temp\here" 
        Recurse     = $true
    }
}
Copy-Item @CopyItemSplat
<#
# Results

Processing the location D:\
#>

# Validate if there is any content in the destination
Try 
{
    Get-PSDrive -PSProvider FileSystem | 
    Where Name -eq 'D' | 
    ForEach {
        "Processing location $($PSItem.Root) and the contents are as listed."
        (Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
    }
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results

Processing location D:\ and the contents are as listed.
D:\Temp\here\book1.csv
#>

3 Comments

Hi there thanks for the reply, I'll take a good look through once I'm home. This is the only real time I've had to expermient with powershell so the feedback on the other mistakes I have made will be really useful
No worries. We are all here to help when and where we can. Yet, if you are new, Jump on Youtube to get some ramp up. Just search for 'Beginning PowerShell', 'Intermediate PowerShell', 'Advanced PowerShell', 'PowerShell File and Folder Management','PowerShell copying files', 'PowerShell Moving files', etc. Also check out techcommunity.microsoft.com/t5/powershell/ct-p/… and techsnips.io/?query=powershell and the list of resources here: reddit.com/r/PowerShell/comments/fhsxbe/learning_powershell
I few hours set aside tonight so I'll definetely jump in and take a look, thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.