2

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.

2
  • In this case, you want `D:\AHP\pi_exceed_presentation` ? Commented Feb 15, 2016 at 22:34
  • Yes. I'd like the script to be able to determine where it actually resides. Commented Feb 16, 2016 at 14:42

3 Answers 3

2

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
Sign up to request clarification or add additional context in comments.

9 Comments

The script already lives on the remote server. I'm referencing it via a UNC path. My workaround has been since I know the UNC path I can calculate the file system path and pass that as a parameter, but I was hoping there would be a way to compute it from the running context on the remote server rather than passing it in...
$psscriptroot didn't work (ps3.0 or newer)? You need to provide a sample of how you use invoke-command as this was unclear.
Updated the original post with the script running the Invoke-Command.
Also, PowerShell V4 and I verified that $PSScriptRoot is empty when examined in the remote script
++; it sounds like using the target server-local path inside the script block is the simplest option (D:\AHP\pi_exceed_presentation\pi_exceed_presentation_deploy.ps1, using the OP's example), which bypasses the need to access network resources.
|
1

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.

Comments

0

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]}

Comments

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.