Что это и как это пользоваться

mainFolder | - subFolder | | - MainScript.ps1 | | - SubScript.ps1

I want to call the SubScript.ps1 from the MainScript.ps1 and after some trial and error I found two ways to do that. (Note that I might call the MainScript.ps1 from a console which current working directory is not the same directory where both script are located)

Push-Location $PSScriptRoot
./SubScript param1 param2
Pop-Location $PSScriptRoot
& "$PSScriptRoot/SubScript.ps1" param1 param2

Are these two options completely equal, or is one prefered over the other? Any other better way to call another script?

As detailed in the question

asked Aug 7, 2023 at 14:00

bszabo's user avatar

Are these two options completely equal?

No: The first approach changes the current location, whereas the second doesn’t.

That is, the invoked script will potentially see a different location as current, changing the meaning of any relative paths it uses.

In other words:

  • The Push-Location / PopLocation technique is only necessary and only advisable if you must ensure that the script’s own location, reflected in the automatic $PSScriptRoot variable is the current location.

  • # Equivalent to:
    # & "$PSScriptRoot/SubScript.ps1" param1 param2
    & (Join-Path $PSScriptRoot SubScript.ps1) param1 param2

If you must change the current location, there’s a pitfall:

  • Changing the current location (be it via Push-Location or Set-Location) is invariably session-global.

    • This contrasts with cmd.exe‘s ability to limit current-directory changes in batch files to that batch file only, using the internal setlocal command. In POSIX-compatible shells such as Bash the problem never arises, because shell scripts there execute in an independent child process.
  • Therefore, unless you restore the previous location via Pop-Location (or with Set-Location using a variable that stored the previous location), you’ll end up changing the current location for the caller of your script too (which may be the interactive prompt).

# Change to this script's location (directory).
# Normally, this shouldn't fail.
Push-Location -ErrorAction Stop -LiteralPath $PSScriptRoot
try { # Perform operations here that rely on the script's directory to be # the current location. ./SubScript param1 param2
}
finally { # Ensure that the previous location is returned to, # even in case of a fatal error or the user having pressed Ctrl-C. Pop-Location
}
  • GitHub issue #20490 is a proposal to encapsulate the above by introducing a -Location parameter to the Invoke-Command cmdlet.

answered Aug 7, 2023 at 14:49

mklement0's user avatar

67 gold badges673 silver badges862 bronze badges

Get Current Directory or Script Path in PowerShell

As a professional working with PowerShell, I frequently receive questions to get the current directory from the script. PowerShell, Microsoft’s versatile scripting language, is integrated deeply into the Windows operating system. This makes it incredibly potent for handling file and directory manipulation tasks, making it important to know the current path you are working from. So, In this guide, we’ll walk you through the various ways to get the current directory, script directory, and script path using PowerShell. Whether you want the path of the existing script or the full path of the current location, we’ve got you covered.

Table of contents

  • Understanding the Current Directory in PowerShell
  • How to get the current directory in PowerShell?
  • Common mistakes to avoid when working with directories in PowerShell
  • Conclusion and final thoughts

Understanding the Current Directory in PowerShell

Whether you’re dealing with files, making configuration changes, or working with scripts, being cognizant of your current directory is critical. The current directory, or working directory, is the directory (folder) in which your PowerShell environment is currently operating. It defines the point from which relative paths originate and plays a crucial role in file management tasks.

Method 1: Using the Get-Location Cmdlet

The most direct way to obtain your current directory in PowerShell is by employing the Get-Location cmdlet. This cmdlet retrieves the current working location, i.e., the path of the directory you’re in. This cmdlet returns the Path of the current directory, including the path and the provider (file system or registry). To use it, type “Get-Location” and press Enter. The system will display the full path of the current directory in the PowerShell prompt.

:/>  Как вставить снимок экрана в Office для Windows и Mac? - My Road

The syntax for the Get-Location cmdlet goes like this:

#Syntax 1
Get-Location [-PSProvider <String[]>] [-PSDrive <String[]>] [<CommonParameters>]
#Syntax 2
Get-Location [-Stack] [-StackName <String[]>] [<CommonParameters>]

Here is the list of nifty parameters of this cmdlet.

ParameterDescriptionExample
-PSDriveRetrieves the current location from the specified PowerShell drive. E.g., PowerShell Registry Provider.Get-Location -PSDrive HKCU
-PSProviderRetrieves the current location for the specified provider. Providers can include the FileSystem, Registry, Certificate stores, etc. If the provider supports multiple drives, this cmdlet returns the location of the most recently accessed drive.Get-Location -PSProvider FileSystem
-StackDisplays the location default stack. PowerShell maintains a stack of locations you can push to and pop from using Push-Location cmdlet and Pop-Location cmdlet. This parameter shows the current stack contents.Get-Location -Stack
-StackNameThe Stackname parameter displays the location from a named location stack. You can have multiple named location stacks.Get-Location -StackName myStack

