Reputation: 605
How can I get a remotely executed script to know it's own location? I'm using Invoke-Command to run a script on a remote server. The script needs to create files in the directory in which it lives. Running with relative addressing doesn't work (i.e. .\output.log), the scripts generally end up in my user profile on the remote server. I tried all the methods outlined in this question but none of them seem to work when the script is remote.
Update: Provided script invocation code per request
$server='ad1hfdahp802' $remotepath='\\ad1hfdahp802\d$\AHP\pi_exceed_presentation\pi_exceed_presentation_deploy.ps1' $SDFEnvironment='INT' Invoke-Command -ComputerName $server -FilePath $remotepath -ArgumentList($SDFEnvironment,$remotepath)
The remote script takes the $remotepath and turns it into a file system path.
Upvotes: 2
Views: 2230
Reputation: 605
After trying some of the changes proposed I've come to understand that the Invoke-Command isn't actually running the remote script at its original location, but rather loading it from the original location and then running it under the context of PowerShell as the user running the local script. The "script directory" is actually a directory in the user's workspace regardless of where the script originally lived.
This clarifies things for me somewhat. While there may be ways to divine where the script originally came from or to actually start a session on the remote server then run the script as a "local" script there, the need for the remote script to further access other servers, creating multiple hops in authentication, means I have to add CredSSP to the mix.
It seems my original plan, to pass the path I'm using to locate the script to the script so it can place output files in the original directory, is probably the best approach given that I also have to add CredSSP to the mix.
I'm open to refutation, but I don't think any of the proposed solutions actually improve the functionality of the remote script so I'm going to stick with what I started with for now. Thanks to everyone for their contributions.
Upvotes: 1
Reputation: 3287
Enter a session on the remote server, and call the script from there.
local PS> Enter-PSSession -ComputerName $server ...
remote PS> powershell d:\AHP\...\script.ps1
remote PS> exit
local PS>
Then you can use $PSScriptRoot
in the script in the remote server to get the local path of the directory of the script on the remote server.
EDIT:
To locate the script on the remote server, you can use your knowledge of the network path of the script file, and parse the output of net share
to map network path to local path on the remote server.
remote PS> net share | where { $_.StartsWith('D$ ') } | foreach { [regex]::Split($_, " +")[1]}
Upvotes: 0
Reputation: 54981
Using -FilePath
with Invoke-Command
means that you read the script locally and send the content as the scriptblock to the remote computer. $PSScriptRoot
only works when the script is executed directly on the target. You could try using:
Invoke-Command - ComputerName "computer1" -Scriptblock { & '\\server\path\to\script.ps1' } -Authentication Credssp
Be aware that you need CredSSP to make this work since the remote computer can't use your credentials to access network-resources without it. As an alternative, you could use psexec
(or start a process remotely). Ex.
psexec \\computer1 powershell -noprofile -file \\server\path\to\script.ps1
Upvotes: 2