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
"$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