Home > Software design >  Copy files from my current directory to new directory
Copy files from my current directory to new directory

Time:12-20

so I am trying to copy 2 files from same folder that my Powershell script is in. I have created script there and also 2 files Moveit1.txt, Moveit2.txt my script is this :

$ScriptDirectory = get-childitem -path $PSScriptRoot
Copy-Item $ScriptDirectory\MoveIt1.txt $env:USERPROFILE   "\AppData\Roaming\" -Force
Copy-Item $ScriptDirectory\MoveIt2.txt "C:\Program Files (x86)\" -Force

But unfortunately it says the files can't be found? But if I check just line $ScriptDirectory it shows where its located and with the files inside. What am I doing wrong?

CodePudding user response:

There is one thing to note:

$ScriptDirectory = Get-ChildItem -Path $PSScriptRoot

$scriptDirectory will most likely contain the 2 MoveIt files in addition to your .ps1 script. When you do:

$ScriptDirectory\MoveIt1.txt

I'm guessing it will end up being something like this when interpreted by Copy-Item:

path\to\script\script.ps1\path\to\script\moveit1.txt\path\to\script\moiveit2.txt\moveit1.txt

Try doing this instead:

Copy-Item (Join-Path $PSScriptRoot MoveIt1.txt) (Join-Path $env:USERPROFILE "\AppData\Roaming\") -Force
Copy-Item (Join-Path $PSScriptRoot MoveIt2.txt) "C:\Program Files (x86)\" -Force

Regarding your Access Denied issue and it working when ran as Administrator with hard-coded paths. You can put this at the top of the script so it elevates itself however this will pop an UAC prompt:

$invocation = "-File `"$PSCommandPath`""
Start-Process powershell -Verb Runas -ArgumentList $invocation

CodePudding user response:

The primary problem with your code is a syntax problem (Santiago's helpful answer addresses additional problems):

In order to pass an expression such as

$env:USERPROFILE   "\AppData\Roaming\"

as a command argument, you need to enclose it in (...).

Neglecting to do so passes three arguments, as the following simplified example demonstrates:

# !! WRONG: Passes *three* arguments instead of the result 
#           of the intended expression.
PS> Write-Output $env:USERPROFILE   "\AppData\Roaming"
C:\Users\jdoe
 
\App\Data\Roaming

# OK: (...) forces a new parsing context, in which the expression is recognized
#     as such.
PS> Write-Output $env:USERPROFILE   "\AppData\Roaming"
C:\Users\jdoe\App\Data\Roaming

As an aside:

  • You could use $env:APPDATA to directly get the path of interest, and
  • Even in cases where you do need to build a path from multiple strings, it may be simpler to use an expandable string instead of the operator: "$env:USERPROFILE\AppData\Roaming" - in this particular case, because the string contains neither spaces nor other special characters (other than the intended $), the double quotes are even optional.

See this answer for more information.

CodePudding user response:

try {
    $scriptPath = $PSScriptRoot
    if (!$scriptPath)
    {
        if ($psISE)
        {
            $scriptPath = Split-Path -Parent -Path $psISE.CurrentFile.FullPath
        } else {
            Write-Host -ForegroundColor Red "Cannot resolve script file's path"
            exit 1
        }
    }
} catch {
    Write-Host -ForegroundColor Red "Caught Exception: $($Error[0].Exception.Message)"
    exit 2
}

Write-Host "Path: $scriptPath"


Copy-Item $ScriptPath\onexcuiconcif.xml -Destination "$env:APPDATA\Avaya\Avaya one-x Communicator" -Force
Copy-Item $scriptPath\InstallConfig.xml -Destination "C:\Program Files (x86)\Avaya\Avaya one-X Communicator" -Force
  • Related