It can move between PowerShell drives, different drives, Windows directories, etc. Here’s an example to get the current directory path using the Get-Location command:

PS C:\Users\Thomas> Get-Location
Path
----
C:\Users\Thomas
PS C:\Users\Thomas> pwd
Path
----
C:\Users\Thomas

When you run this command, PowerShell returns the path of your current directory. This serves as your springboard, the starting point from which all relative paths are defined.

Method 2: Getting the script directory in PowerShell using $PSScriptRoot variable

The script directory is the directory where the currently running script is located. This is useful for accessing other files or scripts in the same directory as the script. To get the script directory in PowerShell, you can use the $PSScriptRoot variable. This variable contains the full path of the directory where the script is located. Here’s an example: Say you have a PowerShell script file called “CopyFiles.ps1” with the below content:

Executing the script retrieves the current location where the script is stored.

PS C:\Users\Thomas\Desktop> .\CopyFiles.ps1
C:\Users\Thomas\Desktop

Method 3: Getting the script path in PowerShell

The script path is the full path of the currently running script, including the drive letter and any subdirectories. To get the script path in PowerShell, you can use the $MyInvocation variable. This variable contains information about the current script, including the path and the command line arguments. Here’s an example:

#Get Script Path
$MyInvocation.MyCommand.Path
#Get the folder of the script
Split-Path -Path $MyInvocation.MyCommand.Path -Parent

Here is what you’ll see when running the script:

PS C:\Users\Thomas\Desktop> .\MyScript.ps1
C:\Users\Thomas\Desktop\MyScript.ps1
C:\Users\Thomas\Desktop

Method 4: Using the $PWD Variable

Another way to get the current directory in PowerShell is by using the $PWD variable. This variable holds the current working directory as a PowerShell object. To display the current directory using this method, type “$PWD” and press Enter. The full path of the current directory will be displayed.

$pwd | Select -ExpandProperty Path

Method 5: Using the [Environment]::CurrentDirectory Property

[Environment]::CurrentDirectory 
get current directory in powershell

Method 6: Get the current directory path using Get-Item cmdlet

Here, the dot (.) specifies the current directory.

Common mistakes to avoid when working with directories in PowerShell

Here are some common mistakes to avoid when working with directories in PowerShell:

  1. Assuming that the current directory is always the same. The current directory can be changed by scripts, cmdlets, or user input.
  2. Using relative paths without considering the current directory. Relative paths are resolved relative to the current directory, so changing the current directory can affect the results.
  3. We often forget to handle errors when accessing files or directories. PowerShell provides many error handling mechanisms, such as the Try-Catch-Finally statement and the -ErrorAction parameter.
:/>  Ноутбук не читает двд диски что делать windows 7

Conclusion and final thoughts

In conclusion, there are several ways to get the current directory in PowerShell, ranging from simple commands like pwd and Get-Location to using variables and properties. In this guide, I have explained the concept of the current directory in PowerShell and shown you how to get the current directory, script directory, and script path using PowerShell. Whether you need the full path or script directory, it’s quick and easy to get in PowerShell. Experiment with these methods to find the best one for your needs.

To change the location to a different path, use the Set-Location cmdlet (E.g., Set-Location C:\Temp). More here: How to Change the current Directory in PowerShell?

How can I retrieve the current directory in PowerShell?

To retrieve the current directory in PowerShell, you can use the PowerShell cmdlets like “Get-Location” or its alias pwd. For example:
$currentDirectory = Get-Location
Write-Host "Current directory: $($currentDirectory.Path)"

How do I get the path of the current script in PowerShell?

To get the path of the current script in PowerShell, you can use the “$MyInvocation.MyCommand.Path” command.

How can I access a specific folder in PowerShell?

How do I find the path of a folder in PowerShell?

In PowerShell, you can find the path of a folder using Resolve-Path for Relative Paths:
$RelativePath = ".\Logs"
$FullPath = Resolve-Path $RelativePath
Write-Output $FullPath

How can I check if a specific directory is the current directory?

How do I get the parent directory of the current directory?

The packaging component of PowerShell Pro Tools allows you to bundle, package as an executable and obfuscate the resulting executable.

Write-Host "Hi! I'm script 1"

Script1.ps1 outputs “Hi! I’m script 1” and then calls Script2.ps1 found at the $PSScriptRoot. Script2.ps1 could then look like this.

`Write-Host “Hi! I’m script 2”

Script2.ps2 outputs “Hi! I’m script 2” and the calls Script3.ps1. Script3.ps1 could consist of something like this.

Write-Host "Hi! I'm script 3"

If you wanted to deploy these scripts to an environment, you’d need to make sure to copy each script. Using bundling, you could combine the scripts, automatically, into a single script. The resulting script would look like this.

`Write-Host “Hi! I’m script 1”

Write-Host “Hi! I’m script 2”

Write-Host “Hi! I’m script 3″`

This enables developers to organize their code into multiple scripts but then deploy a single script. You could store all three scripts in source control, such as GitHub, and then run a bundling step using a continuous integration system, such as AppVeyor.

You can bundle scripts with PowerShell Pro tools using Visual Studio or Merge-Script.

Packaging as an Executable

Scripts can be packaged as a .NET executable for easy deployment on any Windows system. You can combine bundling with packaging to include multiple scripts into a single executable.

You can package scripts with PowerShell Pro tools using Visual Studio or Merge-Script.

You can obfuscate executables with PowerShell Pro tools using Visual Studio, Visual Studio Code and Merge-Script.

We use the Microsoft NuGet.org package system to download the packages necessary to host PowerShell in .NET. You will need an internet connection to access NuGet.org.

dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org

For offline builds, you can also host your own NuGet feed.

:/>  «Удаление записей реестра программного обеспечения сканера, а также полное удаление принтера и его драйверов из операционных систем Windows 7, 8 и 10»
PSscriptroot in Windows

PowerShell offers a multitude of built-in variables to assist script developers in various tasks. One of these essential variables is $PSScriptRoot. Understanding how PSScriptRoot functions and its significance can significantly enhance your PowerShell scripting experience.

In this article, I will explain what is PSScriptRoot and how you use it in your PowerShell scripts to make it more portable and reliable.

$PSScriptRoot is an automatic variable in PowerShell that stores the directory path where the currently executing script resides. This variable helps scriptwriters to reference files, modules, or resources located relative to the script’s location, irrespective of where the script itself is run from.

PSScriptRoot variable in PowerShell Script

Let’s take an example scenario where a PowerShell script references other files or modules using relative paths.

You have a PowerShell script (WelcomeScript.ps1) located in a folder along with a file named “welcome.txt”. You want to read the content of welcome.txt from your script.

In the first scenario, I will define a path in the script “C:\rahul”, this is where both the “WelcomeScript.ps1” and the “welcome.txt” reside.

The contents of the script will look something like this:

$filePath = Join-Path -Path C:\rahul -ChildPath "welcome.txt"
$content = Get-Content -Path $filePath
Write-Output "Content of welcome.txt:"
Write-Output $content

Run this script and you’ll be able to read the output of the “welcome.txt” file.

running our newly created script

Now, move both the script and welcome.txt file to a different location. I am moving it to “C:\rahul\logs”. After moving both files, re-run the script.

error in welcome script

You’ll get an error. This is because the path we mentioned of the “welcome.txt” in the WelcomeScript.ps1 has been changed and we need to change it again in the script too. This is a hassle (doing it again every time the location changes) and that’s why this time we are going to use the $PSScriptRoot variable.

Now the contents of the script will look something like this:

$filePath = Join-Path -Path $PSScriptRoot -ChildPath "welcome.txt"
$content = Get-Content -Path $filePath
Write-Output "Content of welcome.txt:"
Write-Output $content

(The only change is the path of the file, instead of the absolute path, we are using the $PSScriptRoot variable.)

And now run this script. You’ll see it works.

Now, you can move both these files at any location, and you’ll see the script works flawlessly.

PowerShell PSScriptRoot Empty

PowerShell PSScriptRoot serves as a variable designed explicitly to hold the directory path where the currently executing script resides. However, it’s important to note that when used outside of a PowerShell script or if the caller is not a script or command, $PSScriptRoot may indeed appear empty.

psscriptroot empty

Also, PSScriptRoot relies on the context of a running script to determine its value. It won’t be available or populated when executing individual commands or when PowerShell is not running in a script context.

Therefore, if you try to run the contents of the “WelcomeScript.ps1” individually in a PowerShell console, it will output an error that will look something like this:

$filePath = Join-Path -Path $PSScriptRoot -ChildPath "welcome.txt"
error in psscriptroot

Wrapping Up!

Always employ PSScriptRoot when referencing resources related to the script’s location.

As you have seen, without PSScriptRoot, running the script from different locations might lead to failures due to incorrect path resolution.

Moreover, when scripts are properly structured using PSScriptRoot, they become more maintainable. Updates or changes to file locations become hassle-free as the script’s internal references are tied to its own location rather than absolute paths (that might change over time). By utilizing PSScriptRoot, you ensure the script’s portability, reliability and maintainability across various environments.

Rahul is a passionate writer with a deep-rooted love for technology. His articles, tutorials, and guides are crafted with the aim of helping others solve technical problems and kindle their passion for learning. When not busy with the ever-evolving world of technology, he dedicates his time to learning something new every day. Whether it’s delving into a new skill, exploring the power of AI, or simply seeking out fresh perspectives, Rahul’s commitment to lifelong learning remains unwavering.