Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 359
Paolo Tedesco Avatar asked Mar 07 '11 12:03

Paolo Tedesco


People also ask

How do I get the PowerShell script path?

To get the full path of the script we need to use the $myInvocation command. This is an automatic variable and it is only invoked when the script or the function is executed.

What is MyInvocation in PowerShell?

$MyInvocation Contains information about the current command, such as the name, parameters, parameter values, and information about how the command was started, called, or invoked, such as the name of the script that called the current command. $MyInvocation is populated only for scripts, function, and script blocks.

What is Iwr in PowerShell?

The Invoke-WebRequest cmdlet sends HTTP, HTTPS, FTP, and FILE requests to a web page or web service. It parses the response and returns collections of forms, links, images, and other significant HTML elements. This cmdlet was introduced in Windows PowerShell 3.0.


1 Answers

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.

like image 57
mjolinor Avatar answered Oct 11 '22 09:10

mjolinor