Get script directory in PowerShell when script is invoked with Invoke-Command
Asked Answered
A

2

6

I have a set of PowerShell scripts that include a "common" script, located in the same folder, like this:

# some-script.ps1
$scriptDir = Split-Path -Parent $myinvocation.mycommand.path
. "$scriptDir\script-utils.ps1"

This is fine if the script is called directly, e.g.

.\some-script.ps1

However, if the script is called with Invoke-Command, this does not work:

Invoke-Command -ComputerName server01 -FilePath "X:\some-script.ps1"

In this case, infact, $myinvocation.mycommand contains the contents of the script, and $myinvocation.mycommand.path is null.
How can I determine the script's directory in a way that works also when the script is invoked with Invoke-Command?

NOTE
In the end, this is the solution I actually used:

Invoke-Command -ComputerName server01 `
  {param($scriptArg); & X:\some-script.ps1 $scriptArg } `
  -ArgumentList $something

This also allows passing parameters to the script.

Airedale answered 7/3, 2011 at 12:1 Comment(1)
any solution with full source code about it ?Brynn
P
6

I don't believe you can, from within the invoked script. From get-help invoke-command:

-FilePath Runs the specified local script on one or more remote computers. Enter the path and file name of the script, or pipe a script path to Invoke-Command. The script must reside on the local computer or in a directory that the local computer can access. Use the ArgumentList parameter to specify the values of parameters in the script.

 **When you use this parameter, Windows PowerShell converts the contents of the specified script file to a script
 block, transmits the script block to the remote computer, and runs it on the remote computer.**

When you use invoke-command using the -filepath parameter, the script is read from the file on the local computer, converted to a script block, and that's what gets passed to the remote computer. The remote computer doesn't have any way of knowing if that script block was read from a file.

For the remote computer to know what that original file path was, you'll have to tell it. I think the easiest way to do that would be to write a function to do the invocation, and have it pass the filename to the invoked script as a parameter.

Pinebrook answered 7/3, 2011 at 13:55 Comment(1)
Wouldn't expect any other answer with PowerShell!Bunch
P
1

alternatively rather than using filepath.. you could pass in a scriptblock, that dotsources the script from a UNC path that all machines have access to. However each machine will need to have the appropriate executionpolicy set so that they can run that script from the UNC path

let me be clear though, that i'm not saying to run the script from the UNC path as if that does the remoting, but still using invoke-command or start-job to run a scriptblock on a remote computer. It just happens that that scriptblock will run the script from a UNC path for convenience.

Particularity answered 7/3, 2011 at 17:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